gridviz 3.0.1 → 3.0.2

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 (54) hide show
  1. package/README.md +36 -33
  2. package/dist/gridviz.js +434 -183
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +4 -3
  5. package/src/button/Button.js +1 -0
  6. package/src/button/FullscreenButton.js +1 -0
  7. package/src/button/ZoomButtons.js +1 -0
  8. package/src/core/Dataset.js +1 -0
  9. package/src/core/Drawable.js +1 -0
  10. package/src/core/GeoCanvas.js +1 -0
  11. package/src/core/Layer.js +1 -0
  12. package/src/core/Legend.js +1 -0
  13. package/src/core/Map.js +1 -0
  14. package/src/core/MultiResolutionDataset.js +1 -0
  15. package/src/core/Style.js +10 -1
  16. package/src/core/Tooltip.js +1 -0
  17. package/src/dataset/COGeo.js +1 -0
  18. package/src/dataset/CSVGrid.js +1 -0
  19. package/src/dataset/GeoTIFF.js +1 -0
  20. package/src/dataset/JSGrid.js +1 -0
  21. package/src/dataset/TiledGrid.js +1 -0
  22. package/src/index.js +2 -2
  23. package/src/layer/BackgroundLayer.js +1 -0
  24. package/src/layer/BackgroundLayerWMS.js +1 -0
  25. package/src/layer/GeoJSONLayer.js +1 -0
  26. package/src/layer/GridLayer.js +1 -0
  27. package/src/layer/LabelLayer.js +1 -0
  28. package/src/legend/ColorCategoryLegend.js +1 -0
  29. package/src/legend/ColorDiscreteLegend.js +2 -0
  30. package/src/legend/ColorLegend.js +1 -0
  31. package/src/legend/OrientationLegend.js +1 -0
  32. package/src/legend/SizeLegend.js +4 -2
  33. package/src/style/CompositionStyle.js +1 -0
  34. package/src/style/ContourStyle.js +1 -0
  35. package/src/style/DotDensityStyle.js +1 -0
  36. package/src/style/IsoFenceStyle.js +24 -72
  37. package/src/style/JoyPlotStyle.js +1 -1
  38. package/src/style/LegoStyle.js +22 -24
  39. package/src/style/MosaicStyle.js +1 -0
  40. package/src/style/NinjaStarStyle.js +1 -1
  41. package/src/style/PillarStyle.js +1 -0
  42. package/src/style/SegmentStyle.js +1 -0
  43. package/src/style/ShapeColorSizeStyle.js +1 -0
  44. package/src/style/SideCategoryStyle.js +1 -0
  45. package/src/style/SideStyle.js +51 -28
  46. package/src/style/SquareColorCategoryWebGLStyle.js +4 -3
  47. package/src/style/SquareColorWebGLStyle.js +1 -0
  48. package/src/style/StrokeStyle.js +1 -1
  49. package/src/style/TanakaStyle.js +11 -5
  50. package/src/style/TextStyle.js +1 -1
  51. package/src/style/TimeSeriesStyle.js +1 -0
  52. package/src/utils/scale.js +22 -11
  53. package/src/utils/stretching.js +4 -0
  54. package/src/utils/utils.js +2 -1
@@ -6,6 +6,7 @@ import { Style } from '../core/Style.js'
6
6
  /**
7
7
  * A style where each cell is represented by a segment whose length, width, color and orientation can vary according to statistical values.
8
8
  *
9
+ * @module style
9
10
  * @author Julien Gaffuri
10
11
  */
