gridviz 3.0.19 → 3.0.21

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 +128 -128
  2. package/dist/gridviz.js +7875 -7857
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +74 -74
  5. package/src/button/ZoomButtons.js +101 -101
  6. package/src/core/Dataset.js +154 -154
  7. package/src/core/Drawable.js +78 -60
  8. package/src/core/GeoCanvas.js +430 -430
  9. package/src/core/Layer.js +23 -23
  10. package/src/core/Legend.js +108 -108
  11. package/src/core/Map.js +516 -516
  12. package/src/core/MultiResolutionDataset.js +93 -93
  13. package/src/core/Style.js +98 -98
  14. package/src/dataset/CSVGrid.js +112 -112
  15. package/src/dataset/GeoTIFF.js +122 -122
  16. package/src/dataset/JSGrid.js +55 -55
  17. package/src/dataset/TiledGrid.js +302 -302
  18. package/src/dataset/worker.js +18 -18
  19. package/src/index.js +77 -77
  20. package/src/layer/BackgroundLayer.js +162 -162
  21. package/src/layer/BackgroundLayerImage.js +81 -81
  22. package/src/layer/BackgroundLayerWMS.js +104 -104
  23. package/src/layer/GeoJSONLayer.js +214 -214
  24. package/src/layer/GridLayer.js +148 -148
  25. package/src/layer/LabelLayer.js +194 -194
  26. package/src/legend/ColorCategoryLegend.js +109 -109
  27. package/src/legend/ColorDiscreteLegend.js +100 -100
  28. package/src/legend/ColorLegend.js +115 -115
  29. package/src/legend/OrientationLegend.js +89 -89
  30. package/src/legend/SizeLegend.js +224 -224
  31. package/src/legend/TernaryLegend.js +302 -302
  32. package/src/style/CompositionStyle.js +291 -291
  33. package/src/style/DotDensityStyle.js +133 -133
  34. package/src/style/ImageStyle.js +100 -100
  35. package/src/style/IsoFenceStyle.js +217 -217
  36. package/src/style/JoyPlotStyle.js +127 -127
  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 -207
  41. package/src/style/SegmentStyle.js +105 -105
  42. package/src/style/ShapeColorSizeStyle.js +147 -147
  43. package/src/style/SideCategoryStyle.js +112 -112
  44. package/src/style/SideStyle.js +212 -212
  45. package/src/style/SquareColorCategoryWebGLStyle.js +107 -107
  46. package/src/style/SquareColorWebGLStyle.js +126 -126
  47. package/src/style/StrokeStyle.js +135 -135
  48. package/src/style/TanakaStyle.js +69 -69
  49. package/src/style/TextStyle.js +110 -110
  50. package/src/style/TimeSeriesStyle.js +222 -222
  51. package/src/utils/scale.js +218 -218
  52. package/src/utils/stretching.js +120 -120
  53. package/src/utils/ternary.js +208 -208
  54. package/src/utils/utils.js +58 -58
  55. package/src/utils/webGLUtils.js +72 -72
