gridviz 3.0.14 → 3.0.16

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 (55) hide show
  1. package/README.md +127 -128
  2. package/dist/gridviz.js +7959 -7860
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +74 -74
  5. package/src/button/ZoomButtons.js +101 -96
  6. package/src/core/Dataset.js +154 -157
  7. package/src/core/Drawable.js +60 -61
  8. package/src/core/GeoCanvas.js +409 -370
  9. package/src/core/Layer.js +23 -25
  10. package/src/core/Legend.js +108 -110
  11. package/src/core/Map.js +495 -495
  12. package/src/core/MultiResolutionDataset.js +93 -97
  13. package/src/core/Style.js +98 -99
  14. package/src/dataset/CSVGrid.js +112 -112
  15. package/src/dataset/GeoTIFF.js +122 -123
  16. package/src/dataset/JSGrid.js +55 -54
  17. package/src/dataset/TiledGrid.js +289 -288
  18. package/src/dataset/worker.js +18 -0
  19. package/src/index.js +77 -71
  20. package/src/layer/BackgroundLayer.js +162 -158
  21. package/src/layer/BackgroundLayerImage.js +81 -84
  22. package/src/layer/BackgroundLayerWMS.js +104 -108
  23. package/src/layer/GeoJSONLayer.js +214 -220
  24. package/src/layer/GridLayer.js +148 -157
  25. package/src/layer/LabelLayer.js +194 -193
  26. package/src/legend/ColorCategoryLegend.js +109 -110
  27. package/src/legend/ColorDiscreteLegend.js +100 -102
  28. package/src/legend/ColorLegend.js +115 -118
  29. package/src/legend/OrientationLegend.js +89 -91
  30. package/src/legend/SizeLegend.js +224 -224
  31. package/src/legend/TernaryLegend.js +302 -210
  32. package/src/style/CompositionStyle.js +291 -288
  33. package/src/style/DotDensityStyle.js +133 -134
  34. package/src/style/ImageStyle.js +100 -102
  35. package/src/style/IsoFenceStyle.js +217 -203
  36. package/src/style/JoyPlotStyle.js +127 -128
  37. package/src/style/LegoStyle.js +110 -110
  38. package/src/style/MosaicStyle.js +99 -99
  39. package/src/style/NinjaStarStyle.js +102 -102
  40. package/src/style/PillarStyle.js +207 -208
  41. package/src/style/SegmentStyle.js +105 -105
  42. package/src/style/ShapeColorSizeStyle.js +147 -132
  43. package/src/style/SideCategoryStyle.js +112 -114
  44. package/src/style/SideStyle.js +212 -205
  45. package/src/style/SquareColorCategoryWebGLStyle.js +107 -108
  46. package/src/style/SquareColorWebGLStyle.js +126 -126
  47. package/src/style/StrokeStyle.js +135 -136
  48. package/src/style/TanakaStyle.js +69 -68
  49. package/src/style/TextStyle.js +110 -111
  50. package/src/style/TimeSeriesStyle.js +222 -229
  51. package/src/utils/scale.js +218 -228
  52. package/src/utils/stretching.js +120 -133
  53. package/src/utils/ternary.js +203 -203
  54. package/src/utils/utils.js +58 -63
  55. package/src/utils/webGLUtils.js +72 -70
