gridviz 3.0.0 → 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 +528 -229
  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 -1
  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 +15 -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 +3 -3
  21. package/src/dataset/TiledGrid.js +1 -0
  22. package/src/index.js +3 -3
  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 +21 -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 +44 -18
  53. package/src/utils/stretching.js +4 -0
  54. package/src/utils/utils.js +2 -1
@@ -7,21 +7,18 @@ import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.j
7
7
  import { Style } from '../core/Style.js'
8
8
 
9
9
  /**
10
+ * @module style
10
11
  * @author Julien Gaffuri
11
12
  */
12
13
  export class LegoStyle {
13
- /**
14
- * @param {string} col
15
- * @param {object} opts
16
- * @returns {Array.<Style>}
17
- */
18
- static get(col, opts) {
14
+
15
+ static get(value, breaks, colors, opts = {}) {
19
16
  opts = opts || {}
20
17
 
21
18
  //the colors
22
19
  //http://www.jennyscrayoncollection.com/2021/06/all-current-lego-colors.html
23
20
  //https://leonawicz.github.io/legocolors/reference/figures/README-plot-1.png
24
- opts.colors = opts.colors || [
21
+ /*opts.colors = opts.colors || [
25
22
  '#00852b', //darker green
26
23
  '#afd246', //light green
27
24
  '#fac80a', //dark yellow
@@ -32,18 +29,18 @@ export class LegoStyle {
32
29
  '#720012', //dark red
33
30
  //"purple",
34
31
  //"#eee" //whithe
35
- ]
32
+ ]*/
36
33
 
37
34
  opts.colDark = opts.colDark || '#333'
38
35
  opts.colBright = opts.colBright || '#aaa'
39
36
  opts.widthFactor = opts.widthFactor || 0.12
40
37
 
41
38
  //reuse tanaka as basis
42
- const ts = TanakaStyle.get(col, opts)
39
+ const ts = TanakaStyle.get(value, breaks, colors, opts)
43
40
  //style to show limits between pieces
44
41
  const sst = new StrokeStyle({
45
42
  strokeColor: () => '#666',
46
- strokeWidth: (v, r, s, z) => 0.2 * z,
43
+ strokeWidth: (c, r, z) => 0.2 * z,
47
44
  filter: opts.filter,
48
45
  })
49
46
 
@@ -56,20 +53,21 @@ export class LegoStyle {
56
53
  }
57
54
 
58
55
  /**
59
- * @param {function(string):string} col
56
+ * @param {function(import('../core/Dataset.js').Cell):string} code
57
+ * @param {object} color
60
58
  * @param {object} opts
61
59
  * @returns {Array.<Style>}
62
60
  */
63
- static getCat(col, opts) {
61
+ static getCategory(code, color, opts) {
64
62
  opts = opts || {}
65
63
 
66
64
  opts.colDark = opts.colDark || '#333'
67
65
  opts.colBright = opts.colBright || '#aaa'
68
66
 
69
67
  //
70
- const s = new SquareColorCategoryWebGLStyle({ colorCol: col, color: opts.color })
68
+ const s = new SquareColorCategoryWebGLStyle({ code: code, color: color })
71
69
  //style to show limits between pieces
72
- const sst = new StrokeStyle({ strokeColor: () => '#666', strokeWidth: (v, r, s, z) => 0.2 * z })
70
+ const sst = new StrokeStyle({ strokeColor: () => '#666', strokeWidth: (c, r, z) => 0.2 * z })
73
71
 
74
72
  return [s, sst, new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright })]
75
73
  }
@@ -87,26 +85,26 @@ class LegoTopStyle extends Style {
87
85
  this.colBright = opts.colBright || '#aaa'
88
86
  }
89
87
 
90
- draw(cells, r, cg) {
88
+ draw(cells, geoCanvas, r) {
91
89
  //filter
92
90
  if (this.filter) cells = cells.filter(this.filter)
93
91
 
94
- cg.ctx.lineWidth = 0.6 * cg.view.z
92
+ geoCanvas.ctx.lineWidth = 0.6 * geoCanvas.view.z
95
93
 
96
94
  //dark part
97
- cg.ctx.strokeStyle = this.colDark
95
+ geoCanvas.ctx.strokeStyle = this.colDark
98
96
  for (let c of cells) {
99
- cg.ctx.beginPath()
100
- cg.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), true)
101
- cg.ctx.stroke()
97
+ geoCanvas.ctx.beginPath()
98
+ geoCanvas.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), true)
99
+ geoCanvas.ctx.stroke()
102
100
  }
103
101
 
104
102
  //bright part
105
- cg.ctx.strokeStyle = this.colBright
103
+ geoCanvas.ctx.strokeStyle = this.colBright
106
104
  for (let c of cells) {
107
- cg.ctx.beginPath()
108
- cg.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), false)
109
- cg.ctx.stroke()
105
+ geoCanvas.ctx.beginPath()
106
+ geoCanvas.ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), false)
107
+ geoCanvas.ctx.stroke()
110
108
  }
