gridviz 3.0.26 → 3.0.28

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 (67) hide show
  1. package/README.md +126 -128
  2. package/dist/gridviz.js +8798 -8706
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +73 -73
  5. package/src/button/Button.js +67 -67
  6. package/src/button/FullscreenButton.js +121 -121
  7. package/src/button/ZoomButtons.js +103 -103
  8. package/src/core/Dataset.js +154 -154
  9. package/src/core/Drawable.js +78 -78
  10. package/src/core/GeoCanvas.js +443 -443
  11. package/src/core/Layer.js +23 -23
  12. package/src/core/Legend.js +108 -108
  13. package/src/core/Map.js +544 -544
  14. package/src/core/MultiResolutionDataset.js +93 -93
  15. package/src/core/Style.js +98 -98
  16. package/src/core/Tooltip.js +182 -182
  17. package/src/dataset/COGeo.js +25 -25
  18. package/src/dataset/CSVGrid.js +112 -112
  19. package/src/dataset/GeoTIFF.js +122 -122
  20. package/src/dataset/JSGrid.js +55 -55
  21. package/src/dataset/TiledGrid.js +302 -302
  22. package/src/dataset/worker.js +18 -18
  23. package/src/index.js +78 -77
  24. package/src/layer/BackgroundLayer.js +173 -173
  25. package/src/layer/BackgroundLayerImage.js +81 -81
  26. package/src/layer/BackgroundLayerWMS.js +104 -104
  27. package/src/layer/GeoJSONLayer.js +224 -214
  28. package/src/layer/GridLayer.js +149 -148
  29. package/src/layer/LabelLayer.js +194 -194
  30. package/src/legend/ColorCategoryLegend.js +109 -109
  31. package/src/legend/ColorDiscreteLegend.js +100 -100
  32. package/src/legend/ColorLegend.js +115 -115
  33. package/src/legend/OrientationLegend.js +89 -89
  34. package/src/legend/SizeLegend.js +224 -224
  35. package/src/legend/TernaryLegend.js +302 -302
  36. package/src/style/CompositionStyle.js +291 -291
  37. package/src/style/ContourStyle.js +21 -21
  38. package/src/style/DotDensityStyle.js +133 -133
  39. package/src/style/ImageStyle.js +100 -100
  40. package/src/style/IsoFenceStyle.js +217 -217
  41. package/src/style/JoyPlotStyle.js +127 -127
  42. package/src/style/LegoStyle.js +110 -110
  43. package/src/style/MosaicStyle.js +99 -99
  44. package/src/style/NinjaStarStyle.js +102 -102
  45. package/src/style/PillarStyle.js +207 -207
  46. package/src/style/SegmentStyle.js +105 -105
  47. package/src/style/ShadingStyle.js +61 -0
  48. package/src/style/ShapeColorSizeStyle.js +147 -147
  49. package/src/style/SideCategoryStyle.js +112 -112
  50. package/src/style/SideStyle.js +212 -212
  51. package/src/style/SquareColorCategoryWebGLStyle.js +107 -107
  52. package/src/style/SquareColorWebGLStyle.js +126 -126
  53. package/src/style/StrokeStyle.js +135 -135
  54. package/src/style/TanakaStyle.js +69 -69
  55. package/src/style/TextStyle.js +110 -110
  56. package/src/style/TimeSeriesStyle.js +222 -222
  57. package/src/utils/WebGLRectangleColoring.js +106 -106
  58. package/src/utils/WebGLSquareColoring.js +118 -118
  59. package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
  60. package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
  61. package/src/utils/WebGLSquareColoringKS.js +153 -153
  62. package/src/utils/scale.js +218 -218
  63. package/src/utils/stretching.js +120 -120
  64. package/src/utils/ternary.js +208 -208
  65. package/src/utils/utils.js +58 -58
  66. package/src/utils/webGLUtils.js +72 -72
  67. package/src/utils/zoomUtils.js +142 -142
