gridviz 2.0.41 → 2.0.43

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.
Files changed (54) hide show
  1. package/README.md +119 -119
  2. package/dist/gridviz.js +7490 -7499
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +76 -76
  5. package/src/App.js +642 -642
  6. package/src/BackgroundLayer.js +182 -182
  7. package/src/BackgroundLayerWMS.js +131 -131
  8. package/src/Dataset.js +76 -76
  9. package/src/DatasetComponent.js +101 -101
  10. package/src/GeoCanvas.js +420 -419
  11. package/src/LabelLayer.js +190 -190
  12. package/src/Layer.js +92 -92
  13. package/src/Legend.js +86 -86
  14. package/src/LineLayer.js +150 -150
  15. package/src/Style.js +114 -114
  16. package/src/Tooltip.js +168 -168
  17. package/src/dataset/COGeo.js +24 -24
  18. package/src/dataset/CSVGrid.js +104 -104
  19. package/src/dataset/GeoTIFF.js +127 -127
  20. package/src/dataset/GridTile.js +41 -41
  21. package/src/dataset/TiledGrid.js +264 -264
  22. package/src/index.js +176 -176
  23. package/src/legend/ColorCategoryLegend.js +124 -124
  24. package/src/legend/ColorDiscreteLegend.js +103 -105
  25. package/src/legend/ColorLegend.js +124 -125
  26. package/src/legend/SegmentOrientationLegend.js +87 -87
  27. package/src/legend/SegmentWidthLegend.js +97 -97
  28. package/src/legend/SizeLegend.js +141 -141
  29. package/src/style/CompositionStyle.js +300 -300
  30. package/src/style/ContourStyle.js +54 -54
  31. package/src/style/DotDensityStyle.js +156 -156
  32. package/src/style/JoyPlotStyle.js +135 -135
  33. package/src/style/LegoStyle.js +112 -112
  34. package/src/style/MosaicStyle.js +107 -107
  35. package/src/style/NinjaStarStyle.js +124 -124
  36. package/src/style/PillarStyle.js +230 -230
  37. package/src/style/SegmentStyle.js +142 -142
  38. package/src/style/ShapeColorSizeStyle.js +126 -126
  39. package/src/style/SideCatStyle.js +172 -172
  40. package/src/style/SideStyle.js +218 -218
  41. package/src/style/SquareColorCatWGLStyle.js +120 -120
  42. package/src/style/SquareColorWGLStyle.js +146 -146
  43. package/src/style/StrokeStyle.js +131 -131
  44. package/src/style/TanakaStyle.js +160 -160
  45. package/src/style/TextStyle.js +132 -132
  46. package/src/utils/Utils.js +35 -35
  47. package/src/utils/WebGLRectangleColoring.js +106 -106
  48. package/src/utils/WebGLSquareColoring.js +118 -118
  49. package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
  50. package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
  51. package/src/utils/WebGLSquareColoringKS.js +153 -153
  52. package/src/utils/stretching.js +131 -131
  53. package/src/utils/webGLUtils.js +71 -71
  54. package/src/utils/zoomUtils.js +142 -142
