gridviz 2.0.37 → 2.0.39
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.
- package/README.md +119 -119
- package/dist/gridviz.js +33256 -33296
- package/dist/gridviz.min.js +1 -1
- package/package.json +78 -78
- package/src/App.js +698 -698
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +103 -103
- package/src/GeoCanvas.js +419 -419
- package/src/LabelLayer.js +190 -190
- package/src/Layer.js +92 -92
- package/src/Legend.js +86 -86
- package/src/LineLayer.js +150 -150
- package/src/Style.js +114 -114
- package/src/Tooltip.js +168 -166
- package/src/dataset/COGeo.js +24 -24
- package/src/dataset/CSVGrid.js +104 -104
- package/src/dataset/GeoTIFF.js +127 -127
- package/src/dataset/GridTile.js +41 -41
- package/src/dataset/ParquetGrid.js +122 -122
- package/src/dataset/TiledGrid.js +296 -296
- package/src/index.js +177 -177
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +105 -105
- package/src/legend/ColorLegend.js +125 -125
- package/src/legend/SegmentOrientationLegend.js +87 -87
- package/src/legend/SegmentWidthLegend.js +97 -97
- package/src/legend/SizeLegend.js +141 -141
- package/src/style/CompositionStyle.js +300 -300
- package/src/style/ContourStyle.js +54 -54
- package/src/style/DotDensityStyle.js +156 -156
- package/src/style/JoyPlotStyle.js +135 -135
- package/src/style/KernelSmoothingOldStyle.js +221 -221
- package/src/style/KernelSmoothingStyle.js +115 -115
- package/src/style/KernelSmoothingWGLStyle.js +130 -130
- package/src/style/LegoStyle.js +112 -112
- package/src/style/MosaicStyle.js +107 -107
- package/src/style/NinjaStarStyle.js +124 -124
- package/src/style/PillarStyle.js +230 -230
- package/src/style/SegmentStyle.js +142 -142
- package/src/style/ShapeColorSizeStyle.js +126 -126
- package/src/style/SideCatStyle.js +172 -172
- package/src/style/SideStyle.js +218 -218
- package/src/style/SquareColorCatWGLStyle.js +120 -120
- package/src/style/SquareColorWGLStyle.js +146 -146
- package/src/style/StrokeStyle.js +131 -131
- package/src/style/TanakaStyle.js +160 -160
- package/src/style/TextStyle.js +132 -132
- package/src/utils/Utils.js +35 -35
- package/src/utils/WebGLRectangleColoring.js +106 -106
- package/src/utils/WebGLSquareColoring.js +118 -118
- package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
- package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
- package/src/utils/WebGLSquareColoringKS.js +153 -153
- package/src/utils/stretching.js +131 -131
- package/src/utils/webGLUtils.js +71 -71
- package/src/utils/zoomUtils.js +142 -142
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
import { density2d } from 'fast-kde'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A style representing the cell as a smoothed layer, to smoothing local variations and show main trends across space.
|
|
9
|
-
*
|
|
10
|
-
* @author Julien Gaffuri
|
|
11
|
-
*/
|
|
12
|
-
export class KernelSmoothingStyle extends Style {
|
|
13
|
-
// https://observablehq.com/d/5dd1cb5e4d21c021
|
|
14
|
-
// https://observablehq.com/@uwdata/fast-kde
|
|
15
|
-
// https://observablehq.com/d/3127b6d89ada959f
|
|
16
|
-
//TODO https://observablehq.com/@sahilchinoy/areal-interpolation-iii ?
|
|
17
|
-
|
|
18
|
-
/** @param {object} opts */
|
|
19
|
-
constructor(opts) {
|
|
20
|
-
super(opts)
|
|
21
|
-
opts = opts || {}
|
|
22
|
-
|
|
23
|
-
/** A function returning the value to consider for each cell. This is the value to be smoothed.
|
|
24
|
-
* @type {function(import("../Dataset").Cell):number} */
|
|
25
|
-
this.value = opts.value
|
|
26
|
-
|
|
27
|
-
/** The smoothing parameter, in geo unit. The larger, the more smoothed.
|
|
28
|
-
* @type {function(number,number):number}
|
|
29
|
-
*/
|
|
30
|
-
this.sigma = opts.sigma // (r, zf)=>...
|
|
31
|
-
|
|
32
|
-
/** A factor to adjust the smoothed grid resolution.
|
|
33
|
-
* When set to 1, the smoothed grid is exactly the screen resolution.
|
|
34
|
-
* Set to 2 to degrade the resolution to a factor 2.
|
|
35
|
-
* The higher, the more pixelised and the faster to compute.
|
|
36
|
-
* @type { number }
|
|
37
|
-
*/
|
|
38
|
-
this.factor = opts.factor || 2
|
|
39
|
-
|
|
40
|
-
/** A filter function to filter the smoothed cells based on their smoothed value.
|
|
41
|
-
* Return true to keep the cell, false otherwise.
|
|
42
|
-
* @type { function(number):boolean }
|
|
43
|
-
*/
|
|
44
|
-
this.filterSm = opts.filterSm
|
|
45
|
-
|
|
46
|
-
/** The name of the attribute where the smoothed value is stored in the output smoothed grid.
|
|
47
|
-
* @type { string }
|
|
48
|
-
*/
|
|
49
|
-
this.sCol = opts.sCol || 'ksmval'
|
|
50
|
-
|
|
51
|
-
/** The styles to represent the smoothed grid.
|
|
52
|
-
* @type {Array.<Style>}
|
|
53
|
-
*/
|
|
54
|
-
this.styles = opts.styles || []
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Draw the smoothed cells depending on the list of styles specified.
|
|
59
|
-
*
|
|
60
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
61
|
-
* @param {number} r
|
|
62
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
63
|
-
*/
|
|
64
|
-
draw(cells, r, cg) {
|
|
65
|
-
//filter
|
|
66
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
67
|
-
|
|
68
|
-
if (!cells || cells.length == 0) return
|
|
69
|
-
|
|
70
|
-
//get smoothing param in geo unit
|
|
71
|
-
/** @type {number} */
|
|
72
|
-
const sG = this.sigma(r, cg.zf)
|
|
73
|
-
|
|
74
|
-
//compute smoothed grid dimensions
|
|
75
|
-
const nbX = Math.ceil(cg.w / this.factor)
|
|
76
|
-
const nbY = Math.ceil(cg.h / this.factor)
|
|
77
|
-
//compute smoothed grid geo extent
|
|
78
|
-
const e_ = [
|
|
79
|
-
[cg.pixToGeoX(0), cg.pixToGeoX(nbX * this.factor)],
|
|
80
|
-
[cg.pixToGeoY(nbY * this.factor), cg.pixToGeoY(0)],
|
|
81
|
-
]
|
|
82
|
-
|
|
83
|
-
//compute smoothed grid
|
|
84
|
-
let g = density2d(cells, {
|
|
85
|
-
x: (c) => c.x + r / 2,
|
|
86
|
-
y: (c) => c.y + r / 2,
|
|
87
|
-
weight: (c) => this.value(c),
|
|
88
|
-
bins: [nbX, nbY],
|
|
89
|
-
bandwidth: sG,
|
|
90
|
-
extent: e_,
|
|
91
|
-
}).grid()
|
|
92
|
-
|
|
93
|
-
//compute the resolution of the smoothed grid
|
|
94
|
-
const resSmoothed = (e_[0][1] - e_[0][0]) / nbX
|
|
95
|
-
|
|
96
|
-
//make smoothed cells
|
|
97
|
-
cells = []
|
|
98
|
-
for (let ind = 0; ind < g.length; ind++) {
|
|
99
|
-
const v = g[ind]
|
|
100
|
-
if (this.filterSm && !this.filterSm(v)) continue
|
|
101
|
-
const row = Math.floor(ind / nbX)
|
|
102
|
-
const col = ind % nbX
|
|
103
|
-
const c = { x: e_[0][0] + col * resSmoothed, y: e_[1][0] + row * resSmoothed }
|
|
104
|
-
c[this.sCol] = v
|
|
105
|
-
cells.push(c)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
//draw smoothed cells from styles
|
|
109
|
-
for (let s of this.styles) s.draw(cells, resSmoothed, cg)
|
|
110
|
-
|
|
111
|
-
//update legends
|
|
112
|
-
//for (let s of this.styles)
|
|
113
|
-
// s.updateLegends({ style: s, r: r, zf: cg.getZf() });
|
|
114
|
-
}
|
|
115
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
import { density2d } from 'fast-kde'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A style representing the cell as a smoothed layer, to smoothing local variations and show main trends across space.
|
|
9
|
+
*
|
|
10
|
+
* @author Julien Gaffuri
|
|
11
|
+
*/
|
|
12
|
+
export class KernelSmoothingStyle extends Style {
|
|
13
|
+
// https://observablehq.com/d/5dd1cb5e4d21c021
|
|
14
|
+
// https://observablehq.com/@uwdata/fast-kde
|
|
15
|
+
// https://observablehq.com/d/3127b6d89ada959f
|
|
16
|
+
//TODO https://observablehq.com/@sahilchinoy/areal-interpolation-iii ?
|
|
17
|
+
|
|
18
|
+
/** @param {object} opts */
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
super(opts)
|
|
21
|
+
opts = opts || {}
|
|
22
|
+
|
|
23
|
+
/** A function returning the value to consider for each cell. This is the value to be smoothed.
|
|
24
|
+
* @type {function(import("../Dataset").Cell):number} */
|
|
25
|
+
this.value = opts.value
|
|
26
|
+
|
|
27
|
+
/** The smoothing parameter, in geo unit. The larger, the more smoothed.
|
|
28
|
+
* @type {function(number,number):number}
|
|
29
|
+
*/
|
|
30
|
+
this.sigma = opts.sigma // (r, zf)=>...
|
|
31
|
+
|
|
32
|
+
/** A factor to adjust the smoothed grid resolution.
|
|
33
|
+
* When set to 1, the smoothed grid is exactly the screen resolution.
|
|
34
|
+
* Set to 2 to degrade the resolution to a factor 2.
|
|
35
|
+
* The higher, the more pixelised and the faster to compute.
|
|
36
|
+
* @type { number }
|
|
37
|
+
*/
|
|
38
|
+
this.factor = opts.factor || 2
|
|
39
|
+
|
|
40
|
+
/** A filter function to filter the smoothed cells based on their smoothed value.
|
|
41
|
+
* Return true to keep the cell, false otherwise.
|
|
42
|
+
* @type { function(number):boolean }
|
|
43
|
+
*/
|
|
44
|
+
this.filterSm = opts.filterSm
|
|
45
|
+
|
|
46
|
+
/** The name of the attribute where the smoothed value is stored in the output smoothed grid.
|
|
47
|
+
* @type { string }
|
|
48
|
+
*/
|
|
49
|
+
this.sCol = opts.sCol || 'ksmval'
|
|
50
|
+
|
|
51
|
+
/** The styles to represent the smoothed grid.
|
|
52
|
+
* @type {Array.<Style>}
|
|
53
|
+
*/
|
|
54
|
+
this.styles = opts.styles || []
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Draw the smoothed cells depending on the list of styles specified.
|
|
59
|
+
*
|
|
60
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
61
|
+
* @param {number} r
|
|
62
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
63
|
+
*/
|
|
64
|
+
draw(cells, r, cg) {
|
|
65
|
+
//filter
|
|
66
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
67
|
+
|
|
68
|
+
if (!cells || cells.length == 0) return
|
|
69
|
+
|
|
70
|
+
//get smoothing param in geo unit
|
|
71
|
+
/** @type {number} */
|
|
72
|
+
const sG = this.sigma(r, cg.zf)
|
|
73
|
+
|
|
74
|
+
//compute smoothed grid dimensions
|
|
75
|
+
const nbX = Math.ceil(cg.w / this.factor)
|
|
76
|
+
const nbY = Math.ceil(cg.h / this.factor)
|
|
77
|
+
//compute smoothed grid geo extent
|
|
78
|
+
const e_ = [
|
|
79
|
+
[cg.pixToGeoX(0), cg.pixToGeoX(nbX * this.factor)],
|
|
80
|
+
[cg.pixToGeoY(nbY * this.factor), cg.pixToGeoY(0)],
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
//compute smoothed grid
|
|
84
|
+
let g = density2d(cells, {
|
|
85
|
+
x: (c) => c.x + r / 2,
|
|
86
|
+
y: (c) => c.y + r / 2,
|
|
87
|
+
weight: (c) => this.value(c),
|
|
88
|
+
bins: [nbX, nbY],
|
|
89
|
+
bandwidth: sG,
|
|
90
|
+
extent: e_,
|
|
91
|
+
}).grid()
|
|
92
|
+
|
|
93
|
+
//compute the resolution of the smoothed grid
|
|
94
|
+
const resSmoothed = (e_[0][1] - e_[0][0]) / nbX
|
|
95
|
+
|
|
96
|
+
//make smoothed cells
|
|
97
|
+
cells = []
|
|
98
|
+
for (let ind = 0; ind < g.length; ind++) {
|
|
99
|
+
const v = g[ind]
|
|
100
|
+
if (this.filterSm && !this.filterSm(v)) continue
|
|
101
|
+
const row = Math.floor(ind / nbX)
|
|
102
|
+
const col = ind % nbX
|
|
103
|
+
const c = { x: e_[0][0] + col * resSmoothed, y: e_[1][0] + row * resSmoothed }
|
|
104
|
+
c[this.sCol] = v
|
|
105
|
+
cells.push(c)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//draw smoothed cells from styles
|
|
109
|
+
for (let s of this.styles) s.draw(cells, resSmoothed, cg)
|
|
110
|
+
|
|
111
|
+
//update legends
|
|
112
|
+
//for (let s of this.styles)
|
|
113
|
+
// s.updateLegends({ style: s, r: r, zf: cg.getZf() });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
import { makeWebGLCanvas } from '../utils/webGLUtils'
|
|
6
|
-
import { WebGLSquareColoringKS } from '../utils/WebGLSquareColoringKS'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @author Julien Gaffuri
|
|
10
|
-
*/
|
|
11
|
-
export class KernelSmoothingStyle extends Style {
|
|
12
|
-
//see
|
|
13
|
-
//https://stackoverflow.com/questions/8099979/creating-a-glsl-arrays-of-uniforms
|
|
14
|
-
//see https://gist.github.com/jasonkit/c5b4fd62e8cbfe2780cc
|
|
15
|
-
|
|
16
|
-
/** @param {object} opts */
|
|
17
|
-
constructor(opts) {
|
|
18
|
-
super(opts)
|
|
19
|
-
opts = opts || {}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
23
|
-
* @type {string} */
|
|
24
|
-
this.colorCol = opts.colorCol
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* A function returning the t value (within [0,1]) of the cell.
|
|
28
|
-
* @type {function(number,number,import("../Style").Stat):number} */
|
|
29
|
-
this.tFun = opts.tFun || ((v, r, s) => v / s.max)
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Distribution stretching method.
|
|
33
|
-
* The stretching is performed on GPU side (fragment shader).
|
|
34
|
-
* @type {{ fun:string, alpha:number }} */
|
|
35
|
-
this.stretching = opts.stretching
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* The sample of the color ramp.
|
|
39
|
-
* The color is computed on GPU side (fragment shader) based on those values (linear interpolation).
|
|
40
|
-
* @type {Array.<string>} */
|
|
41
|
-
this.colors =
|
|
42
|
-
opts.colors ||
|
|
43
|
-
[
|
|
44
|
-
'rgb(158, 1, 66)',
|
|
45
|
-
'rgb(248, 142, 83)',
|
|
46
|
-
'rgb(251, 248, 176)',
|
|
47
|
-
'rgb(137, 207, 165)',
|
|
48
|
-
'rgb(94, 79, 162)',
|
|
49
|
-
].reverse()
|
|
50
|
-
if (opts.color)
|
|
51
|
-
this.colors = [
|
|
52
|
-
opts.color(0),
|
|
53
|
-
opts.color(0.2),
|
|
54
|
-
opts.color(0.4),
|
|
55
|
-
opts.color(0.6),
|
|
56
|
-
opts.color(0.8),
|
|
57
|
-
opts.color(1),
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* A function returning the size of the cells, in geographical unit. All cells have the same size.
|
|
62
|
-
* @type {function(number,number):number} */
|
|
63
|
-
this.size = opts.size // (resolution, zf) => ...
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
68
|
-
* @param {number} r
|
|
69
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
70
|
-
*/
|
|
71
|
-
draw(cells, r, cg) {
|
|
72
|
-
//filter
|
|
73
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
74
|
-
|
|
75
|
-
//zoom factor
|
|
76
|
-
const zf = cg.getZf()
|
|
77
|
-
|
|
78
|
-
//compute color variable statistics
|
|
79
|
-
const statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
80
|
-
|
|
81
|
-
if (!statColor) return
|
|
82
|
-
|
|
83
|
-
//create canvas and webgl renderer
|
|
84
|
-
const cvWGL = makeWebGLCanvas(cg.w + '', cg.h + '')
|
|
85
|
-
if (!cvWGL) {
|
|
86
|
-
console.error('No webGL')
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
//add vertice and fragment data
|
|
91
|
-
const r2 = r / 2
|
|
92
|
-
let c,
|
|
93
|
-
nb = cells.length
|
|
94
|
-
const verticesBuffer = []
|
|
95
|
-
//const tBuffer = []
|
|
96
|
-
for (let i = 0; i < nb; i++) {
|
|
97
|
-
c = cells[i]
|
|
98
|
-
const t = this.tFun(c[this.colorCol], r, statColor)
|
|
99
|
-
if (t == null || t == undefined) continue
|
|
100
|
-
verticesBuffer.push(c.x + r2, c.y + r2)
|
|
101
|
-
//tBuffer.push(t > 1 ? 1 : t < 0 ? 0 : t)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const sizeGeo = this.size ? this.size(r, zf) : r + 0.2 * zf
|
|
105
|
-
const wgp = new WebGLSquareColoringKS(cvWGL.gl, this.colors, this.stretching, sizeGeo / zf)
|
|
106
|
-
|
|
107
|
-
//TODO - [i,j,t]
|
|
108
|
-
let data = []
|
|
109
|
-
for (const c of cells) {
|
|
110
|
-
const xGL = cg.geoToPixX(c.x + r2) //TODO within [-1,1] ?
|
|
111
|
-
data.push(xGL)
|
|
112
|
-
const yGL = cg.geoToPixY(c.y + r2) //TODO within [-1,1] ?
|
|
113
|
-
data.push(yGL)
|
|
114
|
-
const t = this.tFun(c[this.colorCol], r, statColor)
|
|
115
|
-
data.push(t)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
data = [0.0, 2.0, 1.0, 0.0, 0.0, 0.0]
|
|
119
|
-
|
|
120
|
-
//draw
|
|
121
|
-
wgp.draw(verticesBuffer, data, cg.getWebGLTransform())
|
|
122
|
-
|
|
123
|
-
//draw in canvas geo
|
|
124
|
-
cg.initCanvasTransform()
|
|
125
|
-
cg.ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
126
|
-
|
|
127
|
-
//update legends
|
|
128
|
-
this.updateLegends({ style: this, r: r, zf: zf, sColor: statColor })
|
|
129
|
-
}
|
|
130
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
import { makeWebGLCanvas } from '../utils/webGLUtils'
|
|
6
|
+
import { WebGLSquareColoringKS } from '../utils/WebGLSquareColoringKS'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @author Julien Gaffuri
|
|
10
|
+
*/
|
|
11
|
+
export class KernelSmoothingStyle extends Style {
|
|
12
|
+
//see
|
|
13
|
+
//https://stackoverflow.com/questions/8099979/creating-a-glsl-arrays-of-uniforms
|
|
14
|
+
//see https://gist.github.com/jasonkit/c5b4fd62e8cbfe2780cc
|
|
15
|
+
|
|
16
|
+
/** @param {object} opts */
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
super(opts)
|
|
19
|
+
opts = opts || {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
23
|
+
* @type {string} */
|
|
24
|
+
this.colorCol = opts.colorCol
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A function returning the t value (within [0,1]) of the cell.
|
|
28
|
+
* @type {function(number,number,import("../Style").Stat):number} */
|
|
29
|
+
this.tFun = opts.tFun || ((v, r, s) => v / s.max)
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Distribution stretching method.
|
|
33
|
+
* The stretching is performed on GPU side (fragment shader).
|
|
34
|
+
* @type {{ fun:string, alpha:number }} */
|
|
35
|
+
this.stretching = opts.stretching
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The sample of the color ramp.
|
|
39
|
+
* The color is computed on GPU side (fragment shader) based on those values (linear interpolation).
|
|
40
|
+
* @type {Array.<string>} */
|
|
41
|
+
this.colors =
|
|
42
|
+
opts.colors ||
|
|
43
|
+
[
|
|
44
|
+
'rgb(158, 1, 66)',
|
|
45
|
+
'rgb(248, 142, 83)',
|
|
46
|
+
'rgb(251, 248, 176)',
|
|
47
|
+
'rgb(137, 207, 165)',
|
|
48
|
+
'rgb(94, 79, 162)',
|
|
49
|
+
].reverse()
|
|
50
|
+
if (opts.color)
|
|
51
|
+
this.colors = [
|
|
52
|
+
opts.color(0),
|
|
53
|
+
opts.color(0.2),
|
|
54
|
+
opts.color(0.4),
|
|
55
|
+
opts.color(0.6),
|
|
56
|
+
opts.color(0.8),
|
|
57
|
+
opts.color(1),
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A function returning the size of the cells, in geographical unit. All cells have the same size.
|
|
62
|
+
* @type {function(number,number):number} */
|
|
63
|
+
this.size = opts.size // (resolution, zf) => ...
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
68
|
+
* @param {number} r
|
|
69
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
70
|
+
*/
|
|
71
|
+
draw(cells, r, cg) {
|
|
72
|
+
//filter
|
|
73
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
74
|
+
|
|
75
|
+
//zoom factor
|
|
76
|
+
const zf = cg.getZf()
|
|
77
|
+
|
|
78
|
+
//compute color variable statistics
|
|
79
|
+
const statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
80
|
+
|
|
81
|
+
if (!statColor) return
|
|
82
|
+
|
|
83
|
+
//create canvas and webgl renderer
|
|
84
|
+
const cvWGL = makeWebGLCanvas(cg.w + '', cg.h + '')
|
|
85
|
+
if (!cvWGL) {
|
|
86
|
+
console.error('No webGL')
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//add vertice and fragment data
|
|
91
|
+
const r2 = r / 2
|
|
92
|
+
let c,
|
|
93
|
+
nb = cells.length
|
|
94
|
+
const verticesBuffer = []
|
|
95
|
+
//const tBuffer = []
|
|
96
|
+
for (let i = 0; i < nb; i++) {
|
|
97
|
+
c = cells[i]
|
|
98
|
+
const t = this.tFun(c[this.colorCol], r, statColor)
|
|
99
|
+
if (t == null || t == undefined) continue
|
|
100
|
+
verticesBuffer.push(c.x + r2, c.y + r2)
|
|
101
|
+
//tBuffer.push(t > 1 ? 1 : t < 0 ? 0 : t)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const sizeGeo = this.size ? this.size(r, zf) : r + 0.2 * zf
|
|
105
|
+
const wgp = new WebGLSquareColoringKS(cvWGL.gl, this.colors, this.stretching, sizeGeo / zf)
|
|
106
|
+
|
|
107
|
+
//TODO - [i,j,t]
|
|
108
|
+
let data = []
|
|
109
|
+
for (const c of cells) {
|
|
110
|
+
const xGL = cg.geoToPixX(c.x + r2) //TODO within [-1,1] ?
|
|
111
|
+
data.push(xGL)
|
|
112
|
+
const yGL = cg.geoToPixY(c.y + r2) //TODO within [-1,1] ?
|
|
113
|
+
data.push(yGL)
|
|
114
|
+
const t = this.tFun(c[this.colorCol], r, statColor)
|
|
115
|
+
data.push(t)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
data = [0.0, 2.0, 1.0, 0.0, 0.0, 0.0]
|
|
119
|
+
|
|
120
|
+
//draw
|
|
121
|
+
wgp.draw(verticesBuffer, data, cg.getWebGLTransform())
|
|
122
|
+
|
|
123
|
+
//draw in canvas geo
|
|
124
|
+
cg.initCanvasTransform()
|
|
125
|
+
cg.ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
126
|
+
|
|
127
|
+
//update legends
|
|
128
|
+
this.updateLegends({ style: this, r: r, zf: zf, sColor: statColor })
|
|
129
|
+
}
|
|
130
|
+
}
|