gridviz 2.1.16 → 3.0.0

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 +2 -3
  2. package/dist/gridviz.js +4971 -5654
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +3 -2
  5. package/src/button/Button.js +14 -15
  6. package/src/button/FullscreenButton.js +14 -14
  7. package/src/button/ZoomButtons.js +2 -2
  8. package/src/{DatasetComponent.js → core/Dataset.js} +33 -12
  9. package/src/core/Drawable.js +60 -0
  10. package/src/{GeoCanvas.js → core/GeoCanvas.js} +65 -155
  11. package/src/core/Layer.js +24 -0
  12. package/src/{Legend.js → core/Legend.js} +24 -1
  13. package/src/core/Map.js +460 -0
  14. package/src/core/MultiResolutionDataset.js +96 -0
  15. package/src/core/Style.js +84 -0
  16. package/src/dataset/COGeo.js +5 -5
  17. package/src/dataset/CSVGrid.js +43 -41
  18. package/src/dataset/GeoTIFF.js +9 -14
  19. package/src/dataset/{LGrid.js → JSGrid.js} +9 -10
  20. package/src/dataset/TiledGrid.js +68 -45
  21. package/src/index.js +22 -29
  22. package/src/{BackgroundLayer.js → layer/BackgroundLayer.js} +27 -52
  23. package/src/{BackgroundLayerWMS.js → layer/BackgroundLayerWMS.js} +21 -45
  24. package/src/{LineLayer.js → layer/GeoJSONLayer.js} +22 -23
  25. package/src/layer/GridLayer.js +140 -0
  26. package/src/{LabelLayer.js → layer/LabelLayer.js} +25 -23
  27. package/src/legend/ColorCategoryLegend.js +9 -24
  28. package/src/legend/ColorDiscreteLegend.js +20 -24
  29. package/src/legend/ColorLegend.js +21 -33
  30. package/src/legend/OrientationLegend.js +90 -0
  31. package/src/legend/SizeLegend.js +153 -72
  32. package/src/style/CompositionStyle.js +71 -84
  33. package/src/style/ContourStyle.js +2 -36
  34. package/src/style/DotDensityStyle.js +50 -73
  35. package/src/style/IsoFenceStyle.js +59 -70
  36. package/src/style/JoyPlotStyle.js +41 -48
  37. package/src/style/LegoStyle.js +4 -4
  38. package/src/style/MosaicStyle.js +30 -39
  39. package/src/style/NinjaStarStyle.js +45 -68
  40. package/src/style/PillarStyle.js +70 -93
  41. package/src/style/SegmentStyle.js +37 -75
  42. package/src/style/ShapeColorSizeStyle.js +49 -98
  43. package/src/style/SideCategoryStyle.js +112 -0
  44. package/src/style/SideStyle.js +99 -133
  45. package/src/style/{SquareColorCatWGLStyle.js → SquareColorCategoryWebGLStyle.js} +28 -41
  46. package/src/style/{SquareColorWGLStyle.js → SquareColorWebGLStyle.js} +28 -49
  47. package/src/style/StrokeStyle.js +43 -70
  48. package/src/style/TanakaStyle.js +34 -132
  49. package/src/style/TextStyle.js +43 -64
  50. package/src/style/TimeSeriesStyle.js +44 -75
  51. package/src/utils/WebGLSquareColoringAdvanced.js +4 -4
  52. package/src/utils/scale.js +202 -0
  53. package/src/utils/stretching.js +86 -129
  54. package/src/utils/{Utils.js → utils.js} +15 -0
  55. package/src/utils/webGLUtils.js +4 -5
  56. package/src/utils/zoomUtils.js +30 -30
  57. package/src/App.js +0 -760
  58. package/src/Dataset.js +0 -76
  59. package/src/Layer.js +0 -103
  60. package/src/Style.js +0 -131
  61. package/src/dataset/GridTile.js +0 -41
  62. package/src/legend/SegmentOrientationLegend.js +0 -87
  63. package/src/legend/SegmentWidthLegend.js +0 -101
  64. package/src/style/CompositionStyle_.js +0 -293
  65. package/src/style/ShapeColorSizeStyle_.js +0 -108
  66. package/src/style/SideCatStyle.js +0 -172
  67. /package/src/{Tooltip.js → core/Tooltip.js} +0 -0
