gridviz 3.0.18 → 3.0.20

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 (56) hide show
  1. package/README.md +128 -127
  2. package/dist/gridviz.js +7862 -7819
  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 +60 -60
  8. package/src/core/GeoCanvas.js +430 -419
  9. package/src/core/Layer.js +23 -23
  10. package/src/core/Legend.js +108 -108
  11. package/src/core/Map.js +516 -503
  12. package/src/core/MultiResolutionDataset.js +93 -93
  13. package/src/core/Style.js +98 -98
  14. package/src/core/Tooltip.js +1 -0
  15. package/src/dataset/CSVGrid.js +112 -112
  16. package/src/dataset/GeoTIFF.js +122 -122
  17. package/src/dataset/JSGrid.js +55 -55
  18. package/src/dataset/TiledGrid.js +302 -289
  19. package/src/dataset/worker.js +18 -18
  20. package/src/index.js +77 -77
  21. package/src/layer/BackgroundLayer.js +162 -162
  22. package/src/layer/BackgroundLayerImage.js +81 -81
  23. package/src/layer/BackgroundLayerWMS.js +104 -104
  24. package/src/layer/GeoJSONLayer.js +214 -214
  25. package/src/layer/GridLayer.js +148 -148
  26. package/src/layer/LabelLayer.js +194 -194
  27. package/src/legend/ColorCategoryLegend.js +109 -109
  28. package/src/legend/ColorDiscreteLegend.js +100 -100
  29. package/src/legend/ColorLegend.js +115 -115
  30. package/src/legend/OrientationLegend.js +89 -89
  31. package/src/legend/SizeLegend.js +224 -224
  32. package/src/legend/TernaryLegend.js +302 -302
  33. package/src/style/CompositionStyle.js +291 -291
  34. package/src/style/DotDensityStyle.js +133 -133
  35. package/src/style/ImageStyle.js +100 -100
  36. package/src/style/IsoFenceStyle.js +217 -217
  37. package/src/style/JoyPlotStyle.js +127 -127
  38. package/src/style/LegoStyle.js +110 -110
  39. package/src/style/MosaicStyle.js +99 -99
  40. package/src/style/NinjaStarStyle.js +102 -102
  41. package/src/style/PillarStyle.js +207 -207
  42. package/src/style/SegmentStyle.js +105 -105
  43. package/src/style/ShapeColorSizeStyle.js +147 -147
  44. package/src/style/SideCategoryStyle.js +112 -112
  45. package/src/style/SideStyle.js +212 -212
  46. package/src/style/SquareColorCategoryWebGLStyle.js +107 -107
  47. package/src/style/SquareColorWebGLStyle.js +126 -126
  48. package/src/style/StrokeStyle.js +135 -135
  49. package/src/style/TanakaStyle.js +69 -69
  50. package/src/style/TextStyle.js +110 -110
  51. package/src/style/TimeSeriesStyle.js +222 -222
  52. package/src/utils/scale.js +218 -218
  53. package/src/utils/stretching.js +120 -120
  54. package/src/utils/ternary.js +208 -203
  55. package/src/utils/utils.js +58 -58
  56. 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
+ }