gridviz 2.1.17 → 3.0.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 (67) hide show
  1. package/README.md +2 -3
  2. package/dist/gridviz.js +8659 -9294
  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 -13
  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 +474 -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 -11
  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 +160 -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 +217 -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,12 +1,11 @@
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 { randomNormal } from 'd3-random'
6
6
  import { checkWebGLSupport, makeWebGLCanvas } from '../utils/webGLUtils.js'
7
7
  import { WebGLSquareColoring } from '../utils/WebGLSquareColoring.js'
8
8
  import { color } from 'd3-color'
9
- import { monitor, monitorDuration } from '../utils/Utils.js'
10
9
 
11
10
  /**
12
11
  *
@@ -18,139 +17,117 @@ export class DotDensityStyle extends Style {
18
17
  super(opts)
19
18
  opts = opts || {}
20
19
 
21
- /** The name of the column/attribute of the tabular data where to retrieve the variable for dot number.
22
- * @type {string} */
23
- this.nbCol = opts.nbCol
24
-
25
20
  /** A function returning the number of dots for a cell value.
26
- * @type {function(number,number,import("../Style").Stat,number):number} */
27
- this.nb = opts.nb || ((v, r, s, zf) => (((0.3 * r * r) / (zf * zf)) * v) / s.max)
21
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
22
+ this.dotNumber = opts.dotNumber || ((cell, resolution) => resolution / 100)//(c,r,z,vs) => {}
28
23
 
29
24
  /** The color of the dots. Same color for all dots within a cell.
30
- * @type {function(import("../Dataset").Cell):string} */
31
- this.color = opts.color || (() => '#FF5733')
25
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
26
+ this.color = opts.color || (() => '#FF5733') //(c,r,z,vs) => {}
32
27
 
33
- /** A function returning the size of the dots, in geo unit.
34
- * @type {function(number,number):number} */
35
- this.dotSize = opts.dotSize //|| ((r, zf) => ...
28
+ /** A function returning the size of the dots, in geo unit. Same size for all cells.
29
+ * @type {function(number, number,object):number} */
30
+ this.dotSize = opts.dotSize || ((resolution, z) => 1.5 * z) //(c,r,z,vs) => {}
36
31
 
37
- /** A function returning the sigma of the distribution from the resolution, in geo unit.
38
- * @type {function(number,number):number} */
39
- this.sigma = opts.sigma //|| ((r,zf) => ...
32
+ /** A function returning the sigma of the dots distribution. Same value for all cells.
33
+ * @type {function(number, number,object):number} */
34
+ this.sigma = opts.sigma || ((resolution, z) => resolution / 2)//(c,r,z,vs) => {}
40
35
  }
41
36
 
42
37
  /**
43
38
  * Draw cells as text.
44
39
  *
45
- * @param {Array.<import("../Dataset").Cell>} cells
46
- * @param {number} r
47
- * @param {import("../GeoCanvas").GeoCanvas} cg
40
+ * @param {Array.<import("../core/Dataset").Cell>} cells
41
+ * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas
42
+ * @param {number} resolution
48
43
  */