@@ -1,9 +1,12 @@
1
1
  //@ts-check
2
2
  'use strict'
3
3
 
4
- import { Style } from '../Style.js'
4
+ import { Style } from '../core/Style.js'
5
5
 
6
- /** @typedef {{x:number,y:number,or:"v"|"h",value:number}} Side */
6
+ /** @typedef {{ x:number, y:number, or:"v"|"h", c1:(import('../core/Dataset').Cell)|undefined, c2:(import('../core/Dataset').Cell)|undefined }} Side */
7
+
8
+ /**
9
+ * @typedef {function(Array.<Side>,number, number):*} SideViewScale */
7
10
 
8
11
  /**
9
12
  *
@@ -11,59 +14,103 @@ import { Style } from '../Style.js'
11
14
  */
12
15
  export class SideStyle extends Style {
13
16
  /** @param {object} opts */
14
- constructor(opts) {
17
+ constructor(opts = {}) {
15
18
  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
19
 
28
20
  /** 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')
21
+ * @type {function(Side, number, number, object):string} */
22
+ this.color = opts.color || ((side, resolution, z, sideViewScale) => '#EA6BAC')
31
23
 
32
24
  /** 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
25
+ * @type {function(Side, number, number, object):number} */
26
+ this.width = opts.width || ((side, resolution, z, sideViewScale) => resolution / 5)
39
27
 
40
- /** A fill color for the cells.
41
- * @type {function(import("../Dataset").Cell):string} */
42
- this.fillColor = opts.fillColor
28
+ /** A function returning the length of a cell side, in geo unit
29
+ * @type {function(Side, number, number, object):number} */
30
+ this.length = opts.length || ((side, resolution, z, sideViewScale) => resolution)
43
31
  }
44
32
 
45
33
  /**
46
- * @param {Array.<import("../Dataset").Cell>} cells
47
- * @param {number} r
48
- * @param {import("../GeoCanvas").GeoCanvas} cg
34
+ * @param {Array.<import("../core/Dataset").Cell>} cells
35
+ * @param {number} resolution
36
+ * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas
49
37
  */
50
- draw(cells, r, cg) {
38
+ draw(cells, geoCanvas, resolution) {
39
+
51
40
  //filter
52
41
  if (this.filter) cells = cells.filter(this.filter)
53
42
 
54
- //zoom factor
55
- const zf = cg.getZf()
43
+ //
44
+ const z = geoCanvas.view.z
56
45
 
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
- }
46
+ //build sides
63
47
 
64
48
  /** @type {Array.<Side>} */
49
+ const sides = SideStyle.buildSides(cells, resolution)
50
+ if (sides.length == 0) return
51
+
52
+ //get side view scale
53
+ const viewScale = this.viewScale ? this.viewScale(sides, resolution, z) : undefined
54
+
55
+ //draw sides
56
+
57
+ geoCanvas.ctx.lineCap = 'butt'
58
+ const r2 = resolution * 0.5
59
+ for (let side of sides) {
60
+
61
+ //color
62
+ /** @type {string|undefined} */
63
+ const col = this.color ? this.color(side, resolution, z, viewScale) : undefined
64
+ if (!col || col == 'none') continue
65
+
66
+ //width
67
+ /** @type {number|undefined} */
68
+ const wG = this.width ? this.width(side, resolution, z, viewScale) : undefined
69
+ if (!wG || wG <= 0) continue
70
+
71
+ //length
72
+ /** @type {number|undefined} */
73
+ const lG = this.length ? this.length(side, resolution, z, viewScale) : undefined
74
+ if (!lG || lG <= 0) continue
75
+ const lG2 = lG * 0.5
76
+
77
+ //set color and width
78
+ geoCanvas.ctx.strokeStyle = col
79
+ geoCanvas.ctx.lineWidth = wG
80
+
81
+ //draw segment with correct orientation
82
+ geoCanvas.ctx.beginPath()
83
+ if (side.or === "v") {
84
+ geoCanvas.ctx.moveTo(side.x, side.y + r2 - lG2)
85
+ geoCanvas.ctx.lineTo(side.x, side.y + r2 + lG2)
86
+ } else {
87
+ geoCanvas.ctx.moveTo(side.x + r2 - lG2, side.y)
88
+ geoCanvas.ctx.lineTo(side.x + r2 + lG2, side.y)
89
+ }
90
+ geoCanvas.ctx.stroke()
91
+ }
92
+
93
+ //update legends
94
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
95
+ }
96
+
97
+
98
+
99
+ /**
100
+ *
101
+ * @param {Array.<import('../core/Dataset').Cell>} cells The cells to use to build the sides. The side x,y coordinates are those of the left point for horizontal sides, and of the bottom point for vertical sides.
102
+ * @param {number} resolution The cells resolution
103
+ * @param {boolean} withHorizontal Set to true to build horizontal sides, false otherwise.
104
+ * @param {boolean} withVertical Set to true to build vertical sides, false otherwise.
105
+ * @param {boolean} center Set to true so that the side coordinate are those of its center point rather than its left/bottom point.
106
+ * @returns { Array.<Side> }
107
+ */
108
+ static buildSides(cells, resolution, withHorizontal = true, withVertical = true, center = false) {
109
+ /** @type { Array.<Side> } */
65
110
  const sides = []
66
111
 
112
+ const r2 = center ? resolution / 2 : 0
113
+
67
114
  //make horizontal sides
68
115
  //sort cells by x and y
69
116
  cells.sort((c1, c2) => (c2.x == c1.x ? c1.y - c2.y : c1.x - c2.x))
@@ -71,29 +118,26 @@ export class SideStyle extends Style {
71
118
  for (let i = 1; i < cells.length; i++) {
72
119
  let c2 = cells[i]
73
120
 
74
- if ((c1.y + r == c2.y) && (c1.x == c2.x))
121
+ if ((c1.y + resolution == c2.y) && (c1.x == c2.x))
75
122
  //cells in same column and touch along horizontal side
76
123
  //make shared side
77
124
  sides.push({
78
- x: c1.x,
79
- y: c2.y,
80
125
  or: 'h',
81
- value: this.value(c1[this.valueCol], c2[this.valueCol], r, statValue, zf),
126
+ x: c1.x + r2, y: c2.y,
127
+ c1: c1, c2: c2
82
128
  })
83
129
  else {
84
130
  //cells do not touch along horizontal side
85
131
  //make two sides: top one for c1, bottom for c2
86
132
  sides.push({
87
- x: c1.x,
88
- y: c1.y + r,
89
133
  or: 'h',
90
- value: this.value(c1[this.valueCol], undefined, r, statValue, zf),
134
+ x: c1.x + r2, y: c1.y + resolution,
135
+ c1: c1, c2: undefined
91
136
  })
92
137
  sides.push({
93
- x: c2.x,
94
- y: c2.y,
95
138
  or: 'h',
96
- value: this.value(undefined, c2[this.valueCol], r, statValue, zf),
139
+ x: c2.x + r2, y: c2.y,
140
+ c1: undefined, c2: c2
97
141
  })
98
142
  }
99
143
 
@@ -107,110 +151,32 @@ export class SideStyle extends Style {
107
151
  for (let i = 1; i < cells.length; i++) {
108
152
  let c2 = cells[i]
109
153
 
110
- if ((c1.x + r == c2.x) && (c1.y == c2.y))
154
+ if ((c1.x + resolution == c2.x) && (c1.y == c2.y))
111
155
  //cells in same row and touch along vertical side
112
156
  //make shared side
113
157
  sides.push({
114
- x: c1.x + r,
115
- y: c1.y,
116
158
  or: 'v',
117
- value: this.value(c1[this.valueCol], c2[this.valueCol], r, statValue, zf),
159
+ x: c1.x + resolution, y: c1.y + r2,
160
+ c1: c1, c2: c2
118
161
  })
119
162
  else {
120
163
  //cells do not touch along vertical side
121
164
  //make two sides: right one for c1, left for c2
122
165
  sides.push({
123
- x: c1.x + r,
124
- y: c1.y,
125
166
  or: 'v',
126
- value: this.value(c1[this.valueCol], undefined, r, statValue, zf),
167
+ x: c1.x + resolution, y: c1.y + r2,
168
+ c1: c1, c2: undefined
127
169
  })
128
170
  sides.push({
129
- x: c2.x,
130
- y: c2.y,
131
171
  or: 'v',
132
- value: this.value(undefined, c2[this.valueCol], r, statValue, zf),
172
+ x: c2.x, y: c2.y + r2,
173
+ c1: undefined, c2: c2
133
174
  })
134
175
  }
135
176
 
136
177
  c1 = c2
137
178
  }
138
-
139
- //
140
- if (sides.length == 0) return
141
-
142
- //compute stats on sides
143
- const statSides = SideStyle.getSideStatistics(sides, true)
144
-
145
- //draw in geo coordinates
146
- cg.setCanvasTransform()
147
-
148
- //draw cells, if fillColor specified
149
- if (this.fillColor)
150
- for (let c of cells) {
151
- const fc = this.fillColor(c)
152
- if (!fc || fc == 'none') continue
153
- cg.ctx.fillStyle = fc
154
- cg.ctx.fillRect(c.x, c.y, r, r)
155
- }
156
-
157
- //draw sides
158
- cg.ctx.lineCap = 'butt'
159
- const r2 = r / 2
160
- for (let s of sides) {
161
- //color
162
- /** @type {string|undefined} */
163
- const col = this.color ? this.color(s, r, statSides, zf) : undefined
164
- if (!col || col == 'none') continue
165
-
166
- //width
167
- /** @type {number|undefined} */
168
- const wG = this.width ? this.width(s, r, statSides, zf) : undefined
169
- if (!wG || wG <= 0) continue
170
-
171
- //set color and width
172
- cg.ctx.strokeStyle = col
173
- cg.ctx.lineWidth = wG
174
-
175
- //draw segment with correct orientation
176
- cg.ctx.beginPath()
177
- if (this.orientation == 90) {
178
- cg.ctx.moveTo(s.x + r2, s.y + r2)
179
- if (s.or === 'h') cg.ctx.lineTo(s.x + r2, s.y - r2)
180
- else cg.ctx.lineTo(s.x - r2, s.y + r2)
181
- } else {
182
- cg.ctx.moveTo(s.x, s.y)
183
- cg.ctx.lineTo(s.x + (s.or === 'h' ? r : 0), s.y + (s.or === 'v' ? r : 0))
184
- }
185
- cg.ctx.stroke()
186
- }
187
-
188
- //update legends
189
- this.updateLegends({ style: this, r: r, zf: zf })
179
+ return sides
190
180
  }
191
181
 
192
- /**
193
- * Compute some statistics on a value of some sides.
194
- * This is used to define how to draw specifically the sides within the view.
195
- *
196
- * @param {Array.<Side>} sides
197
- * @param {boolean} ignoreZeros
198
- * @returns {import("../Style").Stat | undefined}
199
- */
200
- static getSideStatistics(sides, ignoreZeros) {
201
- if (!sides || sides.length == 0) return undefined
202
- let min = Infinity
203
- let max = -Infinity
204
- //let sum = 0
205
- //let nb = 0
206
- for (const s of sides) {
207
- const v = s.value
208
- if (ignoreZeros && !v) continue
209
- if (v < min) min = v
210
- if (v > max) max = v
211
- //sum += v
212
- //nb++
213
- }
214
- return { min: min, max: max }
215
- }
216
182
  }
@@ -1,51 +1,49 @@
1
1
  //@ts-check
2
2
  'use strict'
3
3
 
4
- import { Style } from '../Style.js'
4
+ import { Style } from '../core/Style.js'
5
5
  import { makeWebGLCanvas } from '../utils/webGLUtils.js'
6
6
  import { WebGLSquareColoringCatAdvanced } from '../utils/WebGLSquareColoringCatAdvanced.js'
7
- import { monitor, monitorDuration } from '../utils/Utils.js'
8
7
 
9
8
  /**
10
9
  * Style based on webGL
11
10
  * To show cells as colored squares, from categories.
12
- * Alls squares with the same size
11
+ * All cells are drawn as squares, with the same size
13
12
  *
14
13
  * @author Julien Gaffuri
15
14
  */
16
- export class SquareColorCatWGLStyle extends Style {
15
+ export class SquareColorCategoryWebGLStyle extends Style {
17
16
  /** @param {object} opts */
18
17
  constructor(opts) {
19
18
  super(opts)
20
19
  opts = opts || {}
21
20
 
22
21
  /**
23
- * The name of the column/attribute of the tabular data where to retrieve the category of the cell, for coloring.
22
+ * The name of the column/attribute of the tabular data where to retrieve the category code of the cell, for coloring.
24
23
  * @type {string} */
25
- this.colorCol = opts.colorCol
24
+ this.code = opts.code
26
25
 
27
26
  /**
28
- * The dictionary (string -> color) which give the color of each category.
27
+ * The dictionary (code -> color) which gives the color of each category code.
29
28
  * @type {object} */
30
29
  opts.color = opts.color || undefined
31
30
 
32
- /** @type { Array.<string> } @private */
33
- const keys = Object.keys(opts.color)
31
+ /** @type { Array.<string> } */
32
+ const codes = Object.keys(opts.color)
34
33
 
35
34
  /** @type { object } @private */
36
35
  this.catToI = {}
37
- for (let i = 0; i < keys.length; i++) this.catToI[keys[i]] = i + ''
36
+ for (let i = 0; i < codes.length; i++) this.catToI[codes[i]] = i + ''
38
37
 
39
38
  /** @type { Array.<string> } @private */
40
39
  this.colors = []
41
- for (let i = 0; i < keys.length; i++) {
42
- this.colors.push(opts.color['' + keys[i]])
43
- }
40
+ for (const code of codes)
41
+ this.colors.push(opts.color['' + code])
44
42
 
45
43
  /**
46
44
  * A function returning the size of the cells, in geographical unit. All cells have the same size.
47
45
  * @type {function(number,number):number} */
48
- this.size = opts.size // (resolution, zf) => ...
46
+ this.size = opts.size // (resolution, z) => ...
49
47
 
50
48
  /**
51
49
  * @private
@@ -54,28 +52,26 @@ export class SquareColorCatWGLStyle extends Style {
54
52
  }
55
53
 
56
54
  /**
57
- * @param {Array.<import("../Dataset").Cell>} cells
58
- * @param {number} r
59
- * @param {import("../GeoCanvas").GeoCanvas} cg
55
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
56
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
57
+ * @param {number} resolution
60
58
  */
61
- draw(cells, r, cg) {
62
- if (monitor) monitorDuration('*** SquareColorCatWGLStyle draw')
59
+ draw(cells, geoCanvas, resolution) {
63
60
 
64
61
  //filter
65
62
  if (this.filter) cells = cells.filter(this.filter)
66
63
 
67
- //zoom factor
68
- const zf = cg.getZf()
64
+ //
65
+ const z = geoCanvas.view.z
69
66
 
70
67
  //add vertice and fragment data
71
- const r2 = r / 2
72
- let c,
73
- nb = cells.length
68
+ const r2 = resolution / 2
69
+ let c, nb = cells.length
74
70
  const verticesBuffer = []
75
71
  const iBuffer = []
76
72
  for (let i = 0; i < nb; i++) {
77
73
  c = cells[i]
78
- const cat = c[this.colorCol]
74
+ const cat = c[this.code]
79
75
  if (cat == undefined) {
80
76
  console.log('Unexpected category: ' + cat)
81
77
  continue
@@ -90,31 +86,22 @@ export class SquareColorCatWGLStyle extends Style {
90
86
  iBuffer.push(+i_)
91
87
  }
92
88
 
93
- if (monitor) monitorDuration(' webgl program inputs preparation')
94
-
95
89
  //create canvas and webgl renderer
96
- const cvWGL = makeWebGLCanvas(cg.w + '', cg.h + '')
90
+ const cvWGL = makeWebGLCanvas(geoCanvas.w + '', geoCanvas.h + '')
97
91
  if (!cvWGL) {
98
92
  console.error('No webGL')
99
93
  return
100
94
  }
101
- if (monitor) monitorDuration(' web GL canvas creation')
102
95
 
103
96
  //draw
104
- const sizeGeo = this.size ? this.size(r, zf) : r + 0.2 * zf
105
- this.wgp.draw(cvWGL.gl, verticesBuffer, iBuffer, cg.getWebGLTransform(), sizeGeo / zf)
106
-
107
- if (monitor) monitorDuration(' webgl drawing')
97
+ const sizeGeo = this.size ? this.size(resolution, z) : resolution + 0.2 * z
98
+ this.wgp.draw(cvWGL.gl, verticesBuffer, iBuffer, geoCanvas.getWebGLTransform(), sizeGeo / z)
108
99
 
109
100
  //draw in canvas geo
110
- cg.initCanvasTransform()
111
- cg.ctx.drawImage(cvWGL.canvas, 0, 0)
112
-
113
- if (monitor) monitorDuration(' canvas drawing')
101
+ geoCanvas.initCanvasTransform()
102
+ geoCanvas.ctx.drawImage(cvWGL.canvas, 0, 0)
114
103
 
115
104
  //update legends
116
- this.updateLegends({ style: this, r: r, zf: zf })
117
-
118
- if (monitor) monitorDuration('*** SquareColorCatWGLStyle end draw')
105
+ this.updateLegends({ style: this, resolution: resolution, z: z })
119
106
  }
120
- }
107
+ }
@@ -1,10 +1,9 @@
1
1
  //@ts-check
2
2
  'use strict'
3
3
 
4
- import { Style } from '../Style.js'
4
+ import { Style } from '../core/Style.js'
5
5
  import { makeWebGLCanvas } from '../utils/webGLUtils.js'
6
6
  import { WebGLSquareColoringAdvanced } from '../utils/WebGLSquareColoringAdvanced.js'
7
- import { monitor, monitorDuration } from '../utils/Utils.js'
8
7
 
9
8
  /**
10
9
  * Style based on webGL
@@ -13,21 +12,16 @@ import { monitor, monitorDuration } from '../utils/Utils.js'
13
12
  *
14
13
  * @author Julien Gaffuri
15
14
  */
16
- export class SquareColorWGLStyle extends Style {
15
+ export class SquareColorWebGLStyle extends Style {
17
16
  /** @param {object} opts */
18
17
  constructor(opts) {
19
18
  super(opts)
20
19
  opts = opts || {}
21
20
 
22
21
  /**
23
- * The name of the column/attribute of the tabular data where to retrieve the variable for color.
24
- * @type {string} */
25
- this.colorCol = opts.colorCol
26
-
27
- /**
28
- * A function returning the t value (within [0,1]) of the cell.
29
- * @type {function(number,number,import("../Style").Stat):number} */
30
- this.tFun = opts.tFun || ((v, r, s) => v / s.max)
22
+ * A function returning a t value (within [0,1]) for a cell.
23
+ * @type {function(import('../core/Dataset.js').Cell,number,number,object):number} */
24
+ this.tFun = opts.tFun //(c,r,z,vs) => {}
31
25
 
32
26
  /**
33
27
  * Distribution stretching method.
@@ -62,85 +56,70 @@ export class SquareColorWGLStyle extends Style {
62
56
  * Define the opacity of the style, within [0,1].
63
57
  * If this opacity is defined, the individual color opacity will be ignored.
64
58
  * @type {function(number,number):number} */
65
- this.opacity = opts.opacity // (r,zf) => ...
59
+ this.opacity = opts.opacity // (r,z) => ...
66
60
 
67
61
  /**
68
62
  * A function returning the size of the cells, in geographical unit. All cells have the same size.
69
63
  * @type {function(number,number):number} */
70
- this.size = opts.size // (resolution, zf) => ...
64
+ this.size = opts.size // (resolution, z) => ...
71
65
  }
72
66
 
73
67
  /**
74
- * @param {Array.<import("../Dataset").Cell>} cells
75
- * @param {number} r
76
- * @param {import("../GeoCanvas").GeoCanvas} cg
68
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
69
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
70
+ * @param {number} resolution
77
71
  */
78
- draw(cells, r, cg) {
79
- if (monitor) monitorDuration('*** SquareColorWGLStyle draw')
72
+ draw(cells, geoCanvas, resolution) {
80
73
 
81
74
  //filter
82
75
  if (this.filter) cells = cells.filter(this.filter)
83
76
 
84
- //zoom factor
85
- const zf = cg.getZf()
86
-
87
- //compute color variable statistics
88
- const statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
89
- if (monitor) monitorDuration(' color stats computation')
77
+ //
78
+ const z = geoCanvas.view.z
90
79
 
91
- if (!statColor) return
80
+ //get view scale
81
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
92
82
 
93
83
  //create canvas and webgl renderer
94
84
  //for opacity control, see: https://webglfundamentals.org/webgl/lessons/webgl-and-alpha.html
95
85
  const cvWGL = makeWebGLCanvas(
96
- cg.w + '',
97
- cg.h + '',
86
+ geoCanvas.w + '',
87
+ geoCanvas.h + '',
98
88
  this.opacity != undefined ? { premultipliedAlpha: false } : undefined
99
89
  )
100
90
  if (!cvWGL) {
101
91
  console.error('No webGL')
102
92
  return
103
93
  }
104
- if (monitor) monitorDuration(' web GL canvas creation')
105
94
 
106
95
  //add vertice and fragment data
107
- const r2 = r / 2
96
+ const r2 = resolution / 2
108
97
  const verticesBuffer = []
109
98
  const tBuffer = []
110
- for (let c of cells) {
111
- const t = this.tFun(c[this.colorCol], r, statColor)
99
+ for (let cell of cells) {
100
+ const t = this.tFun(cell, resolution, z, viewScale)
112
101
  if (t == null || t == undefined) continue
113
- verticesBuffer.push(c.x + r2, c.y + r2)
102
+ verticesBuffer.push(cell.x + r2, cell.y + r2)
114
103
  tBuffer.push(t > 1 ? 1 : t < 0 ? 0 : t)
115
104
  }
116
105
 
117
- if (monitor) monitorDuration(' webgl drawing data preparation')
118
-
119
106
  //compute pixel size
120
- const sizeGeo = this.size ? this.size(r, zf) : r + 0.2 * zf
107
+ const sizeGeo = this.size ? this.size(resolution, z) : resolution + 0.2 * z
121
108
 
122
109
  //compute opacity
123
- const op = this.opacity ? this.opacity(r, zf) : undefined
110
+ const op = this.opacity ? this.opacity(resolution, z) : undefined
124
111
 
125
112
  //
126
- const wgp = new WebGLSquareColoringAdvanced(cvWGL.gl, this.colors, this.stretching, sizeGeo / zf, op)
127
-
128
- if (monitor) monitorDuration(' webgl program preparation')
113
+ const wgp = new WebGLSquareColoringAdvanced(cvWGL.gl, this.colors, this.stretching, sizeGeo / z, op)
129
114
 
130
115
  //draw
131
- wgp.draw(verticesBuffer, tBuffer, cg.getWebGLTransform())
132
-
133
- if (monitor) monitorDuration(' webgl drawing')
116
+ wgp.draw(verticesBuffer, tBuffer, geoCanvas.getWebGLTransform())
134
117
 
135
118
  //draw in canvas geo
136
- cg.initCanvasTransform()
137
- cg.ctx.drawImage(cvWGL.canvas, 0, 0)
138
-
139
- if (monitor) monitorDuration(' canvas drawing')
119
+ geoCanvas.initCanvasTransform()
120
+ geoCanvas.ctx.drawImage(cvWGL.canvas, 0, 0)
140
121
 
141
122
  //update legends
142
- this.updateLegends({ style: this, r: r, zf: zf, sColor: statColor })
143
-
144
- if (monitor) monitorDuration('*** SquareColorWGLStyle end draw')
123
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
145
124
  }
146
125
  }