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,224 +1,224 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Legend } from '../core/Legend.js'
5
- import { nice } from '../utils/utils.js'
6
- import { max } from 'd3-array'
7
-
8
- /**
9
- * A legend element for proportional symbols.
10
- *
11
- * @module legend
12
- * @author Joseph Davies, Julien Gaffuri
13
- */
14
- export class SizeLegend extends Legend {
15
- /** @param {Object} opts */
16
- constructor(opts) {
17
- super(opts)
18
- opts = opts || {}
19
-
20
- /** A function returning the text label, from the view scale and list of cells, resolution and zoom
21
- * @type { function(object, Array.<import('../core/Dataset.js').Cell>, number, number):(number|string) } */
22
- this.label = opts.label || undefined
23
-
24
- /** A function returning the size of the legend symbol, in geo UoM, from the viewscale, resolution and zoom
25
- * @type { function(object, number, number):number } */
26
- this.size = opts.size || undefined
27
-
28
- //symbol
29
- /** @type {(import("../core/Style").Shape)|"line"} */
30
- this.shape = opts.shape || 'circle'
31
-
32
- //general case
33
- this.fillColor = opts.fillColor || 'none'
34
- this.strokeColor = opts.strokeColor || 'gray'
35
- this.strokeWidth = opts.strokeWidth || 1
36
-
37
- //for line shape
38
- //TODO this.orientation = opts.orientation || 0
39
- this.color = opts.color || 'gray'
40
- this.length = opts.length || ((resolution, z, viewScale) => resolution)
41
- }
42
-
43
- /**
44
- * @param {{ viewScale:object, resolution: number, z:number, cells:Array.<import('../core/Dataset.js').Cell> }} opts
45
- */
46
- update(opts) {
47
- //clear
48
- this.div.selectAll('*').remove()
49
-
50
- //title
51
- this.makeTitle()
52
-
53
- //get label. May not be a number (!)
54
- let label = this.label(opts.viewScale, opts.cells, opts.resolution, opts.z)
55
-
56
- //compute size of symbol, in pix
57
- let sizePix
58
- if (this.size) sizePix = this.size(opts.viewScale, opts.resolution, opts.z) / opts.z
59
- else sizePix = opts.viewScale(+label) / opts.z
60
- if (!sizePix) return
61
-
62
- //format label, if specified and possible
63
- if (this.labelFormat && !isNaN(+label)) label = this.labelFormat(label)
64
-
65
- const d = this.div.append('div')
66
- //to enable vertical centering
67
- //.style("position", "relative")
68
-
69
- //default svg construction, for square and circle
70
- const svg = () =>
71
- d
72
- .append('svg')
73
- .attr('width', sizePix + this.strokeWidth + 2)
74
- .attr('height', sizePix + this.strokeWidth + 2)
75
- .style('', 'inline-block')
76
-
77
- if (this.shape === 'square') {
78
- svg()
79
- .append('rect')
80
- .attr('x', 0)
81
- .attr('y', 0)
82
- .attr('width', sizePix)
83
- .attr('height', sizePix)
84
- .style('fill', this.fillColor)
85
- .style('stroke', this.strokeColor)
86
- .style('stroke-width', this.strokeWidth)
87
- } else if (this.shape === 'circle') {
88
- // <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
89
- const r = (sizePix + this.strokeWidth) * 0.5
90
- svg()
91
- .append('circle')
92
- .attr('cx', r + 1)
93
- .attr('cy', r + 1)
94
- .attr('r', r)
95
- .style('fill', this.fillColor)
96
- .style('stroke', this.strokeColor)
97
- .style('stroke-width', this.strokeWidth)
98
- } else if (this.shape === 'donut') {
99
- //TODO
100
- } else if (this.shape === 'diamond') {
101
- //TODO
102
- } else if (this.shape === 'line') {
103
- //get segment length
104
- let lengthPix = this.length
105
- ? this.length(opts.resolution, opts.z, opts.viewScale)
106
- : opts.resolution
107
- lengthPix /= opts.z
108
-
109
- const svg = d
110
- .append('svg')
111
- .attr('width', lengthPix)
112
- .attr('height', sizePix)
113
- .style('', 'inline-block')
114
-
115
- //TODO orientation
116
- //<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
117
- svg.append('line')
118
- .attr('x1', 0)
119
- .attr('y1', sizePix / 2)
120
- .attr('x2', lengthPix)
121
- .attr('y2', sizePix / 2)
122
- .style('stroke', this.color)
123
- .style('stroke-width', sizePix)
124
- } else {
125
- throw new Error('Unexpected shape:' + this.shape)
126
- }
127
-
128
- //label
129
- d.append('div')
130
- .style('display', 'inline')
131
- .style('padding-left', '5px')
132
- .style('font-size', this.labelFontSize)
133
- .text(label + (this.labelUnitText ? ' ' : '') + this.labelUnitText)
134
- }
135
- }
136
-
137
- /**
138
- * @param {Array.<number>} values
139
- * @param {function(number):number} size
140
- * @param { object } opts
141
- * @returns {Array.<SizeLegend>}
142
- */
143
- export function sizeLegend(values, size, opts = {}) {
144
- const legends = []
145
- for (let value of values) {
146
- opts.title = value == values[0] ? opts.title : undefined
147
- opts.size = () => size(value)
148
- opts.label = () => value
149
- legends.push(new SizeLegend(opts))
150
- }
151
- return legends
152
- }
153
-
154
- /**
155
- * @param { function(import('../core/Dataset.js').Cell):number } value
156
- * @param {*} opts
157
- * @returns {Array.<SizeLegend>}
158
- */
159
- export function sizeLegendViewScale(value, opts = {}) {
160
- const k = opts.k || [0.9, 0.5, 0.2, 0.05]
161
- const legends = []
162
- for (let k_ of k) {
163
- opts.title = k_ == k[0] ? opts.title : undefined
164
- opts.label = (viewScale, cells) => nice(k_ * max(cells, value))
165
- legends.push(new SizeLegend(opts))
166
- }
167
- return legends
168
- }
169
-
170
- /**
171
- * A function which return a stack of size legends for a discrete classification.
172
- *
173
- * @param { Array.<number> } breaks
174
- * @param { Array.<number> } sizes
175
- * @param { object } opts
176
- * @returns {Array.<SizeLegend>}
177
- */
178
- export function sizeDiscreteLegend(breaks, sizes, opts = {}) {
179
- const f = opts.labelFormat || ((x) => x)
180
- const labelText = opts.labelText || defaultLabelText(f)
181
- const legends = []
182
- for (let i = sizes.length - 1; i >= 0; i--) {
183
- opts.title = i == sizes.length - 1 ? opts.title : undefined
184
- opts.size = () => sizes[i]
185
- opts.label = () => labelText(breaks[i - 1], breaks[i])
186
- legends.push(new SizeLegend(opts))
187
- }
188
- return legends
189
- }
190
-
191
- /**
192
- * A function which return a stack of size legends for a discrete classification using a viewscale.
193
- * @param { number } classNumber
194
- * @param { object } opts
195
- * @returns {Array.<SizeLegend>}
196
- */
197
- export function sizeDiscreteViewScaleLegend(classNumber, opts = {}) {
198
- const f = opts.labelFormat || ((x) => x)
199
- const labelText = opts.labelText || defaultLabelText(f)
200
- const legends = []
201
- const viewScaleFun = opts.viewScaleFun || ((t) => t) //TODO do it differently? At sizelegend level !
202
- for (let i = classNumber - 1; i >= 0; i--) {
203
- opts.title = i == classNumber - 1 ? opts.title : undefined
204
- opts.size = (viewScale) => viewScaleFun(viewScale).values[i]
205
- opts.label = (viewScale) =>
206
- labelText(viewScaleFun(viewScale).breaks[i - 1], viewScaleFun(viewScale).breaks[i])
207
- legends.push(new SizeLegend(opts))
208
- }
209
- return legends
210
- }
211
-
212
- /**
213
- * A function that returns a function to format laberls for discrete scale legends.
214
- * @param { function(number):string } format
215
- * @returns { function(number|undefined, number|undefined): string }
216
- */
217
- function defaultLabelText(format) {
218
- return (v0, v1) => {
219
- if (v0 == undefined && v1 == undefined) return ''
220
- if (v1 == undefined) return '> ' + format(v0)
221
- if (v0 == undefined) return '< ' + format(v1)
222
- return format(v0) + ' - ' + format(v1)
223
- }
224
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Legend } from '../core/Legend.js'
5
+ import { nice } from '../utils/utils.js'
6
+ import { max } from 'd3-array'
7
+
8
+ /**
9
+ * A legend element for proportional symbols.
10
+ *
11
+ * @module legend
12
+ * @author Joseph Davies, Julien Gaffuri
13
+ */
14
+ export class SizeLegend extends Legend {
15
+ /** @param {Object} opts */
16
+ constructor(opts) {
17
+ super(opts)
18
+ opts = opts || {}
19
+
20
+ /** A function returning the text label, from the view scale and list of cells, resolution and zoom
21
+ * @type { function(object, Array.<import('../core/Dataset.js').Cell>, number, number):(number|string) } */
22
+ this.label = opts.label || undefined
23
+
24
+ /** A function returning the size of the legend symbol, in geo UoM, from the viewscale, resolution and zoom
25
+ * @type { function(object, number, number):number } */
26
+ this.size = opts.size || undefined
27
+
28
+ //symbol
29
+ /** @type {(import("../core/Style").Shape)|"line"} */
30
+ this.shape = opts.shape || 'circle'
31
+
32
+ //general case
33
+ this.fillColor = opts.fillColor || 'none'
34
+ this.strokeColor = opts.strokeColor || 'gray'
35
+ this.strokeWidth = opts.strokeWidth || 1
36
+
37
+ //for line shape
38
+ //TODO this.orientation = opts.orientation || 0
39
+ this.color = opts.color || 'gray'
40
+ this.length = opts.length || ((resolution, z, viewScale) => resolution)
41
+ }
42
+
43
+ /**
44
+ * @param {{ viewScale:object, resolution: number, z:number, cells:Array.<import('../core/Dataset.js').Cell> }} opts
45
+ */
46
+ update(opts) {
47
+ //clear
48
+ this.div.selectAll('*').remove()
49
+
50
+ //title
51
+ this.makeTitle()
52
+
53
+ //get label. May not be a number (!)
54
+ let label = this.label(opts.viewScale, opts.cells, opts.resolution, opts.z)
55
+
56
+ //compute size of symbol, in pix
57
+ let sizePix
58
+ if (this.size) sizePix = this.size(opts.viewScale, opts.resolution, opts.z) / opts.z
59
+ else sizePix = opts.viewScale(+label) / opts.z
60
+ if (!sizePix) return
61
+
62
+ //format label, if specified and possible
63
+ if (this.labelFormat && !isNaN(+label)) label = this.labelFormat(label)
64
+
65
+ const d = this.div.append('div')
66
+ //to enable vertical centering
67
+ //.style("position", "relative")
68
+
69
+ //default svg construction, for square and circle
70
+ const svg = () =>
71
+ d
72
+ .append('svg')
73
+ .attr('width', sizePix + this.strokeWidth + 2)
74
+ .attr('height', sizePix + this.strokeWidth + 2)
75
+ .style('', 'inline-block')
76
+
77
+ if (this.shape === 'square') {
78
+ svg()
79
+ .append('rect')
80
+ .attr('x', 0)
81
+ .attr('y', 0)
82
+ .attr('width', sizePix)
83
+ .attr('height', sizePix)
84
+ .style('fill', this.fillColor)
85
+ .style('stroke', this.strokeColor)
86
+ .style('stroke-width', this.strokeWidth)
87
+ } else if (this.shape === 'circle') {
88
+ // <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
89
+ const r = (sizePix + this.strokeWidth) * 0.5
90
+ svg()
91
+ .append('circle')
92
+ .attr('cx', r + 1)
93
+ .attr('cy', r + 1)
94
+ .attr('r', r)
95
+ .style('fill', this.fillColor)
96
+ .style('stroke', this.strokeColor)
97
+ .style('stroke-width', this.strokeWidth)
98
+ } else if (this.shape === 'donut') {
99
+ //TODO
100
+ } else if (this.shape === 'diamond') {
101
+ //TODO
102
+ } else if (this.shape === 'line') {
103
+ //get segment length
104
+ let lengthPix = this.length
105
+ ? this.length(opts.resolution, opts.z, opts.viewScale)
106
+ : opts.resolution
107
+ lengthPix /= opts.z
108
+
109
+ const svg = d
110
+ .append('svg')
111
+ .attr('width', lengthPix)
112
+ .attr('height', sizePix)
113
+ .style('', 'inline-block')
114
+
115
+ //TODO orientation
116
+ //<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
117
+ svg.append('line')
118
+ .attr('x1', 0)
119
+ .attr('y1', sizePix / 2)
120
+ .attr('x2', lengthPix)
121
+ .attr('y2', sizePix / 2)
122
+ .style('stroke', this.color)
123
+ .style('stroke-width', sizePix)
124
+ } else {
125
+ throw new Error('Unexpected shape:' + this.shape)
126
+ }
127
+
128
+ //label
129
+ d.append('div')
130
+ .style('display', 'inline')
131
+ .style('padding-left', '5px')
132
+ .style('font-size', this.labelFontSize)
133
+ .text(label + (this.labelUnitText ? ' ' : '') + this.labelUnitText)
134
+ }
135
+ }
136
+
137
+ /**
138
+ * @param {Array.<number>} values
139
+ * @param {function(number):number} size
140
+ * @param { object } opts
141
+ * @returns {Array.<SizeLegend>}
142
+ */
143
+ export function sizeLegend(values, size, opts = {}) {
144
+ const legends = []
145
+ for (let value of values) {
146
+ opts.title = value == values[0] ? opts.title : undefined
147
+ opts.size = () => size(value)
148
+ opts.label = () => value
149
+ legends.push(new SizeLegend(opts))
150
+ }
151
+ return legends
152
+ }
153
+
154
+ /**
155
+ * @param { function(import('../core/Dataset.js').Cell):number } value
156
+ * @param {*} opts
157
+ * @returns {Array.<SizeLegend>}
158
+ */
159
+ export function sizeLegendViewScale(value, opts = {}) {
160
+ const k = opts.k || [0.9, 0.5, 0.2, 0.05]
161
+ const legends = []
162
+ for (let k_ of k) {
163
+ opts.title = k_ == k[0] ? opts.title : undefined
164
+ opts.label = (viewScale, cells) => nice(k_ * max(cells, value))
165
+ legends.push(new SizeLegend(opts))
166
+ }
167
+ return legends
168
+ }
169
+
170
+ /**
171
+ * A function which return a stack of size legends for a discrete classification.
172
+ *
173
+ * @param { Array.<number> } breaks
174
+ * @param { Array.<number> } sizes
175
+ * @param { object } opts
176
+ * @returns {Array.<SizeLegend>}
177
+ */
178
+ export function sizeDiscreteLegend(breaks, sizes, opts = {}) {
179
+ const f = opts.labelFormat || ((x) => x)
180
+ const labelText = opts.labelText || defaultLabelText(f)
181
+ const legends = []
182
+ for (let i = sizes.length - 1; i >= 0; i--) {
183
+ opts.title = i == sizes.length - 1 ? opts.title : undefined
184
+ opts.size = () => sizes[i]
185
+ opts.label = () => labelText(breaks[i - 1], breaks[i])
186
+ legends.push(new SizeLegend(opts))
187
+ }
188
+ return legends
189
+ }
190
+
191
+ /**
192
+ * A function which return a stack of size legends for a discrete classification using a viewscale.
193
+ * @param { number } classNumber
194
+ * @param { object } opts
195
+ * @returns {Array.<SizeLegend>}
196
+ */
197
+ export function sizeDiscreteViewScaleLegend(classNumber, opts = {}) {
198
+ const f = opts.labelFormat || ((x) => x)
199
+ const labelText = opts.labelText || defaultLabelText(f)
200
+ const legends = []
201
+ const viewScaleFun = opts.viewScaleFun || ((t) => t) //TODO do it differently? At sizelegend level !
202
+ for (let i = classNumber - 1; i >= 0; i--) {
203
+ opts.title = i == classNumber - 1 ? opts.title : undefined
204
+ opts.size = (viewScale) => viewScaleFun(viewScale).values[i]
205
+ opts.label = (viewScale) =>
206
+ labelText(viewScaleFun(viewScale).breaks[i - 1], viewScaleFun(viewScale).breaks[i])
207
+ legends.push(new SizeLegend(opts))
208
+ }
209
+ return legends
210
+ }
211
+
212
+ /**
213
+ * A function that returns a function to format laberls for discrete scale legends.
214
+ * @param { function(number):string } format
215
+ * @returns { function(number|undefined, number|undefined): string }
216
+ */
217
+ function defaultLabelText(format) {
218
+ return (v0, v1) => {
219
+ if (v0 == undefined && v1 == undefined) return ''
220
+ if (v1 == undefined) return '> ' + format(v0)
221
+ if (v0 == undefined) return '< ' + format(v1)
222
+ return format(v0) + ' - ' + format(v1)
223
+ }
224
+ }