49
- draw(cells, r, cg) {
50
- if (monitor) monitorDuration('*** DotDensityStyle draw')
44
+ draw(cells, geoCanvas, resolution) {
51
45
 
52
46
  //filter
53
47
  if (this.filter) cells = cells.filter(this.filter)
54
48
 
55
- //zoom factor
56
- const zf = cg.getZf()
49
+ //
50
+ const z = geoCanvas.view.z
57
51
 
58
- let stat
59
- if (this.nbCol) stat = Style.getStatistics(cells, (c) => c[this.nbCol], true)
60
- if (!stat) return
52
+ //get view scale
53
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
61
54
 
62
- //size of the dots
63
- const sGeo = this.dotSize ? this.dotSize(r, zf) : 2 * zf
55
+ //get size
56
+ const sGeo = this.dotSize ? this.dotSize(resolution, z, viewScale) : z
64
57
 
65
58
  //make random function
66
- const sig = this.sigma ? this.sigma(r, zf) : r * 0.4
59
+ const sig = this.sigma ? this.sigma(resolution, z, viewScale) : resolution * 0.4
67
60
  const rand = randomNormal(0, sig)
68
61
 
69
- if (monitor) monitorDuration(' preparation')
70
-
71
62
  if (checkWebGLSupport()) {
72
63
  //create canvas and webgl renderer
73
- const cvWGL = makeWebGLCanvas(cg.w + '', cg.h + '')
64
+ const cvWGL = makeWebGLCanvas(geoCanvas.w + '', geoCanvas.h + '')
74
65
  if (!cvWGL) {
75
66
  console.error('No webGL')
76
67
  return
77
68
  }
78
69
 
79
70
  //create webGL program
80
- const prog = new WebGLSquareColoring(cvWGL.gl, sGeo / zf)
71
+ const prog = new WebGLSquareColoring(cvWGL.gl, sGeo / z)
81
72
 
82
- if (monitor) monitorDuration(' webgl creation')
73
+ const r2 = resolution / 2
83
74
 
84
- const r2 = r / 2
85
-
86
- let col, offset, nb, cx, cy, cc
87
- for (let c of cells) {
75
+ for (let cell of cells) {
88
76
  //get color
89
- col = this.color(c)
77
+ const col = this.color(cell, resolution, z, viewScale)
90
78
  if (!col || col === 'none') continue
91
79
 
92
- //get offset
93
- offset = this.offset(c, r, zf)
94
-
95
80
  //number of dots
96
- nb = this.nb(c[this.nbCol], r, stat, zf)
81
+ const dotNumber = this.dotNumber(cell, resolution, z, viewScale)
82
+
83
+ //get offset
84
+ const offset = this.offset(cell, resolution, z)
97
85
 
98
86
  //cell center
99
- cx = c.x + offset.dx + r2
100
- cy = c.y + offset.dy + r2
87
+ const cx = cell.x + offset.dx + r2
88
+ const cy = cell.y + offset.dy + r2
101
89
 
102
90
  //convert color
103
- cc = color(col)
91
+ const cc = color(col)
104
92
  if (!cc) return
105
93
 
106
94
  //random points
107
- for (let i = 0; i <= nb; i++)
95
+ for (let i = 0; i <= dotNumber; i++)
108
96
  prog.addPointData2(cx + rand(), cy + rand(), cc.r, cc.g, cc.b, cc.opacity)
109
97
  }
110
98
 
111
- if (monitor) monitorDuration(' data preparation')
112
-
113
99
  //draw
114
- prog.draw(cg.getWebGLTransform())
115
-
116
- if (monitor) monitorDuration(' webgl drawing')
100
+ prog.draw(geoCanvas.getWebGLTransform())
117
101
 
118
102
  //draw in canvas geo
119
- cg.initCanvasTransform()
120
- cg.ctx.drawImage(cvWGL.canvas, 0, 0)
103
+ geoCanvas.initCanvasTransform()
104
+ geoCanvas.ctx.drawImage(cvWGL.canvas, 0, 0)
121
105
 
122
- if (monitor) monitorDuration(' canvas drawing')
123
106
  } else {
124
- //draw with HTML canvas
125
-
126
- //draw in geo coordinates
127
- cg.setCanvasTransform()
107
+ for (let cell of cells) {
128
108
 
129
- for (let c of cells) {
130
109
  //get color
131
- const col = this.color(c)
110
+ const col = this.color(cell, resolution, z, viewScale)
132
111
  if (!col || col === 'none') continue
133
112
  //set color
134
- cg.ctx.fillStyle = col
135
-
136
- //get offset
137
- const offset = this.offset(c, r, zf)
113
+ geoCanvas.ctx.fillStyle = col
138
114
 
139
115
  //number of dots
140
- const nb = this.nb(c[this.nbCol], r, stat, zf)
116
+ const dotNumber = this.dotNumber(cell, resolution, z, viewScale)
117
+
118
+ //get offset
119
+ const offset = this.offset(cell, resolution, z)
141
120
 
142
121
  //draw random dots
143
- const cx = c.x + offset.dx + r / 2,
144
- cy = c.y + offset.dy + r / 2
145
- for (let i = 0; i <= nb; i++) {
146
- cg.ctx.fillRect(cx + rand(), cy + rand(), sGeo, sGeo)
122
+ const cx = cell.x + offset.dx + resolution / 2,
123
+ cy = cell.y + offset.dy + resolution / 2
124
+ for (let i = 0; i <= dotNumber; i++) {
125
+ geoCanvas.ctx.fillRect(cx + rand(), cy + rand(), sGeo, sGeo)
147
126
  }
148
127
  }
149
128
  }
150
129
 
151
130
  //update legends
152
- this.updateLegends({ style: this, r: r, zf: zf })
153
-
154
- if (monitor) monitorDuration('*** DotDensityStyle end draw')
131
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
155
132
  }
156
133
  }
@@ -1,9 +1,10 @@
1
1
  //@ts-check
2
2
  'use strict'
3
3
 
4
- import { Style } from '../Style.js'
4
+ import { Style } from '../core/Style.js'
5
+ import { SideStyle } from './SideStyle.js'
5
6
 
6
- /** @typedef {{x:number,y:number,or:"v"|"h",c1:import('../Dataset.js').Cell|undefined,c2:import('../Dataset.js').Cell|undefined}} Side */
7
+ /** @typedef {{x:number,y:number,or:"v"|"h",c1:import('../core/Dataset.js').Cell|undefined,c2:import('../core/Dataset.js').Cell|undefined}} Side */
7
8
 
8
9
  /**
9
10
  * @author Julien Gaffuri
@@ -20,25 +21,21 @@ export class IsoFenceStyle extends Style {
20
21
  * @type {object} */
21
22
  this.color = opts.color
22
23
 
23
- /** The column where to get the height values.
24
- * @type {string} */
25
- this.heightCol = opts.heightCol
26
-
27
- /** A function returning the height of a cell.
28
- * @type {function(number,number,import("../Style").Stat|undefined,number):number} */
29
- this.height = opts.height || ((v, r, s, zf) => r * 0.4)
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)
30
27
 
31
28
  /** The perspective angle, in degree, within [-180,180], from [O,x] axis.
32
29
  * @type {number} */
33
30
  this.angle = opts.angle != undefined ? opts.angle : 50
34
31
 
35
32
  /** A function returning the corner line stroke style.
36
- * @type {function(import('../Dataset.js').Cell,number,number,number):string} */
37
- this.cornerLineStrokeColor = opts.cornerLineStrokeColor || ((c, r, zf, angle) => "#999")
33
+ * @type {function(import('../core/Dataset.js').Cell,number,number,number):string} */
34
+ this.cornerLineStrokeColor = opts.cornerLineStrokeColor || ((c, r, z, angle) => "#999")
38
35
 
39
36
  /** A function returning the corner line width.
40
- * @type {function(import('../Dataset.js').Cell,number,number,number):number} */
41
- this.cornerLineWidth = opts.cornerLineWidth || ((c, r, zf, angle) => (angle % 90 == 0 ? 0 : 0.8 * zf))
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))
42
39
 