11
12
  export class SegmentStyle extends Style {
@@ -7,6 +7,7 @@ import { Style } from '../core/Style.js'
7
7
  * A very generic style that shows grid cells with specific color, size and shape.
8
8
  * It can be used to show variables as cell colors, cell size, cell shape, or any combination of the three visual variables.
9
9
  *
10
+ * @module style
10
11
  * @author Joseph Davies, Julien Gaffuri
11
12
  */
12
13
  export class ShapeColorSizeStyle extends Style {
@@ -6,6 +6,7 @@ import { SideStyle } from './SideStyle.js'
6
6
  /**
7
7
  * A style to show the sides of grid cells based on their different categories.
8
8
  *
9
+ * @module style
9
10
  * @author Julien Gaffuri
10
11
  */
11
12
  export class SideCategoryStyle extends SideStyle {
@@ -9,7 +9,7 @@ import { Style } from '../core/Style.js'
9
9
  * @typedef {function(Array.<Side>,number, number):*} SideViewScale */
10
10
 
11
11
  /**
12
- *
12
+ * @module style
13
13
  * @author Julien Gaffuri
14
14
  */
15
15
  export class SideStyle extends Style {
@@ -28,6 +28,9 @@ export class SideStyle extends Style {
28
28
  /** A function returning the length of a cell side, in geo unit
29
29
  * @type {function(Side, number, number, object):number} */
30
30
  this.length = opts.length || ((side, resolution, z, sideViewScale) => resolution)
31
+
32
+ /** Set to A or true so that the side is drawn as a diamond */
33
+ this.diamond = opts.diamond
31
34
  }
32
35
 
33
36
  /**
@@ -63,31 +66,51 @@ export class SideStyle extends Style {
63
66
  const col = this.color ? this.color(side, resolution, z, viewScale) : undefined
64
67
  if (!col || col == 'none') continue
65
68
 
66
- //width
67
- /** @type {number|undefined} */
68
- const wG = this.width ? this.width(side, resolution, z, viewScale) : undefined
69
- if (!wG || wG <= 0) continue
70
-
71
- //length
72
- /** @type {number|undefined} */
73
- const lG = this.length ? this.length(side, resolution, z, viewScale) : undefined
74
- if (!lG || lG <= 0) continue
75
- const lG2 = lG * 0.5
76
-
77
- //set color and width
78
- geoCanvas.ctx.strokeStyle = col
79
- geoCanvas.ctx.lineWidth = wG
80
-
81
- //draw segment with correct orientation
82
- geoCanvas.ctx.beginPath()
83
- if (side.or === "v") {
84
- geoCanvas.ctx.moveTo(side.x, side.y + r2 - lG2)
85
- geoCanvas.ctx.lineTo(side.x, side.y + r2 + lG2)
69
+ if (this.diamond) {
70
+
71
+ //set color
72
+ geoCanvas.ctx.fillStyle = col
73
+
74
+ //draw diamond
75
+ const x = side.x, y = side.y
76
+ geoCanvas.ctx.beginPath()
77
+ geoCanvas.ctx.moveTo(x - r2, y)
78
+ geoCanvas.ctx.lineTo(x, y + r2)
79
+ geoCanvas.ctx.lineTo(x + r2, y)
80
+ geoCanvas.ctx.lineTo(x, y - r2)
81
+ geoCanvas.ctx.closePath()
82
+ geoCanvas.ctx.fill()
83
+
86
84
  } else {
87
- geoCanvas.ctx.moveTo(side.x + r2 - lG2, side.y)
88
- geoCanvas.ctx.lineTo(side.x + r2 + lG2, side.y)
85
+
86
+ //width
87
+ /** @type {number|undefined} */
88
+ const wG = this.width ? this.width(side, resolution, z, viewScale) : undefined
89
+ if (!wG || wG <= 0) continue
90
+
91
+ //length
92
+ /** @type {number|undefined} */
93
+ const lG = this.length ? this.length(side, resolution, z, viewScale) : undefined
94
+ if (!lG || lG <= 0) continue
95
+ const lG2 = lG * 0.5
96
+
97
+ //set width
98
+ geoCanvas.ctx.lineWidth = wG
99
+ //set color
100
+ geoCanvas.ctx.strokeStyle = col
101
+
102
+ //draw segment with correct orientation
103
+ const x = side.x, y = side.y
104
+ geoCanvas.ctx.beginPath()
105
+ if (side.or === "v") {
106
+ geoCanvas.ctx.moveTo(x, y - lG2)
107
+ geoCanvas.ctx.lineTo(x, y + lG2)
108
+ } else {
109
+ geoCanvas.ctx.moveTo(x - lG2, y)
110
+ geoCanvas.ctx.lineTo(x + lG2, y)
111
+ }
112
+ geoCanvas.ctx.stroke()
89
113
  }
90
- geoCanvas.ctx.stroke()
91
114
  }
92
115
 
93
116
  //update legends
@@ -98,18 +121,18 @@ export class SideStyle extends Style {
98
121
 
99
122
  /**
100
123
  *
101
- * @param {Array.<import('../core/Dataset').Cell>} cells The cells to use to build the sides. The side x,y coordinates are those of the left point for horizontal sides, and of the bottom point for vertical sides.
124
+ * @param {Array.<import('../core/Dataset').Cell>} cells The cells to use to build the sides.
102
125
  * @param {number} resolution The cells resolution
103
126
  * @param {boolean} withHorizontal Set to true to build horizontal sides, false otherwise.
104
127
  * @param {boolean} withVertical Set to true to build vertical sides, false otherwise.
105
- * @param {boolean} center Set to true so that the side coordinate are those of its center point rather than its left/bottom point.
128
+ * @param {boolean} centre Set to true so that the side coordinate are those of its center point rather than its left/bottom point (the side x,y coordinates are those of the left point for horizontal sides, and of the bottom point for vertical sides)
106
129
  * @returns { Array.<Side> }
107
130
  */
108
- static buildSides(cells, resolution, withHorizontal = true, withVertical = true, center = false) {
131
+ static buildSides(cells, resolution, withHorizontal = true, withVertical = true, centre = true) {
109
132
  /** @type { Array.<Side> } */
110
133
  const sides = []
111
134
 
112
- const r2 = center ? resolution / 2 : 0
135
+ const r2 = centre ? resolution / 2 : 0
113
136
 
114
137
  //make horizontal sides
115
138
  //sort cells by x and y
@@ -10,6 +10,7 @@ import { WebGLSquareColoringCatAdvanced } from '../utils/WebGLSquareColoringCatA
10
10
  * To show cells as colored squares, from categories.
11
11
  * All cells are drawn as squares, with the same size
12
12
  *
13
+ * @module style
13
14
  * @author Julien Gaffuri
14
15
  */
15
16
  export class SquareColorCategoryWebGLStyle extends Style {
@@ -19,8 +20,8 @@ export class SquareColorCategoryWebGLStyle extends Style {
19
20
  opts = opts || {}
20
21
 
21
22
  /**
22
- * The name of the column/attribute of the tabular data where to retrieve the category code of the cell, for coloring.
23
- * @type {string} */
23
+ * A function returning the category code of the cell, for coloring.
24
+ * @type {function(import('../core/Dataset.js').Cell):string} */
24
25
  this.code = opts.code
25
26
 
26
27
  /**
@@ -71,7 +72,7 @@ export class SquareColorCategoryWebGLStyle extends Style {
71
72
  const iBuffer = []
72
73
  for (let i = 0; i < nb; i++) {
73
74
  c = cells[i]
74
- const cat = c[this.code]
75
+ const cat = this.code(c)
75
76
  if (cat == undefined) {
76
77
  console.log('Unexpected category: ' + cat)
77
78
  continue
@@ -10,6 +10,7 @@ import { WebGLSquareColoringAdvanced } from '../utils/WebGLSquareColoringAdvance
10
10
  * To show cells as colored squares, with computation of the colors on GPU side (faster than JavaScript side).
11
11
  * Alls squares with the same size
12
12
  *
13
+ * @module style
13
14
  * @author Julien Gaffuri
14
15
  */
15
16
  export class SquareColorWebGLStyle extends Style {
@@ -4,7 +4,7 @@
4
4
  import { Style } from '../core/Style.js'
5
5
 
6
6
  /**
7
- *
7
+ * @module style
8
8
  * @author Julien Gaffuri
9
9
  */
10
10
  export class StrokeStyle extends Style {
@@ -8,6 +8,7 @@ import { classifier as clFun, colorClassifier as cclFun } from '../utils/scale.j
8
8
  /**
9
9
  * @see https://manifold.net/doc/mfd9/example__tanaka_contours.htm
10
10
  *
11
+ * @module style
11
12
  * @author Julien Gaffuri
12
13
  */
13
14
  export class TanakaStyle {
@@ -32,15 +33,20 @@ export class TanakaStyle {
32
33
  return Math.min(minWG + (sideValue - 1) * step, maxWG)
33
34
  })
34
35
 
35
- //make classifiers
36
+ //make classifier
36
37
  const classifier = clFun(breaks)
37
- const colorClassifier = cclFun(breaks, colors)
38
+ //make colors table
39
+ const colorsDict = {};
40
+ for (let i = 0; i < colors.length; i++) colorsDict[i + ""] = colors[i]
38
41
 
39
- const cellStyle = new SquareColorCategoryWebGLStyle({ color: (cell) => colorClassifier(value(cell)) })
42
+ const cellStyle = new SquareColorCategoryWebGLStyle({
43
+ code: cell => classifier(value(cell)),
44
+ color: colorsDict
45
+ })
40
46
 
41
47
  const getSideValue = (side) => {
42
- const cl1 = side.c1 ? classifier(value(side.c1)) : 0
43
- const cl2 = side.c2 ? classifier(value(side.c2)) : 0
48
+ const cl1 = side.c1 ? classifier(value(side.c1)) : -1
49
+ const cl2 = side.c2 ? classifier(value(side.c2)) : -1
44
50
  return cl1 - cl2
45
51
  }
46
52
 
@@ -4,7 +4,7 @@
4
4
  import { Style } from '../core/Style.js'
5
5
 
6
6
  /**
7
- *
7
+ * @module style
8
8
  * @author Julien Gaffuri
9
9
  */
10
10
  export class TextStyle extends Style {
@@ -9,6 +9,7 @@ import { Style } from '../core/Style.js'
9
9
  * Show cell as timeseries chart
10
10
  * Can be used for sparkline map of https://datagistips.hypotheses.org/488
11
11
  *
12
+ * @module style
12
13
  * @author Julien Gaffuri
13
14
  */
14
15
  export class TimeSeriesStyle extends Style {
@@ -13,6 +13,10 @@ import { scaleQuantile } from "d3-scale"
13
13
  * @typedef {function(number):string} ColorScale */
14
14
 
15
15
 
16
+ /**
17
+ * @module utils
18
+ */
19
+
16
20
 
17
21
  /**
18
22
  * Generic function for view scale - continuous or discrete
@@ -29,9 +33,9 @@ export const viewScale = (opts) => {
29
33
  const range_ = opts.range
30
34
  const domain_ = opts.domain
31
35
  const classNumber = opts.classNumber
32
- return (cells, r, z) => {
36
+ return (cells, resolution, z) => {
33
37
  const domain = domain_ || [minValue, max(cells, valueFunction)]
34
- const range = range_ || [minSizePix * z, r * maxSizeFactor]
38
+ const range = range_ || [minSizePix * z, resolution * maxSizeFactor]
35
39
  const domainSize = domain[1] - domain[0], domainMin = domain[0]
36
40
  const rangeSize = range[1] - range[0], rangeMin = range[0]
37
41
  return t => {
@@ -61,9 +65,9 @@ export const viewScaleQuantile = (opts) => {
61
65
  const minSizePix = opts.minSizePix || 1
62
66
  const maxSizeFactor = opts.maxSizeFactor || 1
63
67
  const scale = scaleQuantile()
64
- return (cells, r, z) => {
68
+ return (cells, resolution, z) => {
65
69
  scale.domain(cells.map(valueFunction))
66
- const minSizeGeo = minSizePix * z, maxSizeGeo = r * maxSizeFactor
70
+ const minSizeGeo = minSizePix * z, maxSizeGeo = resolution * maxSizeFactor
67
71
  scale.range(Array.from({ length: classNumber }, (_, i) => minSizeGeo + i * (maxSizeGeo - minSizeGeo) / (classNumber - 1)))
68
72
  scale.breaks = scale.quantiles()
69
73
  scale.values = scale.range()
@@ -87,9 +91,10 @@ export const viewScaleColor = (opts) => {
87
91
  const stretching = opts.stretching
88
92
  let colorScale = opts.colorScale || (() => "purple")
89
93
 
90
- //case of discrete colors
91
- if (opts.colors)
92
- colorScale = t => opts.colors[t == 1 ? opts.colors.length - 1 : Math.floor(t * opts.colors.length)]
94
+ //discrete colors case: build continuous color scale from discrete ones.
95
+ const nbClass = opts.colors?.length
96
+ if (opts.colors && nbClass)
97
+ colorScale = t => opts.colors[t == 1 ? nbClass - 1 : Math.floor(t * nbClass)]
93
98
 
94
99
  return (cells) => {
95
100
  if (cells.length == 0 || !cells) return
@@ -109,6 +114,12 @@ export const viewScaleColor = (opts) => {
109
114
  if (stretching) t = stretching.invert(t)
110
115
  return domain[0] + t * domainSize
111
116
  }
117
+ //discrete colors: return the breaks
118
+ if (opts.colors && nbClass) {
119
+ scale.breaks = []
120
+ for (let i = 1; i < nbClass; i++)
121
+ scale.breaks.push(scale.invert(i / nbClass))
122
+ }
112
123
 
113
124
  return scale;
114
125
  }
@@ -145,16 +156,16 @@ export const viewScaleColorQuantile = (opts) => {
145
156
 
146
157
 
147
158
  /**
148
- * combine view scale functions
159
+ * Combine view scale functions
149
160
  *
150
161
  * @param {*} obj
151
- * @returns
162
+ * @returns {function}
152
163
  */
153
164
  export const viewScaleCombination = (obj) => {
154
165
  //obj: prop and a function to call
155
- return (cells, r, z) => {
166
+ return (cells, resolution, z) => {
156
167
  const out = {}
157
- for (const p in obj) { out[p] = obj[p](cells, r, z) }
168
+ for (const p in obj) { out[p] = obj[p](cells, resolution, z) }
158
169
  return out
159
170
  }
160
171
  }
@@ -1,6 +1,10 @@
1
1
  //@ts-check
2
2
  'use strict'
3
3
 
4
+ /**
5
+ * @module utils
6
+ */
7
+
4
8
 
5
9
  //TODO invert for circular
6
10
  //TODO use Math.sqrt
@@ -30,7 +30,7 @@ export function nice(v, multiples = [8, 6, 5, 4, 2.5, 2]) {
30
30
 
31
31
 
32
32
 
33
-
33
+ /*
34
34
  export let monitor = false
35
35
 
36
36
  let previousDate
@@ -48,3 +48,4 @@ export function monitorDuration(message) {
48
48
  previousDate = nowDate
49
49
  console.log(d, message)
50
50
  }
51
+ */