gridviz 3.1.0 → 3.1.1

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 (46) hide show
  1. package/README.md +18 -15
  2. package/dist/gridviz.js +3829 -2623
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +5 -3
  5. package/src/button/Button.js +77 -68
  6. package/src/button/FullscreenButton.js +123 -123
  7. package/src/button/ZoomButtons.js +109 -104
  8. package/src/core/GeoCanvas.js +15 -0
  9. package/src/core/Legend.js +267 -245
  10. package/src/core/Map.js +819 -670
  11. package/src/core/Tooltip.js +191 -185
  12. package/src/index.js +82 -79
  13. package/src/layer/GridLayer.js +4 -3
  14. package/src/layer/LabelLayer.js +7 -4
  15. package/src/legend/ColorCategoryLegend.js +127 -125
  16. package/src/legend/ColorDiscreteLegend.js +116 -114
  17. package/src/legend/ColorLegend.js +33 -11
  18. package/src/legend/OrientationLegend.js +94 -92
  19. package/src/legend/SizeLegend.js +8 -1
  20. package/src/legend/TernaryLegend.js +317 -314
  21. package/src/legend/VennLegend.js +202 -0
  22. package/src/style/CircleColorSizeWebGLStyle.js +249 -0
  23. package/src/style/CompositionStyle.js +1 -1
  24. package/src/style/DotDensityStyle.js +8 -4
  25. package/src/style/ImageStyle.js +1 -1
  26. package/src/style/Interpolator.js +283 -259
  27. package/src/style/IsoFenceStyle.js +1 -1
  28. package/src/style/LegoStyle.js +6 -5
  29. package/src/style/MosaicStyle.js +1 -1
  30. package/src/style/NinjaStarStyle.js +1 -1
  31. package/src/style/PillarStyle.js +1 -1
  32. package/src/style/RandomWalkInterpolator.js +213 -0
  33. package/src/style/ShadingRayStyle.js +16 -2
  34. package/src/style/ShadingStyle.js +80 -72
  35. package/src/style/ShapeColorSizeStyle.js +18 -2
  36. package/src/style/SideCategoryStyle.js +1 -1
  37. package/src/style/SideStyle.js +1 -1
  38. package/src/style/SideTanakaStyle.js +1 -1
  39. package/src/style/SquareColorCategoryWebGLStyle.js +71 -20
  40. package/src/style/SquareColorWebGLStyle.js +7 -4
  41. package/src/style/StrokeStyle.js +1 -1
  42. package/src/style/TextStyle.js +1 -1
  43. package/src/style/TimeSeriesStyle.js +14 -7
  44. package/src/utils/WebGLSquareColoringAdvanced.js +47 -9
  45. package/src/utils/scale.js +20 -0
  46. package/src/utils/webGLUtils.js +52 -0
