gridviz 2.0.38 → 2.0.40

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 (58) hide show
  1. package/README.md +119 -119
  2. package/dist/gridviz.js +7945 -8887
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +77 -78
  5. package/src/App.js +698 -698
  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 +103 -103
  10. package/src/GeoCanvas.js +419 -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/ParquetGrid.js +122 -122
  22. package/src/dataset/TiledGrid.js +296 -296
  23. package/src/index.js +174 -177
  24. package/src/legend/ColorCategoryLegend.js +124 -124
  25. package/src/legend/ColorDiscreteLegend.js +105 -105
  26. package/src/legend/ColorLegend.js +125 -125
  27. package/src/legend/SegmentOrientationLegend.js +87 -87
  28. package/src/legend/SegmentWidthLegend.js +97 -97
  29. package/src/legend/SizeLegend.js +141 -141
  30. package/src/style/CompositionStyle.js +300 -300
  31. package/src/style/ContourStyle.js +54 -54
  32. package/src/style/DotDensityStyle.js +156 -156
  33. package/src/style/JoyPlotStyle.js +135 -135
  34. package/src/style/LegoStyle.js +112 -112
  35. package/src/style/MosaicStyle.js +107 -107
  36. package/src/style/NinjaStarStyle.js +124 -124
  37. package/src/style/PillarStyle.js +230 -230
  38. package/src/style/SegmentStyle.js +142 -142
  39. package/src/style/ShapeColorSizeStyle.js +126 -126
  40. package/src/style/SideCatStyle.js +172 -172
  41. package/src/style/SideStyle.js +218 -218
  42. package/src/style/SquareColorCatWGLStyle.js +120 -120
  43. package/src/style/SquareColorWGLStyle.js +146 -146
  44. package/src/style/StrokeStyle.js +131 -131
  45. package/src/style/TanakaStyle.js +160 -160
  46. package/src/style/TextStyle.js +132 -132
  47. package/src/utils/Utils.js +35 -35
  48. package/src/utils/WebGLRectangleColoring.js +106 -106
  49. package/src/utils/WebGLSquareColoring.js +118 -118
  50. package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
  51. package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
  52. package/src/utils/WebGLSquareColoringKS.js +153 -153
  53. package/src/utils/stretching.js +131 -131
  54. package/src/utils/webGLUtils.js +71 -71
  55. package/src/utils/zoomUtils.js +142 -142
  56. package/src/style/KernelSmoothingOldStyle.js +0 -221
  57. package/src/style/KernelSmoothingStyle.js +0 -115
  58. package/src/style/KernelSmoothingWGLStyle.js +0 -130
@@ -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
+ }