gridviz 2.1.9 → 2.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -125
- package/dist/gridviz.js +8036 -8024
- package/dist/gridviz.min.js +1 -1
- package/package.json +77 -77
- package/src/App.js +705 -705
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +113 -101
- package/src/GeoCanvas.js +420 -420
- package/src/LabelLayer.js +190 -190
- package/src/Layer.js +103 -103
- package/src/Legend.js +86 -86
- package/src/LineLayer.js +150 -150
- package/src/Style.js +129 -129
- package/src/Tooltip.js +180 -180
- package/src/dataset/COGeo.js +24 -24
- package/src/dataset/CSVGrid.js +104 -104
- package/src/dataset/GeoTIFF.js +127 -127
- package/src/dataset/GridTile.js +41 -41
- package/src/dataset/LGrid.js +54 -54
- package/src/dataset/TiledGrid.js +264 -264
- package/src/index.js +71 -71
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +103 -103
- package/src/legend/ColorLegend.js +124 -124
- package/src/legend/SegmentOrientationLegend.js +87 -87
- package/src/legend/SegmentWidthLegend.js +97 -97
- package/src/legend/SizeLegend.js +141 -141
- package/src/style/CompositionStyle.js +300 -300
- package/src/style/ContourStyle.js +54 -54
- package/src/style/DotDensityStyle.js +156 -156
- package/src/style/IsoFenceStyle.js +262 -262
- package/src/style/JoyPlotStyle.js +135 -135
- package/src/style/LegoStyle.js +112 -112
- package/src/style/MosaicStyle.js +107 -107
- package/src/style/NinjaStarStyle.js +125 -125
- package/src/style/PillarStyle.js +230 -230
- package/src/style/SegmentStyle.js +142 -142
- package/src/style/ShapeColorSizeStyle.js +126 -126
- package/src/style/SideCatStyle.js +172 -172
- package/src/style/SideStyle.js +216 -216
- package/src/style/SquareColorCatWGLStyle.js +120 -120
- package/src/style/SquareColorWGLStyle.js +146 -146
- package/src/style/StrokeStyle.js +131 -131
- package/src/style/TanakaStyle.js +160 -160
- package/src/style/TextStyle.js +132 -132
- package/src/style/TimeSeriesStyle.js +250 -250
- package/src/utils/Utils.js +35 -35
- package/src/utils/WebGLRectangleColoring.js +106 -106
- package/src/utils/WebGLSquareColoring.js +118 -118
- package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
- package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
- package/src/utils/WebGLSquareColoringKS.js +153 -153
- package/src/utils/stretching.js +131 -131
- package/src/utils/webGLUtils.js +71 -71
- package/src/utils/zoomUtils.js +142 -142
|
@@ -1,172 +1,172 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
|
|
6
|
-
/** @typedef {{x:number,y:number,or:"v"|"h",v1:string|undefined,v2:string|undefined}} Side */
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* A style to show the sides of grid cells based on their different categories.
|
|
10
|
-
*
|
|
11
|
-
* @author Julien Gaffuri
|
|
12
|
-
*/
|
|
13
|
-
export class SideCatStyle extends Style {
|
|
14
|
-
/** @param {object} opts */
|
|
15
|
-
constructor(opts) {
|
|
16
|
-
super(opts)
|
|
17
|
-
opts = opts || {}
|
|
18
|
-
|
|
19
|
-
/** The name of the column/attribute of the tabular data where to retrieve the categorical value.
|
|
20
|
-
* @type {string} */
|
|
21
|
-
this.col = opts.col
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The dictionary (string -> color) which give the color of each category.
|
|
25
|
-
* @type {object} */
|
|
26
|
-
this.color = opts.color
|
|
27
|
-
|
|
28
|
-
/** A function returning the width of a cell side line, in geo unit
|
|
29
|
-
* @type {function(Side,number,number):number} */
|
|
30
|
-
this.width = opts.width || ((side, r, z) => r * 0.2)
|
|
31
|
-
|
|
32
|
-
/** A fill color for the cells.
|
|
33
|
-
* @type {function(import("../Dataset").Cell):string} */
|
|
34
|
-
this.fillColor = opts.fillColor
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
39
|
-
* @param {number} r
|
|
40
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
41
|
-
*/
|
|
42
|
-
draw(cells, r, cg) {
|
|
43
|
-
//filter
|
|
44
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
45
|
-
|
|
46
|
-
if (!cells || cells.length == 0) return
|
|
47
|
-
|
|
48
|
-
//zoom factor
|
|
49
|
-
const zf = cg.getZf()
|
|
50
|
-
|
|
51
|
-
/** @type {Array.<Side>} */
|
|
52
|
-
const sides = []
|
|
53
|
-
|
|
54
|
-
//make horizontal sides
|
|
55
|
-
//sort cells by x and y
|
|
56
|
-
cells.sort((c1, c2) => (c2.x == c1.x ? c1.y - c2.y : c1.x - c2.x))
|
|
57
|
-
let c1 = cells[0]
|
|
58
|
-
let v1 = c1[this.col]
|
|
59
|
-
for (let i = 1; i < cells.length; i++) {
|
|
60
|
-
let c2 = cells[i]
|
|
61
|
-
let v2 = c2[this.col]
|
|
62
|
-
|
|
63
|
-
if (c1.y + r == c2.y && c1.x == c2.x) {
|
|
64
|
-
//cells in same column and touch along horizontal side
|
|
65
|
-
//make shared side
|
|
66
|
-
if (v1 != v2) sides.push({ x: c1.x, y: c2.y, or: 'h', v1: v1, v2: v2 })
|
|
67
|
-
} else {
|
|
68
|
-
//cells do not touch along horizontal side
|
|
69
|
-
//make two sides: top one for c1, bottom for c2
|
|
70
|
-
sides.push({ x: c1.x, y: c1.y + r, or: 'h', v1: v1, v2: undefined })
|
|
71
|
-
sides.push({ x: c2.x, y: c2.y, or: 'h', v1: undefined, v2: v2 })
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
c1 = c2
|
|
75
|
-
v1 = v2
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
//make vertical sides
|
|
79
|
-
//sort cells by y and x
|
|
80
|
-
cells.sort((c1, c2) => (c2.y == c1.y ? c1.x - c2.x : c1.y - c2.y))
|
|
81
|
-
c1 = cells[0]
|
|
82
|
-
v1 = c1[this.col]
|
|
83
|
-
for (let i = 1; i < cells.length; i++) {
|
|
84
|
-
let c2 = cells[i]
|
|
85
|
-
let v2 = c2[this.col]
|
|
86
|
-
|
|
87
|
-
if (c1.x + r == c2.x && c1.y == c2.y) {
|
|
88
|
-
//cells in same row and touch along vertical side
|
|
89
|
-
//make shared side
|
|
90
|
-
if (v1 != v2) sides.push({ x: c1.x + r, y: c1.y, or: 'v', v1: v1, v2: v2 })
|
|
91
|
-
} else {
|
|
92
|
-
//cells do not touch along vertical side
|
|
93
|
-
//make two sides: right one for c1, left for c2
|
|
94
|
-
sides.push({ x: c1.x + r, y: c1.y, or: 'v', v1: v1, v2: undefined })
|
|
95
|
-
sides.push({ x: c2.x, y: c2.y, or: 'v', v1: undefined, v2: v2 })
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
c1 = c2
|
|
99
|
-
v1 = v2
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
if (sides.length == 0) return
|
|
104
|
-
|
|
105
|
-
//draw in geo coordinates
|
|
106
|
-
cg.setCanvasTransform()
|
|
107
|
-
|
|
108
|
-
//draw cells, if fillColor specified
|
|
109
|
-
if (this.fillColor)
|
|
110
|
-
for (let c of cells) {
|
|
111
|
-
const fc = this.fillColor(c)
|
|
112
|
-
if (!fc || fc == 'none') continue
|
|
113
|
-
cg.ctx.fillStyle = fc
|
|
114
|
-
cg.ctx.fillRect(c.x, c.y, r, r)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
//draw sides
|
|
118
|
-
cg.ctx.lineCap = 'butt'
|
|
119
|
-
for (let s of sides) {
|
|
120
|
-
//width
|
|
121
|
-
/** @type {number|undefined} */
|
|
122
|
-
const wG = this.width ? this.width(s, r, zf) : undefined
|
|
123
|
-
if (!wG || wG <= 0) continue
|
|
124
|
-
const w2 = wG * 0.5
|
|
125
|
-
|
|
126
|
-
//set color and width
|
|
127
|
-
cg.ctx.lineWidth = wG
|
|
128
|
-
|
|
129
|
-
//draw segment with correct orientation
|
|
130
|
-
if (s.or === 'h') {
|
|
131
|
-
//top line
|
|
132
|
-
if (s.v2) {
|
|
133
|
-
cg.ctx.beginPath()
|
|
134
|
-
cg.ctx.strokeStyle = this.color[s.v2]
|
|
135
|
-
cg.ctx.moveTo(s.x, s.y + w2)
|
|
136
|
-
cg.ctx.lineTo(s.x + r, s.y + w2)
|
|
137
|
-
cg.ctx.stroke()
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
//bottom line
|
|
141
|
-
if (s.v1) {
|
|
142
|
-
cg.ctx.beginPath()
|
|
143
|
-
cg.ctx.strokeStyle = this.color[s.v1]
|
|
144
|
-
cg.ctx.moveTo(s.x, s.y - w2)
|
|
145
|
-
cg.ctx.lineTo(s.x + r, s.y - w2)
|
|
146
|
-
cg.ctx.stroke()
|
|
147
|
-
}
|
|
148
|
-
} else {
|
|
149
|
-
//right line
|
|
150
|
-
if (s.v2) {
|
|
151
|
-
cg.ctx.beginPath()
|
|
152
|
-
cg.ctx.strokeStyle = this.color[s.v2]
|
|
153
|
-
cg.ctx.moveTo(s.x + w2, s.y)
|
|
154
|
-
cg.ctx.lineTo(s.x + w2, s.y + r)
|
|
155
|
-
cg.ctx.stroke()
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
//left line
|
|
159
|
-
if (s.v1) {
|
|
160
|
-
cg.ctx.beginPath()
|
|
161
|
-
cg.ctx.strokeStyle = this.color[s.v1]
|
|
162
|
-
cg.ctx.moveTo(s.x - w2, s.y)
|
|
163
|
-
cg.ctx.lineTo(s.x - w2, s.y + r)
|
|
164
|
-
cg.ctx.stroke()
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
//update legends
|
|
170
|
-
this.updateLegends({ style: this, r: r, zf: zf })
|
|
171
|
-
}
|
|
172
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
|
|
6
|
+
/** @typedef {{x:number,y:number,or:"v"|"h",v1:string|undefined,v2:string|undefined}} Side */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A style to show the sides of grid cells based on their different categories.
|
|
10
|
+
*
|
|
11
|
+
* @author Julien Gaffuri
|
|
12
|
+
*/
|
|
13
|
+
export class SideCatStyle extends Style {
|
|
14
|
+
/** @param {object} opts */
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
super(opts)
|
|
17
|
+
opts = opts || {}
|
|
18
|
+
|
|
19
|
+
/** The name of the column/attribute of the tabular data where to retrieve the categorical value.
|
|
20
|
+
* @type {string} */
|
|
21
|
+
this.col = opts.col
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The dictionary (string -> color) which give the color of each category.
|
|
25
|
+
* @type {object} */
|
|
26
|
+
this.color = opts.color
|
|
27
|
+
|
|
28
|
+
/** A function returning the width of a cell side line, in geo unit
|
|
29
|
+
* @type {function(Side,number,number):number} */
|
|
30
|
+
this.width = opts.width || ((side, r, z) => r * 0.2)
|
|
31
|
+
|
|
32
|
+
/** A fill color for the cells.
|
|
33
|
+
* @type {function(import("../Dataset").Cell):string} */
|
|
34
|
+
this.fillColor = opts.fillColor
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
39
|
+
* @param {number} r
|
|
40
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
41
|
+
*/
|
|
42
|
+
draw(cells, r, cg) {
|
|
43
|
+
//filter
|
|
44
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
45
|
+
|
|
46
|
+
if (!cells || cells.length == 0) return
|
|
47
|
+
|
|
48
|
+
//zoom factor
|
|
49
|
+
const zf = cg.getZf()
|
|
50
|
+
|
|
51
|
+
/** @type {Array.<Side>} */
|
|
52
|
+
const sides = []
|
|
53
|
+
|
|
54
|
+
//make horizontal sides
|
|
55
|
+
//sort cells by x and y
|
|
56
|
+
cells.sort((c1, c2) => (c2.x == c1.x ? c1.y - c2.y : c1.x - c2.x))
|
|
57
|
+
let c1 = cells[0]
|
|
58
|
+
let v1 = c1[this.col]
|
|
59
|
+
for (let i = 1; i < cells.length; i++) {
|
|
60
|
+
let c2 = cells[i]
|
|
61
|
+
let v2 = c2[this.col]
|
|
62
|
+
|
|
63
|
+
if (c1.y + r == c2.y && c1.x == c2.x) {
|
|
64
|
+
//cells in same column and touch along horizontal side
|
|
65
|
+
//make shared side
|
|
66
|
+
if (v1 != v2) sides.push({ x: c1.x, y: c2.y, or: 'h', v1: v1, v2: v2 })
|
|
67
|
+
} else {
|
|
68
|
+
//cells do not touch along horizontal side
|
|
69
|
+
//make two sides: top one for c1, bottom for c2
|
|
70
|
+
sides.push({ x: c1.x, y: c1.y + r, or: 'h', v1: v1, v2: undefined })
|
|
71
|
+
sides.push({ x: c2.x, y: c2.y, or: 'h', v1: undefined, v2: v2 })
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
c1 = c2
|
|
75
|
+
v1 = v2
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//make vertical sides
|
|
79
|
+
//sort cells by y and x
|
|
80
|
+
cells.sort((c1, c2) => (c2.y == c1.y ? c1.x - c2.x : c1.y - c2.y))
|
|
81
|
+
c1 = cells[0]
|
|
82
|
+
v1 = c1[this.col]
|
|
83
|
+
for (let i = 1; i < cells.length; i++) {
|
|
84
|
+
let c2 = cells[i]
|
|
85
|
+
let v2 = c2[this.col]
|
|
86
|
+
|
|
87
|
+
if (c1.x + r == c2.x && c1.y == c2.y) {
|
|
88
|
+
//cells in same row and touch along vertical side
|
|
89
|
+
//make shared side
|
|
90
|
+
if (v1 != v2) sides.push({ x: c1.x + r, y: c1.y, or: 'v', v1: v1, v2: v2 })
|
|
91
|
+
} else {
|
|
92
|
+
//cells do not touch along vertical side
|
|
93
|
+
//make two sides: right one for c1, left for c2
|
|
94
|
+
sides.push({ x: c1.x + r, y: c1.y, or: 'v', v1: v1, v2: undefined })
|
|
95
|
+
sides.push({ x: c2.x, y: c2.y, or: 'v', v1: undefined, v2: v2 })
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
c1 = c2
|
|
99
|
+
v1 = v2
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
//
|
|
103
|
+
if (sides.length == 0) return
|
|
104
|
+
|
|
105
|
+
//draw in geo coordinates
|
|
106
|
+
cg.setCanvasTransform()
|
|
107
|
+
|
|
108
|
+
//draw cells, if fillColor specified
|
|
109
|
+
if (this.fillColor)
|
|
110
|
+
for (let c of cells) {
|
|
111
|
+
const fc = this.fillColor(c)
|
|
112
|
+
if (!fc || fc == 'none') continue
|
|
113
|
+
cg.ctx.fillStyle = fc
|
|
114
|
+
cg.ctx.fillRect(c.x, c.y, r, r)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//draw sides
|
|
118
|
+
cg.ctx.lineCap = 'butt'
|
|
119
|
+
for (let s of sides) {
|
|
120
|
+
//width
|
|
121
|
+
/** @type {number|undefined} */
|
|
122
|
+
const wG = this.width ? this.width(s, r, zf) : undefined
|
|
123
|
+
if (!wG || wG <= 0) continue
|
|
124
|
+
const w2 = wG * 0.5
|
|
125
|
+
|
|
126
|
+
//set color and width
|
|
127
|
+
cg.ctx.lineWidth = wG
|
|
128
|
+
|
|
129
|
+
//draw segment with correct orientation
|
|
130
|
+
if (s.or === 'h') {
|
|
131
|
+
//top line
|
|
132
|
+
if (s.v2) {
|
|
133
|
+
cg.ctx.beginPath()
|
|
134
|
+
cg.ctx.strokeStyle = this.color[s.v2]
|
|
135
|
+
cg.ctx.moveTo(s.x, s.y + w2)
|
|
136
|
+
cg.ctx.lineTo(s.x + r, s.y + w2)
|
|
137
|
+
cg.ctx.stroke()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
//bottom line
|
|
141
|
+
if (s.v1) {
|
|
142
|
+
cg.ctx.beginPath()
|
|
143
|
+
cg.ctx.strokeStyle = this.color[s.v1]
|
|
144
|
+
cg.ctx.moveTo(s.x, s.y - w2)
|
|
145
|
+
cg.ctx.lineTo(s.x + r, s.y - w2)
|
|
146
|
+
cg.ctx.stroke()
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
//right line
|
|
150
|
+
if (s.v2) {
|
|
151
|
+
cg.ctx.beginPath()
|
|
152
|
+
cg.ctx.strokeStyle = this.color[s.v2]
|
|
153
|
+
cg.ctx.moveTo(s.x + w2, s.y)
|
|
154
|
+
cg.ctx.lineTo(s.x + w2, s.y + r)
|
|
155
|
+
cg.ctx.stroke()
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
//left line
|
|
159
|
+
if (s.v1) {
|
|
160
|
+
cg.ctx.beginPath()
|
|
161
|
+
cg.ctx.strokeStyle = this.color[s.v1]
|
|
162
|
+
cg.ctx.moveTo(s.x - w2, s.y)
|
|
163
|
+
cg.ctx.lineTo(s.x - w2, s.y + r)
|
|
164
|
+
cg.ctx.stroke()
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
//update legends
|
|
170
|
+
this.updateLegends({ style: this, r: r, zf: zf })
|
|
171
|
+
}
|
|
172
|
+
}
|