@@ -1,259 +1,283 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Style } from '../core/Style.js'
5
- import { isVisibleAt } from '../core/Drawable.js'
6
- import { cellsToMatrix } from '../utils/utils.js'
7
-
8
- /**
9
- * @module style
10
- * @author Julien Gaffuri
11
- */
12
- export class Interpolator extends Style {
13
- /** @param {object} opts */
14
- constructor(opts) {
15
- super(opts)
16
- opts = opts || {}
17
-
18
- /** The cell value to interpolate
19
- * @type { function } } */
20
- this.value = opts.value //(c) => elevation
21
-
22
- /** The target resolution. As a function (resolution, z) => targetResolution
23
- * NB: Try to make sure that resolution/targetResolution is an integer.
24
- * @type { function } } */
25
- this.targetResolution = opts.targetResolution || ((r, z) => r / 5)
26
-
27
- /** the property name to store the interpolated value in the cell
28
- * @type { string } } */
29
- this.interpolatedProperty = opts.interpolatedProperty || 'value'
30
-
31
- // the interpolation method: currently only 'bilinear' is supported
32
- //this.method = opts.method || 'bilinear' // 'nearest', 'bilinear'
33
-
34
- /** when a neighbor cell has no value, take zero value or average of surrounding cells
35
- * @type { string } } */
36
- this.nodataHandling = opts.nodataHandling || "zero" // 'zero', 'average'
37
-
38
- /** The styles to represent the interpolated grid.
39
- * @type {Array.<Style>} */
40
- this.styles = opts.styles || []
41
- }
42
-
43
-
44
- /**
45
- *
46
- * @param {Array.<import("../core/Dataset.js").Cell>} cells
47
- * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
48
- * @param {number} resolution
49
- */
50
- draw(cells, geoCanvas, resolution) {
51
-
52
- //filter cells
53
- if (this.filter) cells = cells.filter(this.filter)
54
- if (cells.length == 0) return;
55
-
56
- //
57
- const z = geoCanvas.view.z
58
-
59
- //get view scale
60
- //const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
61
-
62
- //index cells by y and x
63
- let m = cellsToMatrix(cells, resolution, c => this.value(c))
64
- const x0 = m.x0, y0 = m.y0
65
-
66
- //get target resolution and scale factor
67
- let targetResolution = this.targetResolution(resolution, z)
68
- const scaleFactor = Math.round(resolution / targetResolution)
69
- targetResolution = resolution / scaleFactor
70
-
71
- // compute ray casting shadow
72
- m = bilinearInterpolator(m, scaleFactor, this.nodataHandling);
73
-
74
- // make cells
75
- cells = []
76
- const ra = (resolution - targetResolution) / 2
77
- for (let i = 0; i < m.length; i++) {
78
- const row = m[i]
79
- const y = y0 - i * targetResolution + ra
80
- for (let j = 0; j < row.length; j++) {
81
- const v = row[j]
82
- if (!v) continue
83
- const c = { x: x0 + j * targetResolution + ra, y: y }
84
- c[this.interpolatedProperty] = v
85
- cells.push(c)
86
- }
87
- }
88
-
89
- //draw smoothed cells from styles
90
- const ctx = geoCanvas.offscreenCtx
91
- for (let s of this.styles) {
92
-
93
- //check if style is visible
94
- if (!isVisibleAt(s, z)) continue
95
-
96
- //set style alpha and blend mode
97
- //TODO: multiply by layer alpha ?
98
- if (s.alpha || s.blendOperation) {
99
- ctx.save()
100
- if (s.alpha) ctx.globalAlpha = s.alpha(z)
101
- if (s.blendOperation) ctx.globalCompositeOperation = s.blendOperation(z)
102
- }
103
-
104
- //set affin transform to draw with geographical coordinates
105
- geoCanvas.setCanvasTransform()
106
-
107
- //draw with style
108
- s.draw(cells, geoCanvas, targetResolution)
109
-
110
- //draw style filter
111
- if (s.filterColor) s.drawFilter(geoCanvas)
112
-
113
- //restore ctx
114
- if (s.alpha || s.blendOperation) ctx.restore()
115
- }
116
-
117
- }
118
- }
119
-
120
-
121
- const interp = (topLeft, topRight, bottomLeft, bottomRight, xRatio, yRatio) => {
122
- const top = topLeft + (topRight - topLeft) * xRatio;
123
- const bottom = bottomLeft + (bottomRight - bottomLeft) * xRatio;
124
- return top + (bottom - top) * yRatio;
125
- }
126
-
127
-
128
- function bilinearInterpolator(grid, scaleFactor = 5, nodataHandling = "zero") {
129
-
130
- if (scaleFactor === 1) return grid;
131
-
132
- // input grid dimensions
133
- const rows = grid.length;
134
- if (rows === 0) return [];
135
- const cols = grid[0].length;
136
-
137
- // output grid dimensions
138
- const fineRows = rows * scaleFactor;
139
- const fineCols = cols * scaleFactor;
140
- const fineGrid = Array(fineRows).fill().map(() => Array(fineCols).fill(undefined));
141
-
142
- // check if scale factor is even
143
- const sfIsEven = scaleFactor % 2 === 0
144
-
145
- //compute output grid values
146
- for (let i = 0; i < fineRows; i++) {
147
-
148
- const coarseI = Math.min(Math.floor(i / scaleFactor), rows - 2);
149
- const yRatio = (i % scaleFactor) / scaleFactor;
150
- const i_ = coarseI * scaleFactor + (scaleFactor / 2)
151
-
152
- for (let j = 0; j < fineCols; j++) {
153
- const coarseJ = Math.min(Math.floor(j / scaleFactor), cols - 2);
154
- const xRatio = (j % scaleFactor) / scaleFactor;
155
- const j_ = coarseJ * scaleFactor + (scaleFactor / 2)
156
-
157
- // get four corner values
158
- const topLeft = grid[coarseI][coarseJ];
159
- const topRight = grid[coarseI][coarseJ + 1];
160
- const bottomLeft = grid[coarseI + 1][coarseJ];
161
- const bottomRight = grid[coarseI + 1][coarseJ + 1];
162
-
163
-
164
- if (sfIsEven) {
165
- if (topLeft === undefined && i <= i_ && j <= j_) continue
166
- if (topRight === undefined && i <= i_ && j >= j_) continue
167
- if (bottomLeft === undefined && i >= i_ && j <= j_) continue
168
- if (bottomRight === undefined && i >= i_ && j >= j_) continue
169
- } else {
170
- if (topLeft === undefined && i < i_ && j < j_) continue
171
- if (topRight === undefined && i < i_ && j > j_) continue
172
- if (bottomLeft === undefined && i > i_ && j < j_) continue
173
- if (bottomRight === undefined && i > i_ && j > j_) continue
174
- }
175
-
176
- if(nodataHandling === "zero") {
177
- // replace undefined values by zero
178
- fineGrid[i][j] = interp(topLeft || 0, topRight || 0, bottomLeft || 0, bottomRight || 0, xRatio, yRatio)
179
- continue
180
- }
181
-
182
- // general case: bilinear interpolation
183
- // If all four are defined, interpolate normally
184
- if (topLeft !== undefined && topRight !== undefined && bottomLeft !== undefined && bottomRight !== undefined) {
185
- fineGrid[i][j] = interp(topLeft, topRight, bottomLeft, bottomRight, xRatio, yRatio)
186
- continue
187
- }
188
-
189
- // If only one is not defined, use average value of 2 adjacents and interpolate
190
- if (topLeft === undefined && topRight !== undefined && bottomLeft !== undefined && bottomRight !== undefined) {
191
- const v = topRight + bottomLeft
192
- fineGrid[i][j] = interp(v / 2, topRight, bottomLeft, bottomRight, xRatio, yRatio)
193
- continue
194
- }
195
- if (topLeft !== undefined && topRight === undefined && bottomLeft !== undefined && bottomRight !== undefined) {
196
- const v = topLeft + bottomRight
197
- fineGrid[i][j] = interp(topLeft, v / 2, bottomLeft, bottomRight, xRatio, yRatio)
198
- continue
199
- }
200
- if (topLeft !== undefined && topRight !== undefined && bottomLeft === undefined && bottomRight !== undefined) {
201
- const v = topLeft + bottomRight
202
- fineGrid[i][j] = interp(topLeft, topRight, v / 2, bottomRight, xRatio, yRatio)
203
- continue
204
- }
205
- if (topLeft !== undefined && topRight !== undefined && bottomLeft !== undefined && bottomRight === undefined) {
206
- const v = topRight + bottomLeft
207
- fineGrid[i][j] = interp(topLeft, topRight, bottomLeft, v / 2, xRatio, yRatio)
208
- continue
209
- }
210
-
211
- // If only two diagonally opposite points are defined, interpolate along diagonal
212
- if (topLeft !== undefined && bottomRight !== undefined) {
213
- const t = (xRatio + yRatio) * Math.SQRT1_2
214
- fineGrid[i][j] = topLeft * (1 - t) + bottomRight * t;
215
- continue
216
- }
217
- if (topRight !== undefined && bottomLeft !== undefined) {
218
- const t = (1 - xRatio + yRatio) * Math.SQRT1_2
219
- fineGrid[i][j] = topRight * (1 - t) + bottomLeft * t;
220
- continue
221
- }
222
-
223
- // If only two adjacent points are defined, interpolate between them
224
- if (topLeft !== undefined && bottomLeft !== undefined) {
225
- fineGrid[i][j] = bottomLeft * yRatio + topLeft * (1 - yRatio);
226
- continue
227
- }
228
- if (topRight !== undefined && bottomRight !== undefined) {
229
- fineGrid[i][j] = bottomRight * yRatio + topRight * (1 - yRatio);
230
- continue
231
- }
232
- if (topLeft !== undefined && topRight !== undefined) {
233
- fineGrid[i][j] = topRight * xRatio + topLeft * (1 - xRatio);
234
- }
235
- if (bottomLeft !== undefined && bottomRight !== undefined) {
236
- fineGrid[i][j] = bottomRight * xRatio + bottomLeft * (1 - xRatio);
237
- continue
238
- }
239
-
240
- // If only one point is defined, use that value
241
- if (topLeft !== undefined) {
242
- fineGrid[i][j] = topLeft;
243
- continue
244
- }
245
- if (topRight !== undefined) {
246
- fineGrid[i][j] = topRight;
247
- continue
248
- }
249
- if (bottomLeft !== undefined) {
250
- fineGrid[i][j] = bottomLeft;
251
- continue
252
- }
253
- if (bottomRight !== undefined) {
254
- fineGrid[i][j] = bottomRight;
255
- }
256
- }
257
- }
258
- return fineGrid;
259
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Style } from '../core/Style.js'
5
+ import { isVisibleAt } from '../core/Drawable.js'
6
+ import { cellsToMatrix } from '../utils/utils.js'
7
+
8
+ /**
9
+ * A style which makes a finer grid from a grid, by bilinear interpolation of a value, and draws it with other styles.
10
+ * It does not draw anything by itself.
11
+ *
12
+ * @example
13
+ * const interpolator = new gridviz.Interpolator({ value: (c) => c.v, targetResolution: (r, z) => r / 5, interpolatedProperty: 'v' })
14
+ * interpolator.styles.push(someStyle)
15
+ *
16
+ * @module style
17
+ * @author Julien Gaffuri
18
+ */
19
+ export class Interpolator extends Style {
20
+ /** @param {object} opts The options of the style (see Style for the others: filter, visible...).
21
+ * @param {function(import('../core/Dataset.js').Cell):number} opts.value The value to interpolate.
22
+ * @param {function(number, number):number} [opts.targetResolution] (resolution, z) => the resolution of the interpolated cells. Make sure that resolution/targetResolution is an integer. Default: resolution / 5.
23
+ * @param {string} [opts.interpolatedProperty] The property of the interpolated cells which holds the interpolated value. Default: 'value'.
24
+ * @param {'zero'|'average'} [opts.nodataHandling] What to do with the neighbour cells without value. Default: 'zero'.
25
+ * @param {Array.<Style>} [opts.styles] The styles which draw the interpolated cells.
26
+ */
27
+ constructor(opts) {
28
+ super(opts)
29
+ opts = opts || {}
30
+
31
+ /** The cell value to interpolate
32
+ * @type { function } } */
33
+ this.value = opts.value //(c) => elevation
34
+
35
+ /** The target resolution. As a function (resolution, z) => targetResolution
36
+ * NB: Try to make sure that resolution/targetResolution is an integer.
37
+ * @type { function } } */
38
+ this.targetResolution = opts.targetResolution || ((r, z) => r / 5)
39
+
40
+ /** the property name to store the interpolated value in the cell
41
+ * @type { string } } */
42
+ this.interpolatedProperty = opts.interpolatedProperty || 'value'
43
+
44
+ // the interpolation method: currently only 'bilinear' is supported
45
+ //this.method = opts.method || 'bilinear' // 'nearest', 'bilinear'
46
+
47
+ /** when a neighbor cell has no value, take zero value or average of surrounding cells
48
+ * @type { string } } */
49
+ this.nodataHandling = opts.nodataHandling || "zero" // 'zero', 'average'
50
+
51
+ /** The styles to represent the interpolated grid.
52
+ * @type {Array.<Style>} */
53
+ this.styles = opts.styles || []
54
+ }
55
+
56
+
57
+ /**
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 cells
66
+ if (this.filter) cells = cells.filter(this.filter)
67
+ if (cells.length == 0) return;
68
+
69
+ //
70
+ const z = geoCanvas.view.z
71
+
72
+ //get view scale
73
+ //const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
74
+
75
+ //index cells by y and x
76
+ let m = cellsToMatrix(cells, resolution, c => this.value(c))
77
+ const x0 = m.x0, y0 = m.y0
78
+
79
+ //get target resolution and scale factor
80
+ let targetResolution = this.targetResolution(resolution, z)
81
+ const scaleFactor = Math.round(resolution / targetResolution)
82
+ targetResolution = resolution / scaleFactor
83
+
84
+ // compute ray casting shadow
85
+ m = bilinearInterpolator(m, scaleFactor, this.nodataHandling);
86
+
87
+ // make cells
88
+ cells = []
89
+ const ra = (resolution - targetResolution) / 2
90
+ for (let i = 0; i < m.length; i++) {
91
+ const row = m[i]
92
+ const y = y0 - i * targetResolution + ra
93
+ for (let j = 0; j < row.length; j++) {
94
+ const v = row[j]
95
+ if (!v) continue
96
+ const c = { x: x0 + j * targetResolution + ra, y: y }
97
+ c[this.interpolatedProperty] = v
98
+ cells.push(c)
99
+ }
100
+ }
101
+
102
+ //draw the interpolated cells with the styles
103
+ this.drawStyles(cells, geoCanvas, targetResolution)
104
+ }
105
+
106
+ /**
107
+ * Draws cells with the styles of the interpolator: the interpolated cells.
108
+ *
109
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
110
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
111
+ * @param {number} resolution The resolution of the cells
112
+ * @protected
113
+ */
114
+ drawStyles(cells, geoCanvas, resolution) {
115
+ const z = geoCanvas.view.z
116
+ const ctx = geoCanvas.offscreenCtx
117
+ for (let s of this.styles) {
118
+ //check if style is visible
119
+ if (!isVisibleAt(s, z)) continue
120
+
121
+ //set style alpha and blend mode
122
+ //TODO: multiply by layer alpha ?
123
+ if (s.alpha || s.blendOperation) {
124
+ ctx.save()
125
+ if (s.alpha) ctx.globalAlpha = s.alpha(z)
126
+ if (s.blendOperation) ctx.globalCompositeOperation = s.blendOperation(z)
127
+ }
128
+
129
+ //set affin transform to draw with geographical coordinates
130
+ geoCanvas.setCanvasTransform()
131
+
132
+ //draw with style
133
+ s.draw(cells, geoCanvas, resolution)
134
+
135
+ //draw style filter
136
+ if (s.filterColor) s.drawFilter(geoCanvas)
137
+
138
+ //restore ctx
139
+ if (s.alpha || s.blendOperation) ctx.restore()
140
+ }
141
+ }
142
+ }
143
+
144
+
145
+ const interp = (topLeft, topRight, bottomLeft, bottomRight, xRatio, yRatio) => {
146
+ const top = topLeft + (topRight - topLeft) * xRatio;
147
+ const bottom = bottomLeft + (bottomRight - bottomLeft) * xRatio;
148
+ return top + (bottom - top) * yRatio;
149
+ }
150
+
151
+
152
+ function bilinearInterpolator(grid, scaleFactor = 5, nodataHandling = "zero") {
153
+
154
+ if (scaleFactor === 1) return grid;
155
+
156
+ // input grid dimensions
157
+ const rows = grid.length;
158
+ if (rows === 0) return [];
159
+ const cols = grid[0].length;
160
+
161
+ // output grid dimensions
162
+ const fineRows = rows * scaleFactor;
163
+ const fineCols = cols * scaleFactor;
164
+ const fineGrid = Array(fineRows).fill().map(() => Array(fineCols).fill(undefined));
165
+
166
+ // check if scale factor is even
167
+ const sfIsEven = scaleFactor % 2 === 0
168
+
169
+ //compute output grid values
170
+ for (let i = 0; i < fineRows; i++) {
171
+
172
+ const coarseI = Math.min(Math.floor(i / scaleFactor), rows - 2);
173
+ const yRatio = (i % scaleFactor) / scaleFactor;
174
+ const i_ = coarseI * scaleFactor + (scaleFactor / 2)
175
+
176
+ for (let j = 0; j < fineCols; j++) {
177
+ const coarseJ = Math.min(Math.floor(j / scaleFactor), cols - 2);
178
+ const xRatio = (j % scaleFactor) / scaleFactor;
179
+ const j_ = coarseJ * scaleFactor + (scaleFactor / 2)
180
+
181
+ // get four corner values
182
+ const topLeft = grid[coarseI][coarseJ];
183
+ const topRight = grid[coarseI][coarseJ + 1];
184
+ const bottomLeft = grid[coarseI + 1][coarseJ];
185
+ const bottomRight = grid[coarseI + 1][coarseJ + 1];
186
+
187
+
188
+ if (sfIsEven) {
189
+ if (topLeft === undefined && i <= i_ && j <= j_) continue
190
+ if (topRight === undefined && i <= i_ && j >= j_) continue
191
+ if (bottomLeft === undefined && i >= i_ && j <= j_) continue
192
+ if (bottomRight === undefined && i >= i_ && j >= j_) continue
193
+ } else {
194
+ if (topLeft === undefined && i < i_ && j < j_) continue
195
+ if (topRight === undefined && i < i_ && j > j_) continue
196
+ if (bottomLeft === undefined && i > i_ && j < j_) continue
197
+ if (bottomRight === undefined && i > i_ && j > j_) continue
198
+ }
199
+
200
+ if(nodataHandling === "zero") {
201
+ // replace undefined values by zero
202
+ fineGrid[i][j] = interp(topLeft || 0, topRight || 0, bottomLeft || 0, bottomRight || 0, xRatio, yRatio)
203
+ continue
204
+ }
205
+
206
+ // general case: bilinear interpolation
207
+ // If all four are defined, interpolate normally
208
+ if (topLeft !== undefined && topRight !== undefined && bottomLeft !== undefined && bottomRight !== undefined) {
209
+ fineGrid[i][j] = interp(topLeft, topRight, bottomLeft, bottomRight, xRatio, yRatio)
210
+ continue
211
+ }
212
+
213
+ // If only one is not defined, use average value of 2 adjacents and interpolate
214
+ if (topLeft === undefined && topRight !== undefined && bottomLeft !== undefined && bottomRight !== undefined) {
215
+ const v = topRight + bottomLeft
216
+ fineGrid[i][j] = interp(v / 2, topRight, bottomLeft, bottomRight, xRatio, yRatio)
217
+ continue
218
+ }
219
+ if (topLeft !== undefined && topRight === undefined && bottomLeft !== undefined && bottomRight !== undefined) {
220
+ const v = topLeft + bottomRight
221
+ fineGrid[i][j] = interp(topLeft, v / 2, bottomLeft, bottomRight, xRatio, yRatio)
222
+ continue
223
+ }
224
+ if (topLeft !== undefined && topRight !== undefined && bottomLeft === undefined && bottomRight !== undefined) {
225
+ const v = topLeft + bottomRight
226
+ fineGrid[i][j] = interp(topLeft, topRight, v / 2, bottomRight, xRatio, yRatio)
227
+ continue
228
+ }
229
+ if (topLeft !== undefined && topRight !== undefined && bottomLeft !== undefined && bottomRight === undefined) {
230
+ const v = topRight + bottomLeft
231
+ fineGrid[i][j] = interp(topLeft, topRight, bottomLeft, v / 2, xRatio, yRatio)
232
+ continue
233
+ }
234
+
235
+ // If only two diagonally opposite points are defined, interpolate along diagonal
236
+ if (topLeft !== undefined && bottomRight !== undefined) {
237
+ const t = (xRatio + yRatio) * Math.SQRT1_2
238
+ fineGrid[i][j] = topLeft * (1 - t) + bottomRight * t;
239
+ continue
240
+ }
241
+ if (topRight !== undefined && bottomLeft !== undefined) {
242
+ const t = (1 - xRatio + yRatio) * Math.SQRT1_2
243
+ fineGrid[i][j] = topRight * (1 - t) + bottomLeft * t;
244
+ continue
245
+ }
246
+
247
+ // If only two adjacent points are defined, interpolate between them
248
+ if (topLeft !== undefined && bottomLeft !== undefined) {
249
+ fineGrid[i][j] = bottomLeft * yRatio + topLeft * (1 - yRatio);
250
+ continue
251
+ }
252
+ if (topRight !== undefined && bottomRight !== undefined) {
253
+ fineGrid[i][j] = bottomRight * yRatio + topRight * (1 - yRatio);
254
+ continue
255
+ }
256
+ if (topLeft !== undefined && topRight !== undefined) {
257
+ fineGrid[i][j] = topRight * xRatio + topLeft * (1 - xRatio);
258
+ }
259
+ if (bottomLeft !== undefined && bottomRight !== undefined) {
260
+ fineGrid[i][j] = bottomRight * xRatio + bottomLeft * (1 - xRatio);
261
+ continue
262
+ }
263
+
264
+ // If only one point is defined, use that value
265
+ if (topLeft !== undefined) {
266
+ fineGrid[i][j] = topLeft;
267
+ continue
268
+ }
269
+ if (topRight !== undefined) {
270
+ fineGrid[i][j] = topRight;
271
+ continue
272
+ }
273
+ if (bottomLeft !== undefined) {
274
+ fineGrid[i][j] = bottomLeft;
275
+ continue
276
+ }
277
+ if (bottomRight !== undefined) {
278
+ fineGrid[i][j] = bottomRight;
279
+ }
280
+ }
281
+ }
282
+ return fineGrid;
283
+ }
@@ -201,7 +201,7 @@ export class IsoFenceStyle extends Style {
201
201
  }