@@ -1,217 +1,217 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Style } from '../core/Style.js'
5
- import { SideStyle } from './SideStyle.js'
6
-
7
- /** @typedef {{x:number,y:number,or:"v"|"h",c1:import('../core/Dataset.js').Cell|undefined,c2:import('../core/Dataset.js').Cell|undefined}} Side */
8
-
9
- /**
10
- * @module style
11
- * @author Julien Gaffuri
12
- */
13
- export class IsoFenceStyle extends Style {
14
- /** @param {object} opts */
15
- constructor(opts) {
16
- super(opts)
17
- opts = opts || {}
18
-
19
- /**
20
- * The dictionary (string -> color) which give the color of each category.
21
- * @type {object} */
22
- this.color = opts.color
23
-
24
- /** A function returning the height of a cell in geographical unit.
25
- * @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
26
- this.height = opts.height || ((cell, resolution, z, viewScale) => resolution * 0.4)
27
-
28
- /** The perspective angle, in degree, within [-180,180], from [O,x] axis.
29
- * @type {number} */
30
- this.angle = opts.angle != undefined ? opts.angle : 50
31
-
32
- /** A function returning the corner line stroke style.
33
- * @type {function(import('../core/Dataset.js').Cell,number,number,number):string} */
34
- this.cornerLineStrokeColor = opts.cornerLineStrokeColor || ((c, r, z, angle) => '#999')
35
-
36
- /** A function returning the corner line width.
37
- * @type {function(import('../core/Dataset.js').Cell,number,number,number):number} */
38
- this.cornerLineWidth = opts.cornerLineWidth || ((c, r, z, angle) => (angle % 90 == 0 ? 0 : 0.8 * z))
39
-
40
- /**
41
- * Show vertical cross-sections.
42
- * @type {boolean} */
43
- this.sVert = opts.sVert != undefined ? opts.sVert : true
44
-
45
- /**
46
- * Show horizontal cross-sections.
47
- * @type {boolean} */
48
- this.sHor = opts.sHor != undefined ? opts.sHor : true
49
- }
50
-
51
- /**
52
- * @param {Array.<import("../core/Dataset.js").Cell>} cells
53
- * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
54
- * @param {number} resolution
55
- * @override
56
- */
57
- draw(cells, geoCanvas, resolution) {
58
- //filter
59
- if (this.filter) cells = cells.filter(this.filter)
60
-
61
- //
62
- const z = geoCanvas.view.z
63
- const ctx = geoCanvas.offscreenCtx
64
-
65
- //get view scale
66
- const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
67
-
68
- //nb categories - used for radar and agepyramid
69
- const cats = Object.keys(this.color)
70
-
71
- //half resolution
72
- const r2 = resolution / 2
73
-
74
- //get offset
75
- // @ts-ignore
76
- const offset = this.offset(undefined, resolution, z),
77
- dx = offset.dx,
78
- dy = offset.dy
79
-
80
- //make sides
81
- /** @type {Array.<Side>} */
82
- const sides = SideStyle.buildSides(
83
- cells,
84
- resolution,
85
- this.angle % 180 != 90 && this.sVert,
86
- this.angle % 180 != 0 && this.sHor
87
- )
88
-
89
- //
90
- if (sides.length == 0) return
91
-
92
- //angle in radians
93
- const aRad = (this.angle * Math.PI) / 180,
94
- cos = Math.cos(aRad),
95
- sin = Math.sin(aRad)
96
-
97
- //sort sides so that the back ones are drawn first. This depends on the angle.
98
- //depending on distance to the reference corner point
99
- const xCorner = Math.abs(this.angle) < 90 ? geoCanvas.extGeo.xMin : geoCanvas.extGeo.xMax
100
- const yCorner = this.angle < 0 ? geoCanvas.extGeo.yMax : geoCanvas.extGeo.yMin
101
- sides.sort(
102
- (s1, s2) =>
103
- Math.hypot(s2.x - xCorner, s2.y - yCorner) - Math.hypot(s1.x - xCorner, s1.y - yCorner)
104
- )
105
-
106
- //prepare function to draw corner line for a cell *c*
107
- const drawCornerLine = (cell) => {
108
- if (!cell) return
109
- //line style
110
- const lw = this.cornerLineWidth ? this.cornerLineWidth(cell, resolution, z, this.angle) : 0.8 * z
111
- if (lw == 0) return
112
- ctx.strokeStyle = this.cornerLineStrokeColor
113
- ? this.cornerLineStrokeColor(cell, resolution, z, this.angle)
114
- : '#333'
115
- ctx.lineWidth = lw
116
-
117
- //height - in geo
118
- const hG = this.height(cell, resolution, z, viewScale)
119
-
120
- //draw line
121
- ctx.beginPath()
122
- ctx.moveTo(cell.x + r2 + dx, cell.y + r2 + dy)
123
- ctx.lineTo(cell.x + r2 + hG * cos + dx, cell.y + r2 + hG * sin + dy)
124
- ctx.stroke()
125
- }
126
-
127
- //draw sides
128
- ctx.lineCap = 'round'
129
- for (let side of sides) {
130
- const c1 = side.c1,
131
- c2 = side.c2,
132
- x = side.x,
133
- y = side.y
134
-
135
- //heights - in geo
136
- const hG1 = c1 ? this.height(c1, resolution, z, viewScale) : 0,
137
- hG2 = c2 ? this.height(c2, resolution, z, viewScale) : 0
138
-
139
- //compute totals for both cells
140
- const total1 = computeTotal(c1, cats),
141
- total2 = computeTotal(c2, cats)
142
- if (total1 == 0 && total2 == 0) continue
143
-
144
- let cumul1 = 0,
145
- cumul2 = 0
146
- for (let [column, color] of Object.entries(this.color)) {
147
- //draw stripe of side s and category column
148
-
149
- //get values for both cells
150
- let v1 = c1 ? +c1[column] : 0
151
- let v2 = c2 ? +c2[column] : 0
152
- if (v1 == 0 && v2 == 0) continue
153
-
154
- //compute heights
155
- const h1 = (hG1 * cumul1) / total1 || 0
156
- const h1n = (hG1 * (cumul1 + v1)) / total1 || 0
157
- const h2 = (hG2 * cumul2) / total2 || 0
158
- const h2n = (hG2 * (cumul2 + v2)) / total2 || 0
159
-
160
- //make path
161
- ctx.beginPath()
162
- if (side.or == 'h') {
163
- //horizontal side - vertical section
164
- //bottom left
165
- ctx.moveTo(x + h1 * cos + dx, y - r2 + h1 * sin + dy)
166
- //top left
167
- ctx.lineTo(x + h2 * cos + dx, y + r2 + h2 * sin + dy)
168
- //top right
169
- ctx.lineTo(x + h2n * cos + dx, y + r2 + h2n * sin + dy)
170
- //bottom right
171
- ctx.lineTo(x + h1n * cos + dx, y - r2 + h1n * sin + dy)
172
- } else {
173
- //vertical side - horizontal section
174
- //bottom left
175
- ctx.moveTo(x - r2 + h1 * cos + dx, y + h1 * sin + dy)
176
- //bottom right
177
- ctx.lineTo(x + r2 + h2 * cos + dx, y + h2 * sin + dy)
178
- //top right
179
- ctx.lineTo(x + r2 + h2n * cos + dx, y + h2n * sin + dy)
180
- //top left
181
- ctx.lineTo(x - r2 + h1n * cos + dx, y + h1n * sin + dy)
182
- }
183
- //cg.ctx.closePath()
184
-
185
- //fill
186
- ctx.fillStyle = color
187
- ctx.fill()
188
-
189
- cumul1 += v1
190
- cumul2 += v2
191
-
192
- //TODO draw only one line
193
- //draw corner line
194
- //if (side.or == "h") {
195
- drawCornerLine(c1)
196
- drawCornerLine(c2)
197
- //if (this.angle > 0 && side.or == "h") drawCornerLine(c2)
198
- //else drawCornerLine(c2)
199
- //}
200
- }
201
- }
202
-
203
- //update legends
204
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
205
- }
206
- }
207
-
208
- const computeTotal = (cell, categories) => {
209
- if (!cell) return 0
210
- let total = 0
211
- for (let column of categories) {
212
- const v = cell[column]
213
- if (!v) continue
214
- total += +v
215
- }
216
- return total || 0
217
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Style } from '../core/Style.js'
5
+ import { SideStyle } from './SideStyle.js'
6
+
7
+ /** @typedef {{x:number,y:number,or:"v"|"h",c1:import('../core/Dataset.js').Cell|undefined,c2:import('../core/Dataset.js').Cell|undefined}} Side */
8
+
9
+ /**
10
+ * @module style
11
+ * @author Julien Gaffuri
12
+ */
13
+ export class IsoFenceStyle extends Style {
14
+ /** @param {object} opts */
15
+ constructor(opts) {
16
+ super(opts)
17
+ opts = opts || {}
18
+
19
+ /**
20
+ * The dictionary (string -> color) which give the color of each category.
21
+ * @type {object} */
22
+ this.color = opts.color
23
+
24
+ /** A function returning the height of a cell in geographical unit.
25
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
26
+ this.height = opts.height || ((cell, resolution, z, viewScale) => resolution * 0.4)
27
+
28
+ /** The perspective angle, in degree, within [-180,180], from [O,x] axis.
29
+ * @type {number} */
30
+ this.angle = opts.angle != undefined ? opts.angle : 50
31
+
32
+ /** A function returning the corner line stroke style.
33
+ * @type {function(import('../core/Dataset.js').Cell,number,number,number):string} */
34
+ this.cornerLineStrokeColor = opts.cornerLineStrokeColor || ((c, r, z, angle) => '#999')
35
+
36
+ /** A function returning the corner line width.
37
+ * @type {function(import('../core/Dataset.js').Cell,number,number,number):number} */
38
+ this.cornerLineWidth = opts.cornerLineWidth || ((c, r, z, angle) => (angle % 90 == 0 ? 0 : 0.8 * z))
39
+
40
+ /**
41
+ * Show vertical cross-sections.
42
+ * @type {boolean} */
43
+ this.sVert = opts.sVert != undefined ? opts.sVert : true
44
+
45
+ /**
46
+ * Show horizontal cross-sections.
47
+ * @type {boolean} */
48
+ this.sHor = opts.sHor != undefined ? opts.sHor : true
49
+ }
50
+
51
+ /**
52
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
53
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
54
+ * @param {number} resolution
55
+ * @override
56
+ */
57
+ draw(cells, geoCanvas, resolution) {
58
+ //filter
59
+ if (this.filter) cells = cells.filter(this.filter)
60
+
61
+ //
62
+ const z = geoCanvas.view.z
63
+ const ctx = geoCanvas.offscreenCtx
64
+
65
+ //get view scale
66
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
67
+
68
+ //nb categories - used for radar and agepyramid
69
+ const cats = Object.keys(this.color)
70
+
71
+ //half resolution
72
+ const r2 = resolution / 2
73
+
74
+ //get offset
75
+ // @ts-ignore
76
+ const offset = this.offset(undefined, resolution, z),
77
+ dx = offset.dx,
78
+ dy = offset.dy
79
+
80
+ //make sides
81
+ /** @type {Array.<Side>} */
82
+ const sides = SideStyle.buildSides(
83
+ cells,
84
+ resolution,
85
+ this.angle % 180 != 90 && this.sVert,
86
+ this.angle % 180 != 0 && this.sHor
87
+ )
88
+
89
+ //
90
+ if (sides.length == 0) return
91
+
92
+ //angle in radians
93
+ const aRad = (this.angle * Math.PI) / 180,
94
+ cos = Math.cos(aRad),
95
+ sin = Math.sin(aRad)
96
+
97
+ //sort sides so that the back ones are drawn first. This depends on the angle.
98
+ //depending on distance to the reference corner point
99
+ const xCorner = Math.abs(this.angle) < 90 ? geoCanvas.extGeo.xMin : geoCanvas.extGeo.xMax
100
+ const yCorner = this.angle < 0 ? geoCanvas.extGeo.yMax : geoCanvas.extGeo.yMin
101
+ sides.sort(
102
+ (s1, s2) =>
103
+ Math.hypot(s2.x - xCorner, s2.y - yCorner) - Math.hypot(s1.x - xCorner, s1.y - yCorner)
104
+ )
105
+
106
+ //prepare function to draw corner line for a cell *c*
107
+ const drawCornerLine = (cell) => {
108
+ if (!cell) return
109
+ //line style
110
+ const lw = this.cornerLineWidth ? this.cornerLineWidth(cell, resolution, z, this.angle) : 0.8 * z
111
+ if (lw == 0) return
112
+ ctx.strokeStyle = this.cornerLineStrokeColor
113
+ ? this.cornerLineStrokeColor(cell, resolution, z, this.angle)
114
+ : '#333'
115
+ ctx.lineWidth = lw
116
+
117
+ //height - in geo
118
+ const hG = this.height(cell, resolution, z, viewScale)
119
+
120
+ //draw line
121
+ ctx.beginPath()
122
+ ctx.moveTo(cell.x + r2 + dx, cell.y + r2 + dy)
123
+ ctx.lineTo(cell.x + r2 + hG * cos + dx, cell.y + r2 + hG * sin + dy)
124
+ ctx.stroke()
125
+ }
126
+
127
+ //draw sides
128
+ ctx.lineCap = 'round'
129
+ for (let side of sides) {
130
+ const c1 = side.c1,
131
+ c2 = side.c2,
132
+ x = side.x,
133
+ y = side.y
134
+
135
+ //heights - in geo
136
+ const hG1 = c1 ? this.height(c1, resolution, z, viewScale) : 0,
137
+ hG2 = c2 ? this.height(c2, resolution, z, viewScale) : 0
138
+
139
+ //compute totals for both cells
140
+ const total1 = computeTotal(c1, cats),
141
+ total2 = computeTotal(c2, cats)
142
+ if (total1 == 0 && total2 == 0) continue
143
+
144
+ let cumul1 = 0,
145
+ cumul2 = 0
146
+ for (let [column, color] of Object.entries(this.color)) {
147
+ //draw stripe of side s and category column
148
+
149
+ //get values for both cells
150
+ let v1 = c1 ? +c1[column] : 0
151
+ let v2 = c2 ? +c2[column] : 0
152
+ if (v1 == 0 && v2 == 0) continue
153
+
154
+ //compute heights
155
+ const h1 = (hG1 * cumul1) / total1 || 0
156
+ const h1n = (hG1 * (cumul1 + v1)) / total1 || 0
157
+ const h2 = (hG2 * cumul2) / total2 || 0
158
+ const h2n = (hG2 * (cumul2 + v2)) / total2 || 0
159
+
160
+ //make path
161
+ ctx.beginPath()
162
+ if (side.or == 'h') {
163
+ //horizontal side - vertical section
164
+ //bottom left
165
+ ctx.moveTo(x + h1 * cos + dx, y - r2 + h1 * sin + dy)
166
+ //top left
167
+ ctx.lineTo(x + h2 * cos + dx, y + r2 + h2 * sin + dy)
168
+ //top right
169
+ ctx.lineTo(x + h2n * cos + dx, y + r2 + h2n * sin + dy)
170
+ //bottom right
171
+ ctx.lineTo(x + h1n * cos + dx, y - r2 + h1n * sin + dy)
172
+ } else {
173
+ //vertical side - horizontal section
174
+ //bottom left
175
+ ctx.moveTo(x - r2 + h1 * cos + dx, y + h1 * sin + dy)
176
+ //bottom right
177
+ ctx.lineTo(x + r2 + h2 * cos + dx, y + h2 * sin + dy)
178
+ //top right
179
+ ctx.lineTo(x + r2 + h2n * cos + dx, y + h2n * sin + dy)
180
+ //top left
181
+ ctx.lineTo(x - r2 + h1n * cos + dx, y + h1n * sin + dy)
182
+ }
183
+ //cg.ctx.closePath()
184
+
185
+ //fill
186
+ ctx.fillStyle = color
187
+ ctx.fill()
188
+
189
+ cumul1 += v1
190
+ cumul2 += v2
191
+
192
+ //TODO draw only one line
193
+ //draw corner line
194
+ //if (side.or == "h") {
195
+ drawCornerLine(c1)
196
+ drawCornerLine(c2)
197
+ //if (this.angle > 0 && side.or == "h") drawCornerLine(c2)
198
+ //else drawCornerLine(c2)
199
+ //}
200
+ }
201
+ }
202
+
203
+ //update legends
204
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
205
+ }
206
+ }
207
+
208
+ const computeTotal = (cell, categories) => {
209
+ if (!cell) return 0
210
+ let total = 0
211
+ for (let column of categories) {
212
+ const v = cell[column]
213
+ if (!v) continue
214
+ total += +v
215
+ }
216
+ return total || 0
217
+ }