43
40
  /**
44
41
  * Show vertical cross-sections.
@@ -52,44 +49,39 @@ export class IsoFenceStyle extends Style {
52
49
  }
53
50
 
54
51
  /**
55
- * Draw cells as segments.
56
- *
57
- * @param {Array.<import("../Dataset.js").Cell>} cells
58
- * @param {number} r
59
- * @param {import("../GeoCanvas.js").GeoCanvas} cg
52
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
53
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
54
+ * @param {number} resolution
55
+ * @override
60
56
  */
61
- draw(cells, r, cg) {
57
+ draw(cells, geoCanvas, resolution) {
58
+
62
59
  //filter
63
60
  if (this.filter) cells = cells.filter(this.filter)
64
61
 
65
- //zoom factor
66
- const zf = cg.getZf()
62
+ //
63
+ const z = geoCanvas.view.z
67
64
 
68
- let stat
69
- if (this.heightCol) {
70
- //if size is used, sort cells by size so that the biggest are drawn first
71
- cells.sort((c1, c2) => c2[this.heightCol] - c1[this.heightCol])
72
- //and compute statistics
73
- stat = Style.getStatistics(cells, (c) => c[this.heightCol], true)
74
- }
65
+ //get view scale
66
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
75
67
 
76
68
  //nb categories - used for radar and agepyramid
77
69
  const cats = Object.keys(this.color)
78
70
 
79
71
  //half resolution
80
- const r2 = r / 2
72
+ const r2 = resolution / 2
81
73
 
82
74
  //get offset
83
75
  // @ts-ignore
84
- const offset = this.offset(undefined, r, zf), dx = offset.dx, dy = offset.dy
85
-
86
- //height
87
- /** @type {function(number,number,import("../Style").Stat|undefined,number):number} */
88
- let h_ = this.height
76
+ const offset = this.offset(undefined, resolution, z), dx = offset.dx, dy = offset.dy
89
77
 
90
78
  //make sides
91
79
  /** @type {Array.<Side>} */
92
- const sides = []
80
+ const sides = SideStyle.buildSides(cells, resolution, this.angle % 180 != 90 && this.sVert, this.angle % 180 != 0 && this.sHor, true)
81
+
82
+
83
+
84
+ /*const sides = []
93
85
 
94
86
  //make horizontal sides - except when angle%180=0
95
87
  //sort cells by x and y
@@ -99,14 +91,14 @@ export class IsoFenceStyle extends Style {
99
91
  for (let i = 1; i < cells.length; i++) {
100
92
  let c2 = cells[i]
101
93
 
102
- if ((c1.y + r == c2.y) && (c1.x == c2.x))
94
+ if ((c1.y + resolution == c2.y) && (c1.x == c2.x))
103
95
  //cells in same column and touch along horizontal side
104
96
  //make shared side
105
97
  sides.push({ x: c1.x + r2, y: c2.y, or: 'h', c1: c1, c2: c2 })
106
98
  else {
107
99
  //cells do not touch along horizontal side
108
100
  //make two sides: top one for c1, bottom for c2
109
- sides.push({ x: c1.x + r2, y: c1.y + r, or: 'h', c1: c1, c2: undefined })
101
+ sides.push({ x: c1.x + r2, y: c1.y + resolution, or: 'h', c1: c1, c2: undefined })
110
102
  sides.push({ x: c2.x + r2, y: c2.y, or: 'h', c1: undefined, c2: c2 })
111
103
  }
112
104
 
@@ -122,20 +114,20 @@ export class IsoFenceStyle extends Style {
122
114
  for (let i = 1; i < cells.length; i++) {
123
115
  let c2 = cells[i]
124
116
 
125
- if ((c1.x + r == c2.x) && (c1.y == c2.y))
117
+ if ((c1.x + resolution == c2.x) && (c1.y == c2.y))
126
118
  //cells in same row and touch along vertical side
127
119
  //make shared side
128
120
  sides.push({ x: c2.x, y: c1.y + r2, or: 'v', c1: c1, c2: c2 })
129
121
  else {
130
122
  //cells do not touch along vertical side
131
123
  //make two sides: right one for c1, left for c2
132
- sides.push({ x: c1.x + r, y: c1.y + r2, or: 'v', c1: c1, c2: undefined })
124
+ sides.push({ x: c1.x + resolution, y: c1.y + r2, or: 'v', c1: c1, c2: undefined })
133
125
  sides.push({ x: c2.x, y: c2.y + r2, or: 'v', c1: undefined, c2: c2 })
134
126
  }
135
127
 
136
128
  c1 = c2
137
129
  }
138
- }
130
+ }*/
139
131
 
140
132
  //
141
133
  if (sides.length == 0) return
@@ -145,40 +137,37 @@ export class IsoFenceStyle extends Style {
145
137
 
146
138
  //sort sides so that the back ones are drawn first. This depends on the angle.
147
139
  //depending on distance to the reference corner point
148
- const xCorner = Math.abs(this.angle) < 90 ? cg.extGeo.xMin : cg.extGeo.xMax
149
- const yCorner = this.angle < 0 ? cg.extGeo.yMax : cg.extGeo.yMin
140
+ const xCorner = Math.abs(this.angle) < 90 ? geoCanvas.extGeo.xMin : geoCanvas.extGeo.xMax
141
+ const yCorner = this.angle < 0 ? geoCanvas.extGeo.yMax : geoCanvas.extGeo.yMin
150
142
  sides.sort((s1, s2) => (Math.hypot(s2.x - xCorner, s2.y - yCorner) - Math.hypot(s1.x - xCorner, s1.y - yCorner)))
151
143
 
152
144
  //prepare function to draw corner line for a cell *c*
153
- const drawCornerLine = (c) => {
145
+ const drawCornerLine = (cell) => {
154
146
 
155
- if (!c) return
147
+ if (!cell) return
156
148
  //line style
157
- const lw = this.cornerLineWidth ? this.cornerLineWidth(c, r, zf, this.angle) : 0.8 * zf
149
+ const lw = this.cornerLineWidth ? this.cornerLineWidth(cell, resolution, z, this.angle) : 0.8 * z
158
150
  if (lw == 0) return
159
- cg.ctx.strokeStyle = this.cornerLineStrokeColor ? this.cornerLineStrokeColor(c, r, zf, this.angle) : "#333"
160
- cg.ctx.lineWidth = lw
151
+ geoCanvas.ctx.strokeStyle = this.cornerLineStrokeColor ? this.cornerLineStrokeColor(cell, resolution, z, this.angle) : "#333"
152
+ geoCanvas.ctx.lineWidth = lw
161
153
 
162
154
  //height - in geo
163
- const hG = h_(c[this.heightCol], r, stat, zf)
155
+ const hG = this.height(cell, resolution, z, viewScale)
164
156
 
165
157
  //draw line
166
- cg.ctx.beginPath()
167
- cg.ctx.moveTo(c.x + r2 + dx, c.y + r2 + dy)
168
- cg.ctx.lineTo(c.x + r2 + hG * cos + dx, c.y + r2 + hG * sin + dy)
169
- cg.ctx.stroke()
158
+ geoCanvas.ctx.beginPath()
159
+ geoCanvas.ctx.moveTo(cell.x + r2 + dx, cell.y + r2 + dy)
160
+ geoCanvas.ctx.lineTo(cell.x + r2 + hG * cos + dx, cell.y + r2 + hG * sin + dy)
161
+ geoCanvas.ctx.stroke()
170
162
  }
171
163
 
172
- //draw in geo coordinates
173
- cg.setCanvasTransform()
174
-
175
164
  //draw sides
176
- cg.ctx.lineCap = "round";
165
+ geoCanvas.ctx.lineCap = "round";
177
166
  for (let s of sides) {
178
167
 
179
168
  //heights - in geo
180
- const hG1 = s.c1 ? h_(s.c1[this.heightCol], r, stat, zf) : 0,
181
- hG2 = s.c2 ? h_(s.c2[this.heightCol], r, stat, zf) : 0
169
+ const hG1 = s.c1 ? this.height(s.c1, resolution, z, viewScale) : 0,
170
+ hG2 = s.c2 ? this.height(s.c2, resolution, z, viewScale) : 0
182
171
 
183
172
  //compute totals for both cells
184
173
  const total1 = computeTotal(s.c1, cats),
@@ -201,33 +190,33 @@ export class IsoFenceStyle extends Style {
201
190
  const h2n = hG2 * (cumul2 + v2) / total2 || 0
202
191
 
203
192
  //make path
204
- cg.ctx.beginPath()
193
+ geoCanvas.ctx.beginPath()
205
194
  if (s.or == "h") {
206
195
  //horizontal side - vertical section
207
196
  //bottom left
208
- cg.ctx.moveTo(s.x + h1 * cos + dx, s.y - r2 + h1 * sin + dy)
197
+ geoCanvas.ctx.moveTo(s.x + h1 * cos + dx, s.y - r2 + h1 * sin + dy)
209
198
  //top left
210
- cg.ctx.lineTo(s.x + h2 * cos + dx, s.y + r2 + h2 * sin + dy)
199
+ geoCanvas.ctx.lineTo(s.x + h2 * cos + dx, s.y + r2 + h2 * sin + dy)
211
200
  //top right
212
- cg.ctx.lineTo(s.x + h2n * cos + dx, s.y + r2 + h2n * sin + dy)
201
+ geoCanvas.ctx.lineTo(s.x + h2n * cos + dx, s.y + r2 + h2n * sin + dy)
213
202
  //bottom right
214
- cg.ctx.lineTo(s.x + h1n * cos + dx, s.y - r2 + h1n * sin + dy)
203
+ geoCanvas.ctx.lineTo(s.x + h1n * cos + dx, s.y - r2 + h1n * sin + dy)
215
204
  } else {
216
205
  //vertical side - horizontal section
217
206
  //bottom left
218
- cg.ctx.moveTo(s.x - r2 + h1 * cos + dx, s.y + h1 * sin + dy)
207
+ geoCanvas.ctx.moveTo(s.x - r2 + h1 * cos + dx, s.y + h1 * sin + dy)
219
208
  //bottom right
220
- cg.ctx.lineTo(s.x + r2 + h2 * cos + dx, s.y + h2 * sin + dy)
209
+ geoCanvas.ctx.lineTo(s.x + r2 + h2 * cos + dx, s.y + h2 * sin + dy)
221
210
  //top right
222
- cg.ctx.lineTo(s.x + r2 + h2n * cos + dx, s.y + h2n * sin + dy)
211
+ geoCanvas.ctx.lineTo(s.x + r2 + h2n * cos + dx, s.y + h2n * sin + dy)
223
212
  //top left
224
- cg.ctx.lineTo(s.x - r2 + h1n * cos + dx, s.y + h1n * sin + dy)
213
+ geoCanvas.ctx.lineTo(s.x - r2 + h1n * cos + dx, s.y + h1n * sin + dy)
225
214
  }
226
215
  //cg.ctx.closePath()
227
216
 
228
217
  //fill
229
- cg.ctx.fillStyle = color
230
- cg.ctx.fill()
218
+ geoCanvas.ctx.fillStyle = color
219
+ geoCanvas.ctx.fill()
231
220
 
232
221
  cumul1 += v1
233
222
  cumul2 += v2
@@ -244,7 +233,7 @@ export class IsoFenceStyle extends Style {
244
233
  }
245
234
 
246
235
  //update legends
247
- this.updateLegends({ style: this, r: r, zf: zf, sSize: stat })
236
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
248
237
  }
249
238
  }
250
239
 
@@ -1,7 +1,7 @@
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
6
  /**
7
7
  *
@@ -13,43 +13,38 @@ export class JoyPlotStyle extends Style {
13
13
  super(opts)
14
14
  opts = opts || {}
15
15
 
16
- /** The cell column where to get the value to represent.
17
- * @type {string} */
18
- this.heightCol = opts.heightCol
19
-
20
- /** A function returning the height of a cell.
21
- * @type {function(number,number,import("../Style").Stat|undefined,number):number} */
22
- this.height = opts.height || ((v) => Math.sqrt(v))
16
+ /** A function returning the height of a cell in geographical unit.
17
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
18
+ this.height = opts.height || ((c, r) => r * Math.random()) //(c,r,z,vs) => {}
23
19
 
24
20
  /**
25
21
  * @type {function(number,{min:number, max:number},number,number):string} */
26
- this.lineColor = opts.lineColor || ((y, ys, r, zf) => '#BBB')
22
+ this.lineColor = opts.lineColor || ((y, ys, r, z) => '#BBB')
27
23
  /**
28
24
  * @type {function(number,{min:number, max:number},number,number):number} */
29
- this.lineWidth = opts.lineWidth || ((y, ys, r, zf) => zf)
25
+ this.lineWidth = opts.lineWidth || ((y, ys, r, z) => z)
30
26
  /**
31
27
  * @type {function(number,{min:number, max:number},number,number):string} */
32
- this.fillColor = opts.fillColor || ((y, ys, r, zf) => '#c08c5968')
28
+ this.fillColor = opts.fillColor || ((y, ys, r, z) => '#c08c5968')
33
29
  }
34
30
 
31
+
35
32
  /**
36
- * Draw cells as squares depending on their value.
37
- *
38
- * @param {Array.<import("../Dataset").Cell>} cells
39
- * @param {number} r
40
- * @param {import("../GeoCanvas").GeoCanvas} cg
41
- * */
42
- draw(cells, r, cg) {
33
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
34
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
35
+ * @param {number} resolution
36
+ * @override
37
+ */
38
+ draw(cells, geoCanvas, resolution) {
39
+
43
40
  //filter
44
41
  if (this.filter) cells = cells.filter(this.filter)
45
42
 
46
- cg.ctx.lineJoin = 'round'
43
+ //
44
+ const z = geoCanvas.view.z
47
45
 
48
- //zoom factor
49
- const zf = cg.getZf()
50
-
51
- //compute statistics
52
- const stat = Style.getStatistics(cells, (c) => c[this.heightCol], true)
46
+ //get view scale
47
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
53
48
 
54
49
  //index cells by y and x
55
50
  /** @type {object} */
@@ -60,25 +55,23 @@ export class JoyPlotStyle extends Style {
60
55
  row = {}
61
56
  ind[cell.y] = row
62
57
  }
63
- row[cell.x] = this.height(cell[this.heightCol], r, stat, zf)
58
+ row[cell.x] = this.height(cell, resolution, z, viewScale)
64
59
  }
65
60
 
66
61
  //compute extent
67
- const e = cg.extGeo
62
+ const e = geoCanvas.extGeo
68
63
  if (!e) return
69
- const xMin = Math.floor(e.xMin / r) * r
70
- const xMax = Math.floor(e.xMax / r) * r
71
- const yMin = Math.floor(e.yMin / r) * r
72
- const yMax = Math.floor(e.yMax / r) * r
64
+ const xMin = Math.floor(e.xMin / resolution) * resolution
65
+ const xMax = Math.floor(e.xMax / resolution) * resolution
66
+ const yMin = Math.floor(e.yMin / resolution) * resolution
67
+ const yMax = Math.floor(e.yMax / resolution) * resolution
73
68
 
74
69
  /** @type {{min:number, max:number}} */
75
70
  const ys = { min: yMin, max: yMax }
76
71
 
77
- //draw in geo coordinates
78
- cg.setCanvasTransform()
79
-
80
72
  //draw lines, row by row, stating from the top
81
- for (let y = yMax; y >= yMin; y -= r) {
73
+ geoCanvas.ctx.lineJoin = 'round'
74
+ for (let y = yMax; y >= yMin; y -= resolution) {
82
75
  //get row
83
76
  const row = ind[y]
84
77
 
@@ -86,15 +79,15 @@ export class JoyPlotStyle extends Style {
86
79
  if (!row) continue
87
80
 
88
81
  //place first point
89
- cg.ctx.beginPath()
90
- cg.ctx.moveTo(xMin - r / 2, y)
82
+ geoCanvas.ctx.beginPath()
83
+ geoCanvas.ctx.moveTo(xMin - resolution / 2, y)
91
84
 
92
85
  //store the previous height
93
86
  /** @type {number|undefined} */
94
87
  let hG_
95
88
 
96
89
  //go through the line cells
97
- for (let x = xMin; x <= xMax; x += r) {
90
+ for (let x = xMin; x <= xMax; x += resolution) {
98
91
  //get column value
99
92
  /** @type {number} */
100
93
  let hG = row[x]
@@ -103,32 +96,32 @@ export class JoyPlotStyle extends Style {
103
96
  if (hG || hG_) {
104
97
  //draw line only when at least one of both values is non-null
105
98
  //TODO test bezierCurveTo
106
- cg.ctx.lineTo(x + r / 2, y + hG)
99
+ geoCanvas.ctx.lineTo(x + resolution / 2, y + hG)
107
100
  } else {
108
101
  //else move the point
109
- cg.ctx.moveTo(x + r / 2, y)
102
+ geoCanvas.ctx.moveTo(x + resolution / 2, y)
110
103
  }
111
104
  //store the previous value
112
105
  hG_ = hG
113
106
  }
114
107
 
115
108
  //last point
116
- if (hG_) cg.ctx.lineTo(xMax + r / 2, y)
109
+ if (hG_) geoCanvas.ctx.lineTo(xMax + resolution / 2, y)
117
110
 
118
111
  //draw fill
119
- const fc = this.fillColor(y, ys, r, zf)
112
+ const fc = this.fillColor(y, ys, resolution, z)
120
113
  if (fc && fc != 'none') {
121
- cg.ctx.fillStyle = fc
122
- cg.ctx.fill()
114
+ geoCanvas.ctx.fillStyle = fc
115
+ geoCanvas.ctx.fill()
123
116
  }
124
117
 
125
118
  //draw line
126
- const lc = this.lineColor(y, ys, r, zf)
127
- const lw = this.lineWidth(y, ys, r, zf)
119
+ const lc = this.lineColor(y, ys, resolution, z)
120
+ const lw = this.lineWidth(y, ys, resolution, z)
128
121
  if (lc && lc != 'none' && lw > 0) {
129
- cg.ctx.strokeStyle = lc
130
- cg.ctx.lineWidth = lw
131
- cg.ctx.stroke()
122
+ geoCanvas.ctx.strokeStyle = lc
123
+ geoCanvas.ctx.lineWidth = lw
124
+ geoCanvas.ctx.stroke()
132
125
  }
133
126
  }
134
127
  }
@@ -3,8 +3,8 @@
3
3
 
4
4
  import { TanakaStyle } from './TanakaStyle.js'
5
5
  import { StrokeStyle } from './StrokeStyle.js'
6
- import { SquareColorCatWGLStyle } from './SquareColorCatWGLStyle.js'
7
- import { Style } from '../Style.js'
6
+ import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.js'
7
+ import { Style } from '../core/Style.js'
8
8
 
9
9
  /**
10
10
  * @author Julien Gaffuri
@@ -67,7 +67,7 @@ export class LegoStyle {
67
67
  opts.colBright = opts.colBright || '#aaa'
68
68
 
69
69
  //
70
- const s = new SquareColorCatWGLStyle({ colorCol: col, color: opts.color })
70
+ const s = new SquareColorCategoryWebGLStyle({ colorCol: col, color: opts.color })
71
71
  //style to show limits between pieces
72
72
  const sst = new StrokeStyle({ strokeColor: () => '#666', strokeWidth: (v, r, s, z) => 0.2 * z })
73
73
 
@@ -91,7 +91,7 @@ class LegoTopStyle extends Style {
91
91
  //filter
92
92
  if (this.filter) cells = cells.filter(this.filter)
93
93
 
94
- cg.ctx.lineWidth = 0.6 * cg.getZf()
94
+ cg.ctx.lineWidth = 0.6 * cg.view.z
95
95
 
96
96
  //dark part
97
97
  cg.ctx.strokeStyle = this.colDark