@@ -1,218 +1,218 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Style } from '../Style.js'
5
-
6
- /** @typedef {{x:number,y:number,or:"v"|"h",value:number}} Side */
7
-
8
- /**
9
- *
10
- * @author Julien Gaffuri
11
- */
12
- export class SideStyle extends Style {
13
- /** @param {object} opts */
14
- constructor(opts) {
15
- super(opts)
16
- opts = opts || {}
17
-
18
- /** The name of the column/attribute of the tabular data where to retrieve the variable for the cell values.
19
- * @type {string} */
20
- this.valueCol = opts.valueCol
21
-
22
- /** A function returning the value of a cell side. This value is computed from the two adjacent cell values.
23
- * For horizontal sides, v1 is the value of the cell below and v2 the value of the cell above.
24
- * For vertical sides, v1 is the value of the cell left and v2 the value of the cell right.
25
- * @type {function(number|undefined,number|undefined,number,import("../Style").Stat|undefined,number):number} */
26
- this.value = opts.value || ((v1, v2, r, s, zf) => 1)
27
-
28
- /** A function returning the color of a cell side.
29
- * @type {function(Side,number,import("../Style").Stat|undefined,number):string} */
30
- this.color = opts.color || (() => '#EA6BAC')
31
-
32
- /** A function returning the width of a cell side, in geo unit
33
- * @type {function(Side,number,import("../Style").Stat|undefined,number):number} */
34
- this.width = opts.width || ((side, r, s, zf) => (r * side.value) / 5)
35
-
36
- /** orientation. Set to 90 to show sides as slope lines for example.
37
- * @type {number} */
38
- this.orientation = opts.orientation || 0
39
-
40
- /** A fill color for the cells.
41
- * @type {function(import("../Dataset").Cell):string} */
42
- this.fillColor = opts.fillColor
43
- }
44
-
45
- /**
46
- * @param {Array.<import("../Dataset").Cell>} cells
47
- * @param {number} r
48
- * @param {import("../GeoCanvas").GeoCanvas} cg
49
- */
50
- draw(cells, r, cg) {
51
- //filter
52
- if (this.filter) cells = cells.filter(this.filter)
53
-
54
- //zoom factor
55
- const zf = cg.getZf()
56
-
57
- //compute stats on cell values
58
- let statValue
59
- if (this.valueCol) {
60
- //compute color variable statistics
61
- statValue = Style.getStatistics(cells, (c) => c[this.valueCol], true)
62
- }
63
-
64
- /** @type {Array.<Side>} */
65
- const sides = []
66
-
67
- const epsilon = r * 0.001
68
-
69
- //make horizontal sides
70
- //sort cells by x and y
71
- cells.sort((c1, c2) => (c2.x == c1.x ? c1.y - c2.y : c1.x - c2.x))
72
- let c1 = cells[0]
73
- for (let i = 1; i < cells.length; i++) {
74
- let c2 = cells[i]
75
-
76
- if (Math.abs(c1.y + r - c2.y) <= epsilon && Math.abs(c1.x - c2.x) <= epsilon)
77
- //cells in same column and touch along horizontal side
78
- //make shared side
79
- sides.push({
80
- x: c1.x,
81
- y: c2.y,
82
- or: 'h',
83
- value: this.value(c1[this.valueCol], c2[this.valueCol], r, statValue, zf),
84
- })
85
- else {
86
- //cells do not touch along horizontal side
87
- //make two sides: top one for c1, bottom for c2
88
- sides.push({
89
- x: c1.x,
90
- y: c1.y + r,
91
- or: 'h',
92
- value: this.value(c1[this.valueCol], undefined, r, statValue, zf),
93
- })
94
- sides.push({
95
- x: c2.x,
96
- y: c2.y,
97
- or: 'h',
98
- value: this.value(undefined, c2[this.valueCol], r, statValue, zf),
99
- })
100
- }
101
-
102
- c1 = c2
103
- }
104
-
105
- //make vertical sides
106
- //sort cells by y and x
107
- cells.sort((c1, c2) => (c2.y == c1.y ? c1.x - c2.x : c1.y - c2.y))
108
- c1 = cells[0]
109
- for (let i = 1; i < cells.length; i++) {
110
- let c2 = cells[i]
111
-
112
- if (Math.abs(c1.x + r - c2.x) <= epsilon && Math.abs(c1.y - c2.y) <= epsilon)
113
- //cells in same row and touch along vertical side
114
- //make shared side
115
- sides.push({
116
- x: c1.x + r,
117
- y: c1.y,
118
- or: 'v',
119
- value: this.value(c1[this.valueCol], c2[this.valueCol], r, statValue, zf),
120
- })
121
- else {
122
- //cells do not touch along vertical side
123
- //make two sides: right one for c1, left for c2
124
- sides.push({
125
- x: c1.x + r,
126
- y: c1.y,
127
- or: 'v',
128
- value: this.value(c1[this.valueCol], undefined, r, statValue, zf),
129
- })
130
- sides.push({
131
- x: c2.x,
132
- y: c2.y,
133
- or: 'v',
134
- value: this.value(undefined, c2[this.valueCol], r, statValue, zf),
135
- })
136
- }
137
-
138
- c1 = c2
139
- }
140
-
141
- //
142
- if (sides.length == 0) return
143
-
144
- //compute stats on sides
145
- const statSides = SideStyle.getSideStatistics(sides, true)
146
-
147
- //draw in geo coordinates
148
- cg.setCanvasTransform()
149
-
150
- //draw cells, if fillColor specified
151
- if (this.fillColor)
152
- for (let c of cells) {
153
- const fc = this.fillColor(c)
154
- if (!fc || fc == 'none') continue
155
- cg.ctx.fillStyle = fc
156
- cg.ctx.fillRect(c.x, c.y, r, r)
157
- }
158
-
159
- //draw sides
160
- cg.ctx.lineCap = 'butt'
161
- const r2 = r / 2
162
- for (let s of sides) {
163
- //color
164
- /** @type {string|undefined} */
165
- const col = this.color ? this.color(s, r, statSides, zf) : undefined
166
- if (!col || col == 'none') continue
167
-
168
- //width
169
- /** @type {number|undefined} */
170
- const wG = this.width ? this.width(s, r, statSides, zf) : undefined
171
- if (!wG || wG <= 0) continue
172
-
173
- //set color and width
174
- cg.ctx.strokeStyle = col
175
- cg.ctx.lineWidth = wG
176
-
177
- //draw segment with correct orientation
178
- cg.ctx.beginPath()
179
- if (this.orientation == 90) {
180
- cg.ctx.moveTo(s.x + r2, s.y + r2)
181
- if (s.or === 'h') cg.ctx.lineTo(s.x + r2, s.y - r2)
182
- else cg.ctx.lineTo(s.x - r2, s.y + r2)
183
- } else {
184
- cg.ctx.moveTo(s.x, s.y)
185
- cg.ctx.lineTo(s.x + (s.or === 'h' ? r : 0), s.y + (s.or === 'v' ? r : 0))
186
- }
187
- cg.ctx.stroke()
188
- }
189
-
190
- //update legends
191
- this.updateLegends({ style: this, r: r, zf: zf })
192
- }
193
-
194
- /**
195
- * Compute some statistics on a value of some sides.
196
- * This is used to define how to draw specifically the sides within the view.
197
- *
198
- * @param {Array.<Side>} sides
199
- * @param {boolean} ignoreZeros
200
- * @returns {import("../Style").Stat | undefined}
201
- */
202
- static getSideStatistics(sides, ignoreZeros) {
203
- if (!sides || sides.length == 0) return undefined
204
- let min = Infinity
205
- let max = -Infinity
206
- //let sum = 0
207
- //let nb = 0
208
- for (const s of sides) {
209
- const v = s.value
210
- if (ignoreZeros && !v) continue
211
- if (v < min) min = v
212
- if (v > max) max = v
213
- //sum += v
214
- //nb++
215
- }
216
- return { min: min, max: max }
217
- }
218
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Style } from '../Style.js'
5
+
6
+ /** @typedef {{x:number,y:number,or:"v"|"h",value:number}} Side */
7
+
8
+ /**
9
+ *
10
+ * @author Julien Gaffuri
11
+ */
12
+ export class SideStyle extends Style {
13
+ /** @param {object} opts */
14
+ constructor(opts) {
15
+ super(opts)
16
+ opts = opts || {}
17
+
18
+ /** The name of the column/attribute of the tabular data where to retrieve the variable for the cell values.
19
+ * @type {string} */
20
+ this.valueCol = opts.valueCol
21
+
22
+ /** A function returning the value of a cell side. This value is computed from the two adjacent cell values.
23
+ * For horizontal sides, v1 is the value of the cell below and v2 the value of the cell above.
24
+ * For vertical sides, v1 is the value of the cell left and v2 the value of the cell right.
25
+ * @type {function(number|undefined,number|undefined,number,import("../Style").Stat|undefined,number):number} */
26
+ this.value = opts.value || ((v1, v2, r, s, zf) => 1)
27
+
28
+ /** A function returning the color of a cell side.
29
+ * @type {function(Side,number,import("../Style").Stat|undefined,number):string} */
30
+ this.color = opts.color || (() => '#EA6BAC')
31
+
32
+ /** A function returning the width of a cell side, in geo unit
33
+ * @type {function(Side,number,import("../Style").Stat|undefined,number):number} */
34
+ this.width = opts.width || ((side, r, s, zf) => (r * side.value) / 5)
35
+
36
+ /** orientation. Set to 90 to show sides as slope lines for example.
37
+ * @type {number} */
38
+ this.orientation = opts.orientation || 0
39
+
40
+ /** A fill color for the cells.
41
+ * @type {function(import("../Dataset").Cell):string} */
42
+ this.fillColor = opts.fillColor
43
+ }
44
+
45
+ /**
46
+ * @param {Array.<import("../Dataset").Cell>} cells
47
+ * @param {number} r
48
+ * @param {import("../GeoCanvas").GeoCanvas} cg
49
+ */
50
+ draw(cells, r, cg) {
51
+ //filter
52
+ if (this.filter) cells = cells.filter(this.filter)
53
+
54
+ //zoom factor
55
+ const zf = cg.getZf()
56
+
57
+ //compute stats on cell values
58
+ let statValue
59
+ if (this.valueCol) {
60
+ //compute color variable statistics
61
+ statValue = Style.getStatistics(cells, (c) => c[this.valueCol], true)
62
+ }
63
+
64
+ /** @type {Array.<Side>} */
65
+ const sides = []
66
+
67
+ const epsilon = r * 0.001
68
+
69
+ //make horizontal sides
70
+ //sort cells by x and y
71
+ cells.sort((c1, c2) => (c2.x == c1.x ? c1.y - c2.y : c1.x - c2.x))
72
+ let c1 = cells[0]
73
+ for (let i = 1; i < cells.length; i++) {
74
+ let c2 = cells[i]
75
+
76
+ if (Math.abs(c1.y + r - c2.y) <= epsilon && Math.abs(c1.x - c2.x) <= epsilon)
77
+ //cells in same column and touch along horizontal side
78
+ //make shared side
79
+ sides.push({
80
+ x: c1.x,
81
+ y: c2.y,
82
+ or: 'h',
83
+ value: this.value(c1[this.valueCol], c2[this.valueCol], r, statValue, zf),
84
+ })
85
+ else {
86
+ //cells do not touch along horizontal side
87
+ //make two sides: top one for c1, bottom for c2
88
+ sides.push({
89
+ x: c1.x,
90
+ y: c1.y + r,
91
+ or: 'h',
92
+ value: this.value(c1[this.valueCol], undefined, r, statValue, zf),
93
+ })
94
+ sides.push({
95
+ x: c2.x,
96
+ y: c2.y,
97
+ or: 'h',
98
+ value: this.value(undefined, c2[this.valueCol], r, statValue, zf),
99
+ })
100
+ }
101
+
102
+ c1 = c2
103
+ }
104
+
105
+ //make vertical sides
106
+ //sort cells by y and x
107
+ cells.sort((c1, c2) => (c2.y == c1.y ? c1.x - c2.x : c1.y - c2.y))
108
+ c1 = cells[0]
109
+ for (let i = 1; i < cells.length; i++) {
110
+ let c2 = cells[i]
111
+
112
+ if (Math.abs(c1.x + r - c2.x) <= epsilon && Math.abs(c1.y - c2.y) <= epsilon)
113
+ //cells in same row and touch along vertical side
114
+ //make shared side
115
+ sides.push({
116
+ x: c1.x + r,
117
+ y: c1.y,
118
+ or: 'v',
119
+ value: this.value(c1[this.valueCol], c2[this.valueCol], r, statValue, zf),
120
+ })
121
+ else {
122
+ //cells do not touch along vertical side
123
+ //make two sides: right one for c1, left for c2
124
+ sides.push({
125
+ x: c1.x + r,
126
+ y: c1.y,
127
+ or: 'v',
128
+ value: this.value(c1[this.valueCol], undefined, r, statValue, zf),
129
+ })
130
+ sides.push({
131
+ x: c2.x,
132
+ y: c2.y,
133
+ or: 'v',
134
+ value: this.value(undefined, c2[this.valueCol], r, statValue, zf),
135
+ })
136
+ }
137
+
138
+ c1 = c2
139
+ }
140
+
141
+ //
142
+ if (sides.length == 0) return
143
+
144
+ //compute stats on sides
145
+ const statSides = SideStyle.getSideStatistics(sides, true)
146
+
147
+ //draw in geo coordinates
148
+ cg.setCanvasTransform()
149
+
150
+ //draw cells, if fillColor specified
151
+ if (this.fillColor)
152
+ for (let c of cells) {
153
+ const fc = this.fillColor(c)
154
+ if (!fc || fc == 'none') continue
155
+ cg.ctx.fillStyle = fc
156
+ cg.ctx.fillRect(c.x, c.y, r, r)
157
+ }
158
+
159
+ //draw sides
160
+ cg.ctx.lineCap = 'butt'
161
+ const r2 = r / 2
162
+ for (let s of sides) {
163
+ //color
164
+ /** @type {string|undefined} */
165
+ const col = this.color ? this.color(s, r, statSides, zf) : undefined
166
+ if (!col || col == 'none') continue
167
+
168
+ //width
169
+ /** @type {number|undefined} */
170
+ const wG = this.width ? this.width(s, r, statSides, zf) : undefined
171
+ if (!wG || wG <= 0) continue
172
+
173
+ //set color and width
174
+ cg.ctx.strokeStyle = col
175
+ cg.ctx.lineWidth = wG
176
+
177
+ //draw segment with correct orientation
178
+ cg.ctx.beginPath()
179
+ if (this.orientation == 90) {
180
+ cg.ctx.moveTo(s.x + r2, s.y + r2)
181
+ if (s.or === 'h') cg.ctx.lineTo(s.x + r2, s.y - r2)
182
+ else cg.ctx.lineTo(s.x - r2, s.y + r2)
183
+ } else {
184
+ cg.ctx.moveTo(s.x, s.y)
185
+ cg.ctx.lineTo(s.x + (s.or === 'h' ? r : 0), s.y + (s.or === 'v' ? r : 0))
186
+ }
187
+ cg.ctx.stroke()
188
+ }
189
+
190
+ //update legends
191
+ this.updateLegends({ style: this, r: r, zf: zf })
192
+ }
193
+
194
+ /**
195
+ * Compute some statistics on a value of some sides.
196
+ * This is used to define how to draw specifically the sides within the view.
197
+ *
198
+ * @param {Array.<Side>} sides
199
+ * @param {boolean} ignoreZeros
200
+ * @returns {import("../Style").Stat | undefined}
201
+ */
202
+ static getSideStatistics(sides, ignoreZeros) {
203
+ if (!sides || sides.length == 0) return undefined
204
+ let min = Infinity
205
+ let max = -Infinity
206
+ //let sum = 0
207
+ //let nb = 0
208
+ for (const s of sides) {
209
+ const v = s.value
210
+ if (ignoreZeros && !v) continue
211
+ if (v < min) min = v
212
+ if (v > max) max = v
213
+ //sum += v
214
+ //nb++
215
+ }
216
+ return { min: min, max: max }
217
+ }
218
+ }