gridviz 3.0.14 → 3.0.16

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 +127 -128
  2. package/dist/gridviz.js +7959 -7860
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +74 -74
  5. package/src/button/ZoomButtons.js +101 -96
  6. package/src/core/Dataset.js +154 -157
  7. package/src/core/Drawable.js +60 -61
  8. package/src/core/GeoCanvas.js +409 -370
  9. package/src/core/Layer.js +23 -25
  10. package/src/core/Legend.js +108 -110
  11. package/src/core/Map.js +495 -495
  12. package/src/core/MultiResolutionDataset.js +93 -97
  13. package/src/core/Style.js +98 -99
  14. package/src/dataset/CSVGrid.js +112 -112
  15. package/src/dataset/GeoTIFF.js +122 -123
  16. package/src/dataset/JSGrid.js +55 -54
  17. package/src/dataset/TiledGrid.js +289 -288
  18. package/src/dataset/worker.js +18 -0
  19. package/src/index.js +77 -71
  20. package/src/layer/BackgroundLayer.js +162 -158
  21. package/src/layer/BackgroundLayerImage.js +81 -84
  22. package/src/layer/BackgroundLayerWMS.js +104 -108
  23. package/src/layer/GeoJSONLayer.js +214 -220
  24. package/src/layer/GridLayer.js +148 -157
  25. package/src/layer/LabelLayer.js +194 -193
  26. package/src/legend/ColorCategoryLegend.js +109 -110
  27. package/src/legend/ColorDiscreteLegend.js +100 -102
  28. package/src/legend/ColorLegend.js +115 -118
  29. package/src/legend/OrientationLegend.js +89 -91
  30. package/src/legend/SizeLegend.js +224 -224
  31. package/src/legend/TernaryLegend.js +302 -210
  32. package/src/style/CompositionStyle.js +291 -288
  33. package/src/style/DotDensityStyle.js +133 -134
  34. package/src/style/ImageStyle.js +100 -102
  35. package/src/style/IsoFenceStyle.js +217 -203
  36. package/src/style/JoyPlotStyle.js +127 -128
  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 -208
  41. package/src/style/SegmentStyle.js +105 -105
  42. package/src/style/ShapeColorSizeStyle.js +147 -132
  43. package/src/style/SideCategoryStyle.js +112 -114
  44. package/src/style/SideStyle.js +212 -205
  45. package/src/style/SquareColorCategoryWebGLStyle.js +107 -108
  46. package/src/style/SquareColorWebGLStyle.js +126 -126
  47. package/src/style/StrokeStyle.js +135 -136
  48. package/src/style/TanakaStyle.js +69 -68
  49. package/src/style/TextStyle.js +110 -111
  50. package/src/style/TimeSeriesStyle.js +222 -229
  51. package/src/utils/scale.js +218 -228
  52. package/src/utils/stretching.js +120 -133
  53. package/src/utils/ternary.js +203 -203
  54. package/src/utils/utils.js +58 -63
  55. package/src/utils/webGLUtils.js +72 -70