@@ -1,104 +1,104 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Layer } from '../core/Layer.js'
5
-
6
- /**
7
- *
8
- * A map WMS background layer.
9
- *
10
- * @module layer
11
- * @author Julien Gaffuri
12
- */
13
- export class BackgroundLayerWMS extends Layer {
14
- /**
15
- * @param {object} opts
16
- */
17
- constructor(opts) {
18
- super(opts)
19
- opts = opts || {}
20
-
21
- /**
22
- * @type {string} */
23
- this.url = opts.url
24
-
25
- /** @type {HTMLImageElement|undefined} */
26
- this.img = undefined
27
-
28
- /** @type {number|undefined} */
29
- this.xMin = undefined
30
- /** @type {number|undefined} */
31
- this.xMax = undefined
32
- /** @type {number|undefined} */
33
- this.yMin = undefined
34
- /** @type {number|undefined} */
35
- this.yMax = undefined
36
- }
37
-
38
- /** Check if the view has moved and a new image needs to be retrieved.
39
- * @private */
40
- hasMoved(extGeo) {
41
- if (extGeo.xMin != this.xMin) return true
42
- else if (extGeo.xMax != this.xMax) return true
43
- else if (extGeo.yMin != this.yMin) return true
44
- else if (extGeo.yMax != this.yMax) return true
45
- else return false
46
- }
47
-
48
- /**
49
- * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
50
- * @returns {void}
51
- */
52
- draw(geoCanvas) {
53
- //update map extent
54
- geoCanvas.updateExtentGeo(0)
55
-
56
- if (!this.hasMoved(geoCanvas.extGeo) && this.img) {
57
- //the map did not move and the image was already downloaded: draw the image
58
- geoCanvas.initCanvasTransform()
59
- geoCanvas.offscreenCtx.drawImage(this.img, 0, 0, geoCanvas.w, geoCanvas.h)
60
- } else {
61
- //the map moved: retrieve new image
62
-
63
- //
64
- this.xMin = geoCanvas.extGeo.xMin
65
- this.xMax = geoCanvas.extGeo.xMax
66
- this.yMin = geoCanvas.extGeo.yMin
67
- this.yMax = geoCanvas.extGeo.yMax
68
-
69
- //build WMS URL
70
- const url = []
71
- url.push(this.url)
72
- url.push('&width=')
73
- url.push(geoCanvas.w)
74
- url.push('&height=')
75
- url.push(geoCanvas.h)
76
- //bbox: xmin ymin xmax ymax
77
- url.push('&bbox=')
78
- url.push(geoCanvas.extGeo.xMin)
79
- url.push(',')
80
- url.push(geoCanvas.extGeo.yMin)
81
- url.push(',')
82
- url.push(geoCanvas.extGeo.xMax)
83
- url.push(',')
84
- url.push(geoCanvas.extGeo.yMax)
85
-
86
- const urlS = url.join('')
87
- //console.log(urlS)
88
-
89
- if (!this.img) {
90
- this.img = new Image()
91
- this.img.onload = () => {
92
- geoCanvas.redraw()
93
- }
94
- this.img.onerror = () => {
95
- //case when no image
96
- console.warn('Could not retrieve WMS background image from', urlS)
97
- }
98
- }
99
-
100
- //set URL to launch the download
101
- this.img.src = urlS
102
- }
103
- }
104
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Layer } from '../core/Layer.js'
5
+
6
+ /**
7
+ *
8
+ * A map WMS background layer.
9
+ *
10
+ * @module layer
11
+ * @author Julien Gaffuri
12
+ */
13
+ export class BackgroundLayerWMS extends Layer {
14
+ /**
15
+ * @param {object} opts
16
+ */
17
+ constructor(opts) {
18
+ super(opts)
19
+ opts = opts || {}
20
+
21
+ /**
22
+ * @type {string} */
23
+ this.url = opts.url
24
+
25
+ /** @type {HTMLImageElement|undefined} */
26
+ this.img = undefined
27
+
28
+ /** @type {number|undefined} */
29
+ this.xMin = undefined
30
+ /** @type {number|undefined} */
31
+ this.xMax = undefined
32
+ /** @type {number|undefined} */
33
+ this.yMin = undefined
34
+ /** @type {number|undefined} */
35
+ this.yMax = undefined
36
+ }
37
+
38
+ /** Check if the view has moved and a new image needs to be retrieved.
39
+ * @private */
40
+ hasMoved(extGeo) {
41
+ if (extGeo.xMin != this.xMin) return true
42
+ else if (extGeo.xMax != this.xMax) return true
43
+ else if (extGeo.yMin != this.yMin) return true
44
+ else if (extGeo.yMax != this.yMax) return true
45
+ else return false
46
+ }
47
+
48
+ /**
49
+ * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
50
+ * @returns {void}
51
+ */
52
+ draw(geoCanvas) {
53
+ //update map extent
54
+ geoCanvas.updateExtentGeo(0)
55
+
56
+ if (!this.hasMoved(geoCanvas.extGeo) && this.img) {
57
+ //the map did not move and the image was already downloaded: draw the image
58
+ geoCanvas.initCanvasTransform()
59
+ geoCanvas.offscreenCtx.drawImage(this.img, 0, 0, geoCanvas.w, geoCanvas.h)
60
+ } else {
61
+ //the map moved: retrieve new image
62
+
63
+ //
64
+ this.xMin = geoCanvas.extGeo.xMin
65
+ this.xMax = geoCanvas.extGeo.xMax
66
+ this.yMin = geoCanvas.extGeo.yMin
67
+ this.yMax = geoCanvas.extGeo.yMax
68
+
69
+ //build WMS URL
70
+ const url = []
71
+ url.push(this.url)
72
+ url.push('&width=')
73
+ url.push(geoCanvas.w)
74
+ url.push('&height=')
75
+ url.push(geoCanvas.h)
76
+ //bbox: xmin ymin xmax ymax
77
+ url.push('&bbox=')
78
+ url.push(geoCanvas.extGeo.xMin)
79
+ url.push(',')
80
+ url.push(geoCanvas.extGeo.yMin)
81
+ url.push(',')
82
+ url.push(geoCanvas.extGeo.xMax)
83
+ url.push(',')
84
+ url.push(geoCanvas.extGeo.yMax)
85
+
86
+ const urlS = url.join('')
87
+ //console.log(urlS)
88
+
89
+ if (!this.img) {
90
+ this.img = new Image()
91
+ this.img.onload = () => {
92
+ geoCanvas.redraw()
93
+ }
94
+ this.img.onerror = () => {
95
+ //case when no image
96
+ console.warn('Could not retrieve WMS background image from', urlS)
97
+ }
98
+ }
99
+
100
+ //set URL to launch the download
101
+ this.img.src = urlS
102
+ }
103
+ }
104
+ }
@@ -1,214 +1,214 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Layer } from '../core/Layer.js'
5
- import { json } from 'd3-fetch'
6
-
7
- /**
8
- * @module layer
9
- * @author Joseph Davies, Julien Gaffuri
10
- */
11
- export class GeoJSONLayer extends Layer {
12
- /**
13
- * @param {object} opts
14
- */
15
- constructor(opts) {
16
- super(opts)
17
- opts = opts || {}
18
-
19
- /**
20
- * @private
21
- * @type {string} */
22
- this.url = opts.url
23
-
24
- /**
25
- * A preprocess to run on each feature after loading.
26
- * It can be used to apply some specific treatment before, format the label data, project coordinates, etc.
27
- * Return false if the label should not be kept.
28
- * @private
29
- * @type {function(object):boolean} */
30
- this.preprocess = opts.preprocess
31
-
32
- //for points
33
- /**
34
- * @private
35
- * @type {function(object,number):string} */
36
- this.shape = opts.shape || ((f, z) => 'circle')
37
- /**
38
- * In pixel
39
- * @private
40
- * @type {function(object,number):number} */
41
- this.size = opts.size || ((f, z) => 10)
42
- /**
43
- * @private
44
- * @type {function(object,number):string} */
45
- this.strokeStyle = opts.strokeStyle || ((f, z) => 'red')
46
- /**
47
- * @private
48
- * @type {function(object,number):string} */
49
- this.fillStyle = opts.fillStyle || ((f, z) => 'black')
50
- /**
51
- * In pixel
52
- * @private
53
- * @type {function(object,number):number} */
54
- this.lineWidth = opts.lineWidth || ((f, z) => 2)
55
-
56
- //for lines
57
-
58
- /**
59
- * @private
60
- * @type {function(object,number):string} */
61
- this.color = opts.color || ((f, z) => 'gray')
62
- /**
63
- * In pixel
64
- * @private
65
- * @type {function(object,number):number} */
66
- this.width = opts.width || ((f, z) => 2)
67
- /**
68
- * @private
69
- * @type {function(object,number):Array.<number>|undefined} */
70
- this.lineDash = opts.lineDash || ((f, z) => undefined)
71
-
72
- /**
73
- * @private
74
- * @type {Array.<object> | undefined} */
75
- this.fs = undefined
76
-
77
- /**
78
- * @private
79
- * @type {string} */
80
- this.loadingStatus = 'notLoaded'
81
- }
82
-
83
- /**
84
- * Draw the layer.
85
- * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas The canvas where to draw the layer.
86
- * @returns {void}
87
- */
88
- draw(geoCanvas) {
89
- //load data, if not done yet.
90
- if (!this.fs) {
91
- this.load(geoCanvas.redraw)
92
- return
93
- }
94
-
95
- //
96
- const z = geoCanvas.view.z
97
- const ctx = geoCanvas.offscreenCtx
98
-
99
- for (const f of this.fs) {
100
- const gt = f.geometry.type
101
-
102
- if (gt == 'Point') {
103
- const c = f.geometry.coordinates
104
-
105
- //get style parameters for the point feature
106
- const shape = this.shape(f, z)
107
- if (!shape || shape == 'none') continue
108
- const size = this.size(f, z) * z
109
- if (!size) continue
110
- const strokeStyle = this.strokeStyle(f, z)
111
- const fillStyle = this.fillStyle(f, z)
112
- const lineWidth = this.lineWidth(f, z) * z
113
-
114
- //set canvas drawing parameters
115
- if (strokeStyle) ctx.strokeStyle = strokeStyle
116
- if (fillStyle) ctx.fillStyle = fillStyle
117
- if (lineWidth) ctx.lineWidth = lineWidth
118
-
119
- if (shape == 'circle') {
120
- //draw circle - fill and stroke
121
- ctx.beginPath()
122
- ctx.arc(c[0], c[1], size / 2, 0, 2 * Math.PI, false)
123
- if (fillStyle) ctx.fill()
124
- if (strokeStyle && lineWidth) ctx.stroke()
125
- } else if (shape == 'square') {
126
- //draw square - fill and stroke
127
- ctx.beginPath()
128
- ctx.rect(c[0] - size / 2, c[1] - size / 2, size, size)
129
- if (fillStyle) ctx.fill()
130
- if (strokeStyle && lineWidth) ctx.stroke()
131
- } else {
132
- console.error('Unexpected shape for point geojson: ' + shape)
133
- }
134
- } else if (gt == 'LineString') {
135
- const cs = f.geometry.coordinates
136
- if (cs.length < 2) continue
137
-
138
- //set color
139
- const col = this.color(f, z)
140
- if (!col || col == 'none') continue
141
- ctx.strokeStyle = col
142
-
143
- //set linewidth
144
- const wP = this.width(f, z)
145
- if (!wP || wP < 0) continue
146
- ctx.lineWidth = wP * z
147
-
148
- //set line dash
149
- const ldP = this.lineDash(f, z)
150
- if (ldP) ctx.setLineDash(ldP)
151
-
152
- //draw line
153
- ctx.beginPath()
154
- ctx.moveTo(cs[0][0], cs[0][1])
155
- for (let i = 1; i < cs.length; i++) ctx.lineTo(cs[i][0], cs[i][1])
156
- ctx.stroke()
157
- } else {
158
- console.log('Unsupported geometry type in GeoJSONLayer: ' + gt)
159
- }
160
- }
161
-
162
- //...
163
- ctx.setLineDash([])
164
- }
165
-
166
- /**
167
- * Load data for labels, from URL this.url
168
- * @param {function():void} callback
169
- * @private
170
- */
171
- async load(callback) {
172
- if (!this.url) {
173
- console.log('Failed loading boundaries: No URL specified. ' + this.url)
174
- this.loadingStatus = 'failed'
175
- this.labels = []
176
- return
177
- }
178
-
179
- //check if data already loaded
180
- if (this.loadingStatus != 'notLoaded') return
181
-
182
- //load data
183
- this.loadingStatus = 'loading'
184
-
185
- try {
186
- const data_ = await json(this.url)
187
-
188
- /** @type { Array.<object> } */
189
- const data = data_.features
190
-
191
- //preprocess/filter
192
- if (this.preprocess) {
193
- this.fs = []
194
- for (const c of data) {
195
- const b = this.preprocess(c)
196
- if (b == false) continue
197
- this.fs.push(c)
198
- }
199
- } else {
200
- //store labels
201
- this.fs = data
202
- }
203
-
204
- this.loadingStatus = 'loaded'
205
-
206
- //redraw
207
- if (callback) callback()
208
- } catch (error) {
209
- console.log('Failed loading boundaries from ' + this.url)
210
- this.fs = []
211
- this.loadingStatus = 'failed'
212
- }
213
- }
214
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Layer } from '../core/Layer.js'
5
+ import { json } from 'd3-fetch'
6
+
7
+ /**
8
+ * @module layer
9
+ * @author Joseph Davies, Julien Gaffuri
10
+ */
11
+ export class GeoJSONLayer extends Layer {
12
+ /**
13
+ * @param {object} opts
14
+ */
15
+ constructor(opts) {
16
+ super(opts)
17
+ opts = opts || {}
18
+
19
+ /**
20
+ * @private
21
+ * @type {string} */
22
+ this.url = opts.url
23
+
24
+ /**
25
+ * A preprocess to run on each feature after loading.
26
+ * It can be used to apply some specific treatment before, format the label data, project coordinates, etc.
27
+ * Return false if the label should not be kept.
28
+ * @private
29
+ * @type {function(object):boolean} */
30
+ this.preprocess = opts.preprocess
31
+
32
+ //for points
33
+ /**
34
+ * @private
35
+ * @type {function(object,number):string} */
36
+ this.shape = opts.shape || ((f, z) => 'circle')
37
+ /**
38
+ * In pixel
39
+ * @private
40
+ * @type {function(object,number):number} */
41
+ this.size = opts.size || ((f, z) => 10)
42
+ /**
43
+ * @private
44
+ * @type {function(object,number):string} */
45
+ this.strokeStyle = opts.strokeStyle || ((f, z) => 'red')
46
+ /**
47
+ * @private
48
+ * @type {function(object,number):string} */
49
+ this.fillStyle = opts.fillStyle || ((f, z) => 'black')
50
+ /**
51
+ * In pixel
52
+ * @private
53
+ * @type {function(object,number):number} */
54
+ this.lineWidth = opts.lineWidth || ((f, z) => 2)
55
+
56
+ //for lines
57
+
58
+ /**
59
+ * @private
60
+ * @type {function(object,number):string} */
61
+ this.color = opts.color || ((f, z) => 'gray')
62
+ /**
63
+ * In pixel
64
+ * @private
65
+ * @type {function(object,number):number} */
66
+ this.width = opts.width || ((f, z) => 2)
67
+ /**
68
+ * @private
69
+ * @type {function(object,number):Array.<number>|undefined} */
70
+ this.lineDash = opts.lineDash || ((f, z) => undefined)
71
+
72
+ /**
73
+ * @private
74
+ * @type {Array.<object> | undefined} */
75
+ this.fs = undefined
76
+
77
+ /**
78
+ * @private
79
+ * @type {string} */
80
+ this.loadingStatus = 'notLoaded'
81
+ }
82
+
83
+ /**
84
+ * Draw the layer.
85
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas The canvas where to draw the layer.
86
+ * @returns {void}
87
+ */
88
+ draw(geoCanvas) {
89
+ //load data, if not done yet.
90
+ if (!this.fs) {
91
+ this.load(geoCanvas.redraw)
92
+ return
93
+ }
94
+
95
+ //
96
+ const z = geoCanvas.view.z
97
+ const ctx = geoCanvas.offscreenCtx
98
+
99
+ for (const f of this.fs) {
100
+ const gt = f.geometry.type
101
+
102
+ if (gt == 'Point') {
103
+ const c = f.geometry.coordinates
104
+
105
+ //get style parameters for the point feature
106
+ const shape = this.shape(f, z)
107
+ if (!shape || shape == 'none') continue
108
+ const size = this.size(f, z) * z
109
+ if (!size) continue
110
+ const strokeStyle = this.strokeStyle(f, z)
111
+ const fillStyle = this.fillStyle(f, z)
112
+ const lineWidth = this.lineWidth(f, z) * z
113
+
114
+ //set canvas drawing parameters
115
+ if (strokeStyle) ctx.strokeStyle = strokeStyle
116
+ if (fillStyle) ctx.fillStyle = fillStyle
117
+ if (lineWidth) ctx.lineWidth = lineWidth
118
+
119
+ if (shape == 'circle') {
120
+ //draw circle - fill and stroke
121
+ ctx.beginPath()
122
+ ctx.arc(c[0], c[1], size / 2, 0, 2 * Math.PI, false)
123
+ if (fillStyle) ctx.fill()
124
+ if (strokeStyle && lineWidth) ctx.stroke()
125
+ } else if (shape == 'square') {
126
+ //draw square - fill and stroke
127
+ ctx.beginPath()
128
+ ctx.rect(c[0] - size / 2, c[1] - size / 2, size, size)
129
+ if (fillStyle) ctx.fill()
130
+ if (strokeStyle && lineWidth) ctx.stroke()
131
+ } else {
132
+ console.error('Unexpected shape for point geojson: ' + shape)
133
+ }
134
+ } else if (gt == 'LineString') {
135
+ const cs = f.geometry.coordinates
136
+ if (cs.length < 2) continue
137
+
138
+ //set color
139
+ const col = this.color(f, z)
140
+ if (!col || col == 'none') continue
141
+ ctx.strokeStyle = col
142
+
143
+ //set linewidth
144
+ const wP = this.width(f, z)
145
+ if (!wP || wP < 0) continue
146
+ ctx.lineWidth = wP * z
147
+
148
+ //set line dash
149
+ const ldP = this.lineDash(f, z)
150
+ if (ldP) ctx.setLineDash(ldP)
151
+
152
+ //draw line
153
+ ctx.beginPath()
154
+ ctx.moveTo(cs[0][0], cs[0][1])
155
+ for (let i = 1; i < cs.length; i++) ctx.lineTo(cs[i][0], cs[i][1])
156
+ ctx.stroke()
157
+ } else {
158
+ console.log('Unsupported geometry type in GeoJSONLayer: ' + gt)
159
+ }
160
+ }
161
+
162
+ //...
163
+ ctx.setLineDash([])
164
+ }
165
+
166
+ /**
167
+ * Load data for labels, from URL this.url
168
+ * @param {function():void} callback
169
+ * @private
170
+ */
171
+ async load(callback) {
172
+ if (!this.url) {
173
+ console.log('Failed loading boundaries: No URL specified. ' + this.url)
174
+ this.loadingStatus = 'failed'
175
+ this.labels = []
176
+ return
177
+ }
178
+
179
+ //check if data already loaded
180
+ if (this.loadingStatus != 'notLoaded') return
181
+
182
+ //load data
183
+ this.loadingStatus = 'loading'
184
+
185
+ try {
186
+ const data_ = await json(this.url)
187
+
188
+ /** @type { Array.<object> } */
189
+ const data = data_.features
190
+
191
+ //preprocess/filter
192
+ if (this.preprocess) {
193
+ this.fs = []
194
+ for (const c of data) {
195
+ const b = this.preprocess(c)
196
+ if (b == false) continue
197
+ this.fs.push(c)
198
+ }
199
+ } else {
200
+ //store labels
201
+ this.fs = data
202
+ }
203
+
204
+ this.loadingStatus = 'loaded'
205
+
206
+ //redraw
207
+ if (callback) callback()
208
+ } catch (error) {
209
+ console.log('Failed loading boundaries from ' + this.url)
210
+ this.fs = []
211
+ this.loadingStatus = 'failed'
212
+ }
213
+ }
214
+ }