111
109
  }
112
110
  }
@@ -4,6 +4,7 @@
4
4
  import { Style } from '../core/Style.js'
5
5
 
6
6
  /**
7
+ * @module style
7
8
  * @author Julien Gaffuri
8
9
  */
9
10
  export class MosaicStyle 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 Joseph Davies, Julien Gaffuri
9
9
  */
10
10
  export class NinjaStarStyle extends Style {
@@ -4,6 +4,7 @@
4
4
  import { Style } from '../core/Style.js'
5
5
 
6
6
  /**
7
+ * @module style
7
8
  * @author Julien Gaffuri
8
9
  */
9
10
  export class PillarStyle extends Style {
@@ -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,11 +13,15 @@ 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
- * Generic function for view scale - continuous
22
+ * Generic function for view scale - continuous or discrete
19
23
  *
20
- * @param {{ valueFunction:function(import("../core/Dataset").Cell):number, minValue?:number, minSizePix?:number, maxSizeFactor?:number, range?:[number, number], domain?:[number, number], stretching?:function(number):number }} opts
24
+ * @param {{ valueFunction:function(import("../core/Dataset").Cell):number, minValue?:number, minSizePix?:number, maxSizeFactor?:number, range?:[number, number], domain?:[number, number], stretching?:function(number):number, classNumber?:number}} opts
21
25
  * @returns {function(Array.<import("../core/Dataset").Cell>):Scale}
22
26
  */
23
27
  export const viewScale = (opts) => {
@@ -28,21 +32,27 @@ export const viewScale = (opts) => {
28
32
  const stretching = opts.stretching
29
33
  const range_ = opts.range
30
34
  const domain_ = opts.domain
31
- return (cells, r, z) => {
35
+ const classNumber = opts.classNumber
36
+ return (cells, resolution, z) => {
32
37
  const domain = domain_ || [minValue, max(cells, valueFunction)]
33
- const range = range_ || [minSizePix * z, r * maxSizeFactor]
38
+ const range = range_ || [minSizePix * z, resolution * maxSizeFactor]
39
+ const domainSize = domain[1] - domain[0], domainMin = domain[0]
40
+ const rangeSize = range[1] - range[0], rangeMin = range[0]
34
41
  return t => {
35
42
  //scale to [0,1]
36
- t = (t - domain[0]) / (domain[1] - domain[0])
43
+ t = (t - domainMin) / domainSize
37
44
  //stretch
38
45
  if (stretching) t = stretching(t)
46
+ //classify
47
+ if (classNumber) t = t == 1 ? 1 : Math.floor(t * (classNumber)) / (classNumber - 1)
39
48
  //scale to range
40
- return range[0] + t * (range[1] - range[0])
49
+ return rangeMin + t * rangeSize
41
50
  }
42
51
  }
43
52
  }
44
53
 
45
54
 
55
+
46
56
  /**
47
57
  * Generic function for view scale - quantile
48
58
  *
@@ -55,9 +65,9 @@ export const viewScaleQuantile = (opts) => {
55
65
  const minSizePix = opts.minSizePix || 1
56
66
  const maxSizeFactor = opts.maxSizeFactor || 1
57
67
  const scale = scaleQuantile()
58
- return (cells, r, z) => {
68
+ return (cells, resolution, z) => {
59
69
  scale.domain(cells.map(valueFunction))
60
- const minSizeGeo = minSizePix * z, maxSizeGeo = r * maxSizeFactor
70
+ const minSizeGeo = minSizePix * z, maxSizeGeo = resolution * maxSizeFactor
61
71
  scale.range(Array.from({ length: classNumber }, (_, i) => minSizeGeo + i * (maxSizeGeo - minSizeGeo) / (classNumber - 1)))
62
72
  scale.breaks = scale.quantiles()
63
73
  scale.values = scale.range()
@@ -71,24 +81,30 @@ export const viewScaleQuantile = (opts) => {
71
81
 
72
82
 
73
83
  /**
74
- * Generic function for color view scale - continuous
84
+ * Generic function for color view scale - continuous or discrete
75
85
  *
76
- * @param {{ valueFunction:function(import("../core/Dataset").Cell):number, colorScale?:function(number):string, stretching?:function(number):number }} opts
86
+ * @param {{ valueFunction:function(import("../core/Dataset").Cell):number, colorScale?:function(number):string, colors?:Array.<string>, stretching?:function(number):number }} opts
77
87
  * @returns {function(Array.<import("../core/Dataset").Cell>):ColorScale}
78
88
  */
79
89
  export const viewScaleColor = (opts) => {
80
90
  const valueFunction = opts.valueFunction
81
- const colorScale = opts.colorScale || (() => "purple")
82
91
  const stretching = opts.stretching
92
+ let colorScale = opts.colorScale || (() => "purple")
93
+
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)]
98
+
83
99
  return (cells) => {
84
100
  if (cells.length == 0 || !cells) return
85
101
  /** @type {[undefined, undefined] | [number, number]} */
86
102
  const domain = extent(cells, valueFunction)
87
103
  if (domain[0] == undefined) return
88
- const amplitude = domain[1] - domain[0]
104
+ const domainSize = domain[1] - domain[0]
89
105
  const scale = t => {
90
106
  //scale to [0,1]
91
- t = (t - domain[0]) / amplitude
107
+ t = (t - domain[0]) / domainSize
92
108
  //stretch
93
109
  if (stretching) t = stretching(t)
94
110
  return colorScale(t)
@@ -96,13 +112,23 @@ export const viewScaleColor = (opts) => {
96
112
  //function that return the domain value from the [0,1] range.
97
113
  scale.invert = t => {
98
114
  if (stretching) t = stretching.invert(t)
99
- return domain[0] + t * amplitude
115
+ return domain[0] + t * domainSize
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))
100
122
  }
101
123
 
102
124
  return scale;
103
125
  }
104
126
  }
105
127
 
128
+
129
+
130
+
131
+
106
132
  /**
107
133
  * Generic function for color view scale - quantile
108
134
  *
@@ -130,16 +156,16 @@ export const viewScaleColorQuantile = (opts) => {
130
156
 
131
157
 
132
158
  /**
133
- * combine view scale functions
159
+ * Combine view scale functions
134
160
  *
135
161
  * @param {*} obj
136
- * @returns
162
+ * @returns {function}
137
163
  */
138
164
  export const viewScaleCombination = (obj) => {
139
165
  //obj: prop and a function to call
140
- return (cells, r, z) => {
166
+ return (cells, resolution, z) => {
141
167
  const out = {}
142
- 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) }
143
169
  return out
144
170
  }
145
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
+ */