@@ -1,68 +1,69 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { SideStyle } from './SideStyle.js'
5
- import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.js'
6
- import { classifier as clFun, colorClassifier as cclFun } from '../utils/scale.js'
7
-
8
- /**
9
- * @see https://manifold.net/doc/mfd9/example__tanaka_contours.htm
10
- *
11
- * @module style
12
- * @author Julien Gaffuri
13
- */
14
- export class TanakaStyle {
15
- /**
16
- * @param {function(import('../core/Dataset.js').Cell):number} value Function that returns the value of a cell
17
- * @param {Array.<number>} breaks The break values
18
- * @param {Array.<string>} colors The colors, one more than the break values
19
- * @param {object} opts
20
- * @returns {Array.<import("../core/Style").Style>}
21
- */
22
- static get(value, breaks, colors, opts = {}) {
23
-
24
- //shadow colors
25
- opts.colorDark = opts.colorDark || '#111'
26
- opts.colorBright = opts.colorBright || '#ddd'
27
-
28
- /** @type { function(number, number):number } */
29
- opts.width = opts.width || ((sideValue, resolution, z) => {
30
- const minWG = 1 * z
31
- const maxWG = 4 * z
32
- const step = (maxWG - minWG) / 3
33
- return Math.min(minWG + (sideValue - 1) * step, maxWG)
34
- })
35
-
36
- //make classifier
37
- const classifier = clFun(breaks)
38
- //make colors table
39
- const colorsDict = {};
40
- for (let i = 0; i < colors.length; i++) colorsDict[i + ""] = colors[i]
41
-
42
- const cellStyle = new SquareColorCategoryWebGLStyle({
43
- code: cell => classifier(value(cell)),
44
- color: colorsDict
45
- })
46
-
47
- const getSideValue = (side) => {
48
- const cl1 = side.c1 ? classifier(value(side.c1)) : -1
49
- const cl2 = side.c2 ? classifier(value(side.c2)) : -1
50
- return cl1 - cl2
51
- }
52
-
53
- /** The side style, for the shadow effect */
54
- const sideStyle = new SideStyle({
55
- //white or black, depending on orientation and value
56
- color: (side) => {
57
- const v = getSideValue(side)
58
- if (v === 0) return
59
- if (side.or === 'v') return v < 0 ? opts.colorBright : opts.colorDark
60
- return v < 0 ? opts.colorDark : opts.colorBright
61
- },
62
- //width depends on the value, that is the number of classes of difference
63
- width: (side, resolution, z) => opts.width(Math.abs(getSideValue(side)), resolution, z)
64
- })
65
-
66
- return [cellStyle, sideStyle]
67
- }
68
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { SideStyle } from './SideStyle.js'
5
+ import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.js'
6
+ import { classifier as clFun, colorClassifier as cclFun } from '../utils/scale.js'
7
+
8
+ /**
9
+ * @see https://manifold.net/doc/mfd9/example__tanaka_contours.htm
10
+ *
11
+ * @module style
12
+ * @author Julien Gaffuri
13
+ */
14
+ export class TanakaStyle {
15
+ /**
16
+ * @param {function(import('../core/Dataset.js').Cell):number} value Function that returns the value of a cell
17
+ * @param {Array.<number>} breaks The break values
18
+ * @param {Array.<string>} colors The colors, one more than the break values
19
+ * @param {object} opts
20
+ * @returns {Array.<import("../core/Style").Style>}
21
+ */
22
+ static get(value, breaks, colors, opts = {}) {
23
+ //shadow colors
24
+ opts.colorDark = opts.colorDark || '#111'
25
+ opts.colorBright = opts.colorBright || '#ddd'
26
+
27
+ /** @type { function(number, number):number } */
28
+ opts.width =
29
+ opts.width ||
30
+ ((sideValue, resolution, z) => {
31
+ const minWG = 1 * z
32
+ const maxWG = 4 * z
33
+ const step = (maxWG - minWG) / 3
34
+ return Math.min(minWG + (sideValue - 1) * step, maxWG)
35
+ })
36
+
37
+ //make classifier
38
+ const classifier = clFun(breaks)
39
+ //make colors table
40
+ const colorsDict = {}
41
+ for (let i = 0; i < colors.length; i++) colorsDict[i + ''] = colors[i]
42
+
43
+ const cellStyle = new SquareColorCategoryWebGLStyle({
44
+ code: (cell) => classifier(value(cell)),
45
+ color: colorsDict,
46
+ })
47
+
48
+ const getSideValue = (side) => {
49
+ const cl1 = side.c1 ? classifier(value(side.c1)) : -1
50
+ const cl2 = side.c2 ? classifier(value(side.c2)) : -1
51
+ return cl1 - cl2
52
+ }
53
+
54
+ /** The side style, for the shadow effect */
55
+ const sideStyle = new SideStyle({
56
+ //white or black, depending on orientation and value
57
+ color: (side) => {
58
+ const v = getSideValue(side)
59
+ if (v === 0) return
60
+ if (side.or === 'v') return v < 0 ? opts.colorBright : opts.colorDark
61
+ return v < 0 ? opts.colorDark : opts.colorBright
62
+ },
63
+ //width depends on the value, that is the number of classes of difference
64
+ width: (side, resolution, z) => opts.width(Math.abs(getSideValue(side)), resolution, z),
65
+ })
66
+
67
+ return [cellStyle, sideStyle]
68
+ }
69
+ }
@@ -1,111 +1,110 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Style } from '../core/Style.js'
5
-
6
- /**
7
- * @module style
8
- * @author Julien Gaffuri
9
- */
10
- export class TextStyle extends Style {
11
- /** @param {object} opts */
12
- constructor(opts) {
13
- super(opts)
14
- opts = opts || {}
15
-
16
- /** A function returning the text of a cell.
17
- * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
18
- this.text = opts.text || (() => 'X') //(c,r,z,vs) => {}
19
-
20
- /** A function returning the color of the cell.
21
- * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
22
- this.color = opts.color || (() => "black") //(c,r,z,vs) => {}
23
-
24
- /** A function returning the font size of a cell in geo unit.
25
- * @type {function(import('../core/Dataset.js').Cell, number, number,object):number} */
26
- this.fontSize = opts.fontSize || ((cell, resolution) => resolution) //(c,r,z,vs) => {}
27
-
28
- /** The text font family.
29
- * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
30
- this.fontFamily = opts.fontFamily || (() => 'Arial')
31
-
32
- /** The text font weight.
33
- * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
34
- this.fontWeight = opts.fontWeight || (() => 'bold')
35
- }
36
-
37
- /**
38
- * Draw cells as text.
39
- *
40
- * @param {Array.<import("../core/Dataset").Cell>} cells
41
- * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas
42
- * @param {number} resolution
43
- */
44
- draw(cells, geoCanvas, resolution) {
45
-
46
- //filter
47
- if (this.filter) cells = cells.filter(this.filter)
48
-
49
- //
50
- const z = geoCanvas.view.z
51
-
52
- //get view scale
53
- const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
54
-
55
- //draw with HTML canvas
56
- //in screen coordinates
57
- geoCanvas.initCanvasTransform()
58
-
59
- for (let cell of cells) {
60
- //get cell text
61
- const text = this.text ? this.text(cell, resolution, z, viewScale) : undefined
62
- if (text == undefined || text == null || text + '' === '') continue
63
-
64
- //color
65
- const col = this.color ? this.color(cell, resolution, z, viewScale) : undefined
66
- if (!col) continue
67
- geoCanvas.ctx.fillStyle = col
68
-
69
- //font size
70
- //size - in pixel unit
71
- const fontSizePix = this.fontSize(cell, resolution, z, viewScale) / z
72
- if (!fontSizePix) continue
73
-
74
- //set font
75
- const fontFamily = this.fontFamily ? this.fontFamily(cell, resolution, z, viewScale) : 'Arial'
76
- const fontWeight = this.fontWeight ? this.fontWeight(cell, resolution, z, viewScale) : 'bold'
77
- geoCanvas.ctx.font = fontWeight + ' ' + fontSizePix + 'px ' + fontFamily
78
-
79
- //get offset
80
- const offset = this.offset(cell, resolution, z)
81
-
82
- //text position
83
- geoCanvas.ctx.textAlign = 'center'
84
- const tx = geoCanvas.geoToPixX(cell.x + resolution * 0.5 + offset.dx)
85
- const ty = geoCanvas.geoToPixY(cell.y + resolution * 0.5 + offset.dy) + fontSizePix * 0.3 //it should be 0.5 but 0.3 seems to work better
86
-
87
- //draw the text
88
- geoCanvas.ctx.fillText(text, tx, ty)
89
- }
90
-
91
- //update legends
92
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
93
- }
94
-
95
- /**
96
- * Build a function [0,1]->string for characters legend
97
- *
98
- * @param {Array.<string>} chars
99
- * @param {(function(number):number)|undefined} scale
100
- * @returns {function(number):string}
101
- */
102
- static textScale(chars, scale = undefined) {
103
- const nb = chars.length
104
- return (t) => {
105
- if (scale) t = scale(t)
106
- if (t == 0) return ""
107
- if (t >= 1) return chars[nb - 1]
108
- return chars[Math.floor(t * nb)]
109
- }
110
- }
111
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Style } from '../core/Style.js'
5
+
6
+ /**
7
+ * @module style
8
+ * @author Julien Gaffuri
9
+ */
10
+ export class TextStyle extends Style {
11
+ /** @param {object} opts */
12
+ constructor(opts) {
13
+ super(opts)
14
+ opts = opts || {}
15
+
16
+ /** A function returning the text of a cell.
17
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
18
+ this.text = opts.text || (() => 'X') //(c,r,z,vs) => {}
19
+
20
+ /** A function returning the color of the cell.
21
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
22
+ this.color = opts.color || (() => 'black') //(c,r,z,vs) => {}
23
+
24
+ /** A function returning the font size of a cell in geo unit.
25
+ * @type {function(import('../core/Dataset.js').Cell, number, number,object):number} */
26
+ this.fontSize = opts.fontSize || ((cell, resolution) => resolution) //(c,r,z,vs) => {}
27
+
28
+ /** The text font family.
29
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
30
+ this.fontFamily = opts.fontFamily || (() => 'Arial')
31
+
32
+ /** The text font weight.
33
+ * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
34
+ this.fontWeight = opts.fontWeight || (() => 'bold')
35
+ }
36
+
37
+ /**
38
+ * Draw cells as text.
39
+ *
40
+ * @param {Array.<import("../core/Dataset").Cell>} cells
41
+ * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas
42
+ * @param {number} resolution
43
+ */
44
+ draw(cells, geoCanvas, resolution) {
45
+ //filter
46
+ if (this.filter) cells = cells.filter(this.filter)
47
+
48
+ //
49
+ const z = geoCanvas.view.z
50
+ const ctx = geoCanvas.offscreenCtx
51
+ //get view scale
52
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
53
+
54
+ //draw with HTML canvas
55
+ //in screen coordinates
56
+ geoCanvas.initCanvasTransform()
57
+
58
+ for (let cell of cells) {
59
+ //get cell text
60
+ const text = this.text ? this.text(cell, resolution, z, viewScale) : undefined
61
+ if (text == undefined || text == null || text + '' === '') continue
62
+
63
+ //color
64
+ const col = this.color ? this.color(cell, resolution, z, viewScale) : undefined
65
+ if (!col) continue
66
+ ctx.fillStyle = col
67
+
68
+ //font size
69
+ //size - in pixel unit
70
+ const fontSizePix = this.fontSize(cell, resolution, z, viewScale) / z
71
+ if (!fontSizePix) continue
72
+
73
+ //set font
74
+ const fontFamily = this.fontFamily ? this.fontFamily(cell, resolution, z, viewScale) : 'Arial'
75
+ const fontWeight = this.fontWeight ? this.fontWeight(cell, resolution, z, viewScale) : 'bold'
76
+ ctx.font = fontWeight + ' ' + fontSizePix + 'px ' + fontFamily
77
+
78
+ //get offset
79
+ const offset = this.offset(cell, resolution, z)
80
+
81
+ //text position
82
+ ctx.textAlign = 'center'
83
+ const tx = geoCanvas.geoToPixX(cell.x + resolution * 0.5 + offset.dx)
84
+ const ty = geoCanvas.geoToPixY(cell.y + resolution * 0.5 + offset.dy) + fontSizePix * 0.3 //it should be 0.5 but 0.3 seems to work better
85
+
86
+ //draw the text
87
+ ctx.fillText(text, tx, ty)
88
+ }
89
+
90
+ //update legends
91
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
92
+ }
93
+
94
+ /**
95
+ * Build a function [0,1]->string for characters legend
96
+ *
97
+ * @param {Array.<string>} chars
98
+ * @param {(function(number):number)|undefined} scale
99
+ * @returns {function(number):string}
100
+ */
101
+ static textScale(chars, scale = undefined) {
102
+ const nb = chars.length
103
+ return (t) => {
104
+ if (scale) t = scale(t)
105
+ if (t == 0) return ''
106
+ if (t >= 1) return chars[nb - 1]
107
+ return chars[Math.floor(t * nb)]
108
+ }
109
+ }
110
+ }