@@ -1,288 +1,291 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Style } from '../core/Style.js'
5
-
6
- /** @typedef {"flag"|"piechart"|"ring"|"segment"|"radar"|"agepyramid"|"halftone"} CompositionType */
7
-
8
- /**
9
- * A style showing the composition of a total in different categories, with different color hues.
10
- * It consists of a symbol with different parts, whose size reflect the proportion of the corresponding category.
11
- * For a list of supported symbols, @see CompositionType
12
- * The symbol can be scaled depending on the cell importance.
13
- *
14
- * @module style
15
- * @author Julien Gaffuri
16
- */
17
- export class CompositionStyle extends Style {
18
- /** @param {object} opts */
19
- constructor(opts) {
20
- super(opts)
21
- opts = opts || {}
22
-
23
- /**
24
- * The dictionary (string -> color) which give the color of each category.
25
- * @type {object} */
26
- this.color = opts.color
27
-
28
- /**
29
- * A function returning the type of decomposition symbol of a cell, @see CompositionType
30
- * @type {function(import("../core/Dataset.js").Cell,number, number,object):CompositionType} */
31
- this.type = opts.type || (() => "flag") //(c,r,z,vs) => {}
32
-
33
- /** A function returning the size of a cell in geographical unit.
34
- * @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
35
- this.size = opts.size || ((c, r) => r) //(c,r,z,vs) => {}
36
-
37
- /** For style types with stripes (flag, segment), the orientation of the stripes (0 for horizontal, other for vertical).
38
- * @type {function(import("../core/Dataset.js").Cell,number,number,object):number} */
39
- this.stripesOrientation = opts.stripesOrientation || (() => 0) //(c,r,z,vs) => ...
40
-
41
- /** The function specifying an offset angle for a radar, halftone or pie chart style.
42
- * The angle is specified in degree. The rotation is anti-clockwise.
43
- * @type {function(import("../core/Dataset.js").Cell,number,number,object):number} */
44
- this.offsetAngle = opts.offsetAngle || (() => 0) //(c,r,z,vs) => ...
45
-
46
- /** The function specifying the height of the age pyramid, in geo unit.
47
- * @type {function(import("../core/Dataset.js").Cell,number,number,object):number} */
48
- this.agePyramidHeight = opts.agePyramidHeight || ((c, r) => r) //(c,r,z,vs) => ...
49
-
50
- /** For pie chart, this is parameter for internal radius, so that the pie chart looks like a donut.
51
- * 0 for normal pie charts, 0.5 to empty half of the radius.
52
- * @type {number} */
53
- this.pieChartInternalRadiusFactor = opts.pieChartInternalRadiusFactor || 0
54
- }
55
-
56
- /**
57
- * Draw cells as squares depending on their value.
58
- *
59
- * @param {Array.<import("../core/Dataset.js").Cell>} cells
60
- * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
61
- * @param {number} resolution
62
- */
63
- draw(cells, geoCanvas, resolution) {
64
-
65
- //filter
66
- if (this.filter) cells = cells.filter(this.filter)
67
-
68
- //
69
- const z = geoCanvas.view.z
70
-
71
- //get view scale
72
- const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
73
-
74
- //nb categories - used for radar and agepyramid
75
- const nbCat = Object.entries(this.color).length
76
-
77
- //draw calls
78
- for (let cell of cells) {
79
-
80
- //size
81
- const sG = this.size ? this.size(cell, resolution, z, viewScale) : resolution
82
- if (!sG) continue
83
-
84
- //get offset
85
- const offset = this.offset(cell, resolution, z)
86
-
87
- //get symbol type
88
- const type_ = this.type ? this.type(cell, resolution, z, viewScale) : 'flag'
89
-
90
- //compute center position
91
- const xc = cell.x + offset.dx + (type_ === 'agepyramid' ? 0 : resolution * 0.5)
92
- const yc = cell.y + offset.dy + (type_ === 'agepyramid' ? 0 : resolution * 0.5)
93
-
94
- //compute offset angle, when relevant
95
- const offAng = this.offsetAngle ? (this.offsetAngle(cell, resolution, z, viewScale) * Math.PI) / 180 : 0
96
-
97
- if (type_ === 'agepyramid' || type_ === 'radar' || type_ === 'halftone') {
98
- //get cell category max value
99
- let maxVal = -Infinity
100
- for (let key of Object.keys(this.color)) {
101
- const v = +cell[key]
102
- if (v > maxVal) maxVal = v
103
- }
104
-
105
- //cumul
106
- let cumul = 0
107
- if (type_ === 'agepyramid' && this.agePyramidHeight)
108
- cumul = (resolution - this.agePyramidHeight(cell, resolution, z, viewScale)) / 2
109
- if (type_ === 'radar' || type_ === 'halftone') cumul = Math.PI / 2 + offAng
110
-
111
- //compute the increment, which is the value to increment the cumul for each category
112
- const incr =
113
- type_ === 'agepyramid'
114
- ? (this.agePyramidHeight ? this.agePyramidHeight(cell, resolution, z, viewScale) : resolution) / nbCat
115
- : type_ === 'radar' || type_ === 'halftone'
116
- ? (2 * Math.PI) / nbCat
117
- : undefined
118
- if (incr === undefined) throw new Error('Unexpected symbol type:' + type_)
119
-
120
- for (let [column, color] of Object.entries(this.color)) {
121
- if (type_ === 'agepyramid') {
122
- //set category color
123
- geoCanvas.ctx.fillStyle = color
124
-
125
- //get category value
126
- const val = cell[column]
127
-
128
- //compute category length - in geo
129
- /** @type {number} */
130
- const wG = (sG * val) / maxVal
131
-
132
- //draw bar
133
- geoCanvas.ctx.fillRect(xc + (resolution - wG) / 2, yc + cumul, wG, incr)
134
-
135
- //next height
136
- cumul += incr
137
- } else if (type_ === 'radar') {
138
- //set category color
139
- geoCanvas.ctx.fillStyle = color
140
-
141
- //get categroy value
142
- const val = cell[column]
143
-
144
- //compute category radius - in geo
145
- /** @type {number} */
146
- //const rG = this.radius(val, r, stat, cellStat, z)
147
- const rG = (sG / 2) * Math.sqrt(val / maxVal)
148
-
149
- //draw angular sector
150
- geoCanvas.ctx.beginPath()
151
- geoCanvas.ctx.moveTo(xc, yc)
152
- geoCanvas.ctx.arc(xc, yc, rG, cumul - incr, cumul)
153
- geoCanvas.ctx.lineTo(xc, yc)
154
- geoCanvas.ctx.fill()
155
-
156
- //next angular sector
157
- cumul += incr
158
- } else if (type_ === 'halftone') {
159
- //set category color
160
- geoCanvas.ctx.fillStyle = color
161
-
162
- //get categroy value
163
- const val = cell[column]
164
-
165
- //compute category radius - in geo
166
- /** @type {number} */
167
- const rG = sG * 0.333 * Math.sqrt(val / maxVal)
168
-
169
- //draw circle
170
- geoCanvas.ctx.beginPath()
171
- geoCanvas.ctx.arc(
172
- xc + resolution * 0.25 * Math.cos(cumul),
173
- yc + resolution * 0.25 * Math.sin(cumul),
174
- rG,
175
- 0,
176
- 2 * Math.PI
177
- )
178
- geoCanvas.ctx.fill()
179
-
180
- //next angular sector
181
- cumul += incr
182
- } else {
183
- throw new Error('Unexpected symbol type:' + type_)
184
- }
185
- }
186
- } else {
187
- //compute total
188
- let total = 0
189
- for (let column of Object.keys(this.color)) {
190
- const v = +cell[column]
191
- if (!v) continue
192
- total += v
193
- }
194
- if (!total || isNaN(total)) continue
195
-
196
- //draw decomposition symbol
197
- let cumul = 0
198
- const d = resolution * (1 - sG / resolution) * 0.5
199
- const ori = this.stripesOrientation(cell, resolution, z, viewScale)
200
-
201
- for (let [column, color] of Object.entries(this.color)) {
202
- //get share
203
- const share = cell[column] / total
204
- if (!share || isNaN(share)) continue
205
-
206
- //set color
207
- geoCanvas.ctx.fillStyle = color
208
-
209
- //draw symbol part
210
- if (type_ === 'flag') {
211
- //draw flag stripe
212
- if (ori == 0) {
213
- //horizontal
214
- geoCanvas.ctx.fillRect(
215
- cell.x + d + offset.dx,
216
- cell.y + d + cumul * sG + offset.dy,
217
- sG,
218
- share * sG
219
- )
220
- } else {
221
- //vertical
222
- geoCanvas.ctx.fillRect(
223
- cell.x + d + cumul * sG + offset.dx,
224
- cell.y + d + offset.dy,
225
- share * sG,
226
- sG
227
- )
228
- }
229
- } else if (type_ === 'piechart') {
230
- //draw pie chart angular sector
231
-
232
- //compute angles
233
- const a1 = cumul * 2 * Math.PI
234
- const a2 = (cumul + share) * 2 * Math.PI
235
-
236
- //draw
237
- geoCanvas.ctx.beginPath()
238
- geoCanvas.ctx.moveTo(xc, yc)
239
- geoCanvas.ctx.arc(xc, yc, sG * 0.5, a1 + offAng, a2 + offAng)
240
- if (this.pieChartInternalRadiusFactor)
241
- geoCanvas.ctx.arc(
242
- xc,
243
- yc,
244
- sG * 0.5 * this.pieChartInternalRadiusFactor,
245
- a1 + offAng,
246
- a2 + offAng,
247
- true
248
- )
249
- geoCanvas.ctx.closePath()
250
- geoCanvas.ctx.fill()
251
- } else if (type_ === 'ring') {
252
- //draw ring
253
- geoCanvas.ctx.beginPath()
254
- geoCanvas.ctx.arc(xc, yc, Math.sqrt(1 - cumul) * sG * 0.5, 0, 2 * Math.PI)
255
- geoCanvas.ctx.fill()
256
- } else if (type_ === 'segment') {
257
- //draw segment sections
258
- const wG = (sG * sG) / resolution
259
- if (ori == 0) {
260
- //horizontal
261
- geoCanvas.ctx.fillRect(
262
- cell.x + offset.dx,
263
- cell.y + (resolution - wG) / 2 + cumul * wG + offset.dy,
264
- resolution,
265
- share * wG
266
- )
267
- } else {
268
- //vertical
269
- geoCanvas.ctx.fillRect(
270
- cell.x + cumul * resolution + offset.dx,
271
- cell.y + (resolution - wG) / 2 + offset.dy,
272
- share * resolution,
273
- wG
274
- )
275
- }
276
- } else {
277
- throw new Error('Unexpected symbol type:' + type_)
278
- }
279
-
280
- cumul += share
281
- }
282
- }
283
- }
284
-
285
- //update legends
286
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
287
- }
288
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Style } from '../core/Style.js'
5
+
6
+ /** @typedef {"flag"|"piechart"|"ring"|"segment"|"radar"|"agepyramid"|"halftone"} CompositionType */
7
+
8
+ /**
9
+ * A style showing the composition of a total in different categories, with different color hues.
10
+ * It consists of a symbol with different parts, whose size reflect the proportion of the corresponding category.
11
+ * For a list of supported symbols, @see CompositionType
12
+ * The symbol can be scaled depending on the cell importance.
13
+ *
14
+ * @module style
15
+ * @author Julien Gaffuri
16
+ */
17
+ export class CompositionStyle extends Style {
18
+ /** @param {object} opts */
19
+ constructor(opts) {
20
+ super(opts)
21
+ opts = opts || {}
22
+
23
+ /**
24
+ * The dictionary (string -> color) which give the color of each category.
25
+ * @type {object} */
26
+ this.color = opts.color
27
+
28
+ /**
29
+ * A function returning the type of decomposition symbol of a cell, @see CompositionType
30
+ * @type {function(import("../core/Dataset.js").Cell,number, number,object):CompositionType} */
31
+ this.type = opts.type || (() => 'flag') //(c,r,z,vs) => {}
32
+
33
+ /** A function returning the size of a cell in geographical unit.
34
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
35
+ this.size = opts.size || ((c, r) => r) //(c,r,z,vs) => {}
36
+
37
+ /** For style types with stripes (flag, segment), the orientation of the stripes (0 for horizontal, other for vertical).
38
+ * @type {function(import("../core/Dataset.js").Cell,number,number,object):number} */
39
+ this.stripesOrientation = opts.stripesOrientation || (() => 0) //(c,r,z,vs) => ...
40
+
41
+ /** The function specifying an offset angle for a radar, halftone or pie chart style.
42
+ * The angle is specified in degree. The rotation is anti-clockwise.
43
+ * @type {function(import("../core/Dataset.js").Cell,number,number,object):number} */
44
+ this.offsetAngle = opts.offsetAngle || (() => 0) //(c,r,z,vs) => ...
45
+
46
+ /** The function specifying the height of the age pyramid, in geo unit.
47
+ * @type {function(import("../core/Dataset.js").Cell,number,number,object):number} */
48
+ this.agePyramidHeight = opts.agePyramidHeight || ((c, r) => r) //(c,r,z,vs) => ...
49
+
50
+ /** For pie chart, this is parameter for internal radius, so that the pie chart looks like a donut.
51
+ * 0 for normal pie charts, 0.5 to empty half of the radius.
52
+ * @type {number} */
53
+ this.pieChartInternalRadiusFactor = opts.pieChartInternalRadiusFactor || 0
54
+ }
55
+
56
+ /**
57
+ * Draw cells as squares depending on their value.
58
+ *
59
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
60
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
61
+ * @param {number} resolution
62
+ */
63
+ draw(cells, geoCanvas, resolution) {
64
+ //filter
65
+ if (this.filter) cells = cells.filter(this.filter)
66
+
67
+ //
68
+ const z = geoCanvas.view.z
69
+ const ctx = geoCanvas.offscreenCtx
70
+
71
+ //get view scale
72
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
73
+
74
+ //nb categories - used for radar and agepyramid
75
+ const nbCat = Object.entries(this.color).length
76
+
77
+ //draw calls
78
+ for (let cell of cells) {
79
+ //size
80
+ const sG = this.size ? this.size(cell, resolution, z, viewScale) : resolution
81
+ if (!sG) continue
82
+
83
+ //get offset
84
+ const offset = this.offset(cell, resolution, z)
85
+
86
+ //get symbol type
87
+ const type_ = this.type ? this.type(cell, resolution, z, viewScale) : 'flag'
88
+
89
+ //compute center position
90
+ const xc = cell.x + offset.dx + (type_ === 'agepyramid' ? 0 : resolution * 0.5)
91
+ const yc = cell.y + offset.dy + (type_ === 'agepyramid' ? 0 : resolution * 0.5)
92
+
93
+ //compute offset angle, when relevant
94
+ const offAng = this.offsetAngle
95
+ ? (this.offsetAngle(cell, resolution, z, viewScale) * Math.PI) / 180
96
+ : 0
97
+
98
+ if (type_ === 'agepyramid' || type_ === 'radar' || type_ === 'halftone') {
99
+ //get cell category max value
100
+ let maxVal = -Infinity
101
+ for (let key of Object.keys(this.color)) {
102
+ const v = +cell[key]
103
+ if (v > maxVal) maxVal = v
104
+ }
105
+
106
+ //cumul
107
+ let cumul = 0
108
+ if (type_ === 'agepyramid' && this.agePyramidHeight)
109
+ cumul = (resolution - this.agePyramidHeight(cell, resolution, z, viewScale)) / 2
110
+ if (type_ === 'radar' || type_ === 'halftone') cumul = Math.PI / 2 + offAng
111
+
112
+ //compute the increment, which is the value to increment the cumul for each category
113
+ const incr =
114
+ type_ === 'agepyramid'
115
+ ? (this.agePyramidHeight
116
+ ? this.agePyramidHeight(cell, resolution, z, viewScale)
117
+ : resolution) / nbCat
118
+ : type_ === 'radar' || type_ === 'halftone'
119
+ ? (2 * Math.PI) / nbCat
120
+ : undefined
121
+ if (incr === undefined) throw new Error('Unexpected symbol type:' + type_)
122
+
123
+ for (let [column, color] of Object.entries(this.color)) {
124
+ if (type_ === 'agepyramid') {
125
+ //set category color
126
+ ctx.fillStyle = color
127
+
128
+ //get category value
129
+ const val = cell[column]
130
+
131
+ //compute category length - in geo
132
+ /** @type {number} */
133
+ const wG = (sG * val) / maxVal
134
+
135
+ //draw bar
136
+ ctx.fillRect(xc + (resolution - wG) / 2, yc + cumul, wG, incr)
137
+
138
+ //next height
139
+ cumul += incr
140
+ } else if (type_ === 'radar') {
141
+ //set category color
142
+ ctx.fillStyle = color
143
+
144
+ //get categroy value
145
+ const val = cell[column]
146
+
147
+ //compute category radius - in geo
148
+ /** @type {number} */
149
+ //const rG = this.radius(val, r, stat, cellStat, z)
150
+ const rG = (sG / 2) * Math.sqrt(val / maxVal)
151
+
152
+ //draw angular sector
153
+ ctx.beginPath()
154
+ ctx.moveTo(xc, yc)
155
+ ctx.arc(xc, yc, rG, cumul - incr, cumul)
156
+ ctx.lineTo(xc, yc)
157
+ ctx.fill()
158
+
159
+ //next angular sector
160
+ cumul += incr
161
+ } else if (type_ === 'halftone') {
162
+ //set category color
163
+ ctx.fillStyle = color
164
+
165
+ //get categroy value
166
+ const val = cell[column]
167
+
168
+ //compute category radius - in geo
169
+ /** @type {number} */
170
+ const rG = sG * 0.333 * Math.sqrt(val / maxVal)
171
+
172
+ //draw circle
173
+ ctx.beginPath()
174
+ ctx.arc(
175
+ xc + resolution * 0.25 * Math.cos(cumul),
176
+ yc + resolution * 0.25 * Math.sin(cumul),
177
+ rG,
178
+ 0,
179
+ 2 * Math.PI
180
+ )
181
+ ctx.fill()
182
+
183
+ //next angular sector
184
+ cumul += incr
185
+ } else {
186
+ throw new Error('Unexpected symbol type:' + type_)
187
+ }
188
+ }
189
+ } else {
190
+ //compute total
191
+ let total = 0
192
+ for (let column of Object.keys(this.color)) {
193
+ const v = +cell[column]
194
+ if (!v) continue
195
+ total += v
196
+ }
197
+ if (!total || isNaN(total)) continue
198
+
199
+ //draw decomposition symbol
200
+ let cumul = 0
201
+ const d = resolution * (1 - sG / resolution) * 0.5
202
+ const ori = this.stripesOrientation(cell, resolution, z, viewScale)
203
+
204
+ for (let [column, color] of Object.entries(this.color)) {
205
+ //get share
206
+ const share = cell[column] / total
207
+ if (!share || isNaN(share)) continue
208
+
209
+ //set color
210
+ ctx.fillStyle = color
211
+
212
+ //draw symbol part
213
+ if (type_ === 'flag') {
214
+ //draw flag stripe
215
+ if (ori == 0) {
216
+ //horizontal
217
+ ctx.fillRect(
218
+ cell.x + d + offset.dx,
219
+ cell.y + d + cumul * sG + offset.dy,
220
+ sG,
221
+ share * sG
222
+ )
223
+ } else {
224
+ //vertical
225
+ ctx.fillRect(
226
+ cell.x + d + cumul * sG + offset.dx,
227
+ cell.y + d + offset.dy,
228
+ share * sG,
229
+ sG
230
+ )
231
+ }
232
+ } else if (type_ === 'piechart') {
233
+ //draw pie chart angular sector
234
+
235
+ //compute angles
236
+ const a1 = cumul * 2 * Math.PI
237
+ const a2 = (cumul + share) * 2 * Math.PI
238
+
239
+ //draw
240
+ ctx.beginPath()
241
+ ctx.moveTo(xc, yc)
242
+ ctx.arc(xc, yc, sG * 0.5, a1 + offAng, a2 + offAng)
243
+ if (this.pieChartInternalRadiusFactor)
244
+ ctx.arc(
245
+ xc,
246
+ yc,
247
+ sG * 0.5 * this.pieChartInternalRadiusFactor,
248
+ a1 + offAng,
249
+ a2 + offAng,
250
+ true
251
+ )
252
+ ctx.closePath()
253
+ ctx.fill()
254
+ } else if (type_ === 'ring') {
255
+ //draw ring
256
+ ctx.beginPath()
257
+ ctx.arc(xc, yc, Math.sqrt(1 - cumul) * sG * 0.5, 0, 2 * Math.PI)
258
+ ctx.fill()
259
+ } else if (type_ === 'segment') {
260
+ //draw segment sections
261
+ const wG = (sG * sG) / resolution
262
+ if (ori == 0) {
263
+ //horizontal
264
+ ctx.fillRect(
265
+ cell.x + offset.dx,
266
+ cell.y + (resolution - wG) / 2 + cumul * wG + offset.dy,
267
+ resolution,
268
+ share * wG
269
+ )
270
+ } else {
271
+ //vertical
272
+ ctx.fillRect(
273
+ cell.x + cumul * resolution + offset.dx,
274
+ cell.y + (resolution - wG) / 2 + offset.dy,
275
+ share * resolution,
276
+ wG
277
+ )
278
+ }
279
+ } else {
280
+ throw new Error('Unexpected symbol type:' + type_)
281
+ }
282
+
283
+ cumul += share
284
+ }
285
+ }
286
+ }
287
+
288
+ //update legends
289
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
290
+ }
291
+ }