202
202
 
203
203
  //update legends
204
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
204
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale, cells: cells })
205
205
  }
206
206
  }
207
207
 
@@ -34,8 +34,9 @@ export class LegoStyle {
34
34
  //"#eee" //whithe
35
35
  ]*/
36
36
 
37
- opts.colorDark = opts.colorDark || '#333'
38
- opts.colorBright = opts.colorBright || '#aaa'
37
+ //the dark and bright colors of the bricks: the sides and the top. colorDark and colorBright are the former names of colDark and colBright.
38
+ const colDark = opts.colDark || opts.colorDark || '#333'
39
+ const colBright = opts.colBright || opts.colorBright || '#aaa'
39
40
 
40
41
  //make classifier
41
42
  const classifier = clFun(breaks)
@@ -53,8 +54,8 @@ export class LegoStyle {
53
54
  //make tanaka side style
54
55
  const tanakaStyle = new SideTanakaStyle({
55
56
  classifier: () => classifier2,
56
- colorDark : opts.colorDark,
57
- colorBright : opts.colorBright,
57
+ colorDark: colDark,
58
+ colorBright: colBright,
58
59
  diamond: opts.diamond,
59
60
  })
60
61
 
@@ -69,7 +70,7 @@ export class LegoStyle {
69
70
  cellStyle,
70
71
  sst,
71
72
  tanakaStyle,
72
- new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright, filter: opts.filter }),
73
+ new LegoTopStyle({ colDark: colDark, colBright: colBright, filter: opts.filter }),
73
74
  ]
74
75
  }
75
76
 
@@ -94,6 +94,6 @@ export class MosaicStyle extends Style {
94
94
  }
95
95
 
96
96
  //update legends
97
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
97
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale, cells: cells })
98
98
  }
99
99
  }
@@ -97,6 +97,6 @@ export class NinjaStarStyle extends Style {
97
97
  }
98
98
 
99
99
  //update legends
100
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
100
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale, cells: cells })
101
101
  }
102
102
  }
@@ -202,6 +202,6 @@ export class PillarStyle extends Style {
202
202
  ctx.lineCap = 'butt'
203
203
 
204
204
  //update legends
205
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
205
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale, cells: cells })
206
206
  }
207
207
  }