gridviz 2.0.41 → 2.0.43
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 +7490 -7499
- package/dist/gridviz.min.js +1 -1
- package/package.json +76 -76
- package/src/App.js +642 -642
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +101 -101
- package/src/GeoCanvas.js +420 -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 -168
- 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/TiledGrid.js +264 -264
- package/src/index.js +176 -176
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +103 -105
- package/src/legend/ColorLegend.js +124 -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/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
package/src/style/MosaicStyle.js
CHANGED
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @author Julien Gaffuri
|
|
8
|
-
*/
|
|
9
|
-
export class MosaicStyle extends Style {
|
|
10
|
-
/** @param {object} opts */
|
|
11
|
-
constructor(opts) {
|
|
12
|
-
super(opts)
|
|
13
|
-
opts = opts || {}
|
|
14
|
-
|
|
15
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
16
|
-
* @type {string} */
|
|
17
|
-
this.colorCol = opts.colorCol
|
|
18
|
-
|
|
19
|
-
/** A function returning the color of the cell.
|
|
20
|
-
* @type {function(number,number,import("../Style").Stat|undefined):string} */
|
|
21
|
-
this.color = opts.color || (() => '#EA6BAC')
|
|
22
|
-
|
|
23
|
-
/** The mosaic factor, within [0,0.5]. Set to 0 for no mosaic effect. Set to 0.5 for strong mosaic effect.
|
|
24
|
-
* @type {number} */
|
|
25
|
-
this.mosaicFactor = opts.mosaicFactor || 0.15
|
|
26
|
-
|
|
27
|
-
/** The mosaic shadow factor, within [0,0.5]. Set to 0 for no mosaic shadow. Set to 0.5 for strong mosaic shadow.
|
|
28
|
-
* @type {number} */
|
|
29
|
-
this.shadowFactor = opts.shadowFactor || 0.2
|
|
30
|
-
|
|
31
|
-
/** The mosaic shadow color.
|
|
32
|
-
* @type {string} */
|
|
33
|
-
this.shadowColor = opts.shadowColor || '#555'
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
39
|
-
* @param {number} resolution
|
|
40
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
41
|
-
*/
|
|
42
|
-
draw(cells, resolution, cg) {
|
|
43
|
-
//filter
|
|
44
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
45
|
-
|
|
46
|
-
//zoom factor
|
|
47
|
-
const zf = cg.getZf()
|
|
48
|
-
|
|
49
|
-
let statColor
|
|
50
|
-
if (this.colorCol) {
|
|
51
|
-
//compute color variable statistics
|
|
52
|
-
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
//set stroke style, for shadow
|
|
56
|
-
cg.ctx.strokeStyle = this.shadowColor
|
|
57
|
-
cg.ctx.lineWidth = this.shadowFactor * resolution
|
|
58
|
-
cg.ctx.lineJoin = 'round'
|
|
59
|
-
cg.ctx.lineCap = 'butt'
|
|
60
|
-
|
|
61
|
-
//function to compute position mosaic effect
|
|
62
|
-
const d = resolution * this.mosaicFactor
|
|
63
|
-
const mosaic = () => {
|
|
64
|
-
return { x: Math.random() * d, y: Math.random() * d }
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
//draw with HTML canvas in geo coordinates
|
|
68
|
-
cg.setCanvasTransform()
|
|
69
|
-
|
|
70
|
-
for (let cell of cells) {
|
|
71
|
-
//set fill color
|
|
72
|
-
const col = this.color ? this.color(cell[this.colorCol], resolution, statColor) : undefined
|
|
73
|
-
if (!col || col === 'none') continue
|
|
74
|
-
cg.ctx.fillStyle = col
|
|
75
|
-
|
|
76
|
-
//get offset
|
|
77
|
-
const offset = this.offset(cell, resolution, zf)
|
|
78
|
-
|
|
79
|
-
//compute position mosaic effect
|
|
80
|
-
const ll = mosaic(),
|
|
81
|
-
ul = mosaic(),
|
|
82
|
-
lr = mosaic(),
|
|
83
|
-
ur = mosaic()
|
|
84
|
-
|
|
85
|
-
//stroke
|
|
86
|
-
if (this.shadowFactor > 0) {
|
|
87
|
-
cg.ctx.beginPath()
|
|
88
|
-
cg.ctx.moveTo(cell.x + offset.dx + ll.x, cell.y + offset.dy + ll.y)
|
|
89
|
-
cg.ctx.lineTo(cell.x + offset.dx + resolution - lr.x, cell.y + offset.dy + lr.y)
|
|
90
|
-
cg.ctx.lineTo(cell.x + offset.dx + resolution - ur.x, cell.y + offset.dy + resolution - ur.y)
|
|
91
|
-
cg.ctx.stroke()
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
//fill
|
|
95
|
-
|
|
96
|
-
cg.ctx.beginPath()
|
|
97
|
-
cg.ctx.moveTo(cell.x + offset.dx + ll.x, cell.y + offset.dy + ll.y)
|
|
98
|
-
cg.ctx.lineTo(cell.x + offset.dx + resolution - lr.x, cell.y + offset.dy + lr.y)
|
|
99
|
-
cg.ctx.lineTo(cell.x + offset.dx + resolution - ur.x, cell.y + offset.dy + resolution - ur.y)
|
|
100
|
-
cg.ctx.lineTo(cell.x + offset.dx + ul.x, cell.y + offset.dy + resolution - ul.y)
|
|
101
|
-
cg.ctx.fill()
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
//update legends
|
|
105
|
-
this.updateLegends({ style: this, r: resolution, zf: zf, sColor: statColor })
|
|
106
|
-
}
|
|
107
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @author Julien Gaffuri
|
|
8
|
+
*/
|
|
9
|
+
export class MosaicStyle extends Style {
|
|
10
|
+
/** @param {object} opts */
|
|
11
|
+
constructor(opts) {
|
|
12
|
+
super(opts)
|
|
13
|
+
opts = opts || {}
|
|
14
|
+
|
|
15
|
+
/** The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
16
|
+
* @type {string} */
|
|
17
|
+
this.colorCol = opts.colorCol
|
|
18
|
+
|
|
19
|
+
/** A function returning the color of the cell.
|
|
20
|
+
* @type {function(number,number,import("../Style").Stat|undefined):string} */
|
|
21
|
+
this.color = opts.color || (() => '#EA6BAC')
|
|
22
|
+
|
|
23
|
+
/** The mosaic factor, within [0,0.5]. Set to 0 for no mosaic effect. Set to 0.5 for strong mosaic effect.
|
|
24
|
+
* @type {number} */
|
|
25
|
+
this.mosaicFactor = opts.mosaicFactor || 0.15
|
|
26
|
+
|
|
27
|
+
/** The mosaic shadow factor, within [0,0.5]. Set to 0 for no mosaic shadow. Set to 0.5 for strong mosaic shadow.
|
|
28
|
+
* @type {number} */
|
|
29
|
+
this.shadowFactor = opts.shadowFactor || 0.2
|
|
30
|
+
|
|
31
|
+
/** The mosaic shadow color.
|
|
32
|
+
* @type {string} */
|
|
33
|
+
this.shadowColor = opts.shadowColor || '#555'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
39
|
+
* @param {number} resolution
|
|
40
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
41
|
+
*/
|
|
42
|
+
draw(cells, resolution, cg) {
|
|
43
|
+
//filter
|
|
44
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
45
|
+
|
|
46
|
+
//zoom factor
|
|
47
|
+
const zf = cg.getZf()
|
|
48
|
+
|
|
49
|
+
let statColor
|
|
50
|
+
if (this.colorCol) {
|
|
51
|
+
//compute color variable statistics
|
|
52
|
+
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//set stroke style, for shadow
|
|
56
|
+
cg.ctx.strokeStyle = this.shadowColor
|
|
57
|
+
cg.ctx.lineWidth = this.shadowFactor * resolution
|
|
58
|
+
cg.ctx.lineJoin = 'round'
|
|
59
|
+
cg.ctx.lineCap = 'butt'
|
|
60
|
+
|
|
61
|
+
//function to compute position mosaic effect
|
|
62
|
+
const d = resolution * this.mosaicFactor
|
|
63
|
+
const mosaic = () => {
|
|
64
|
+
return { x: Math.random() * d, y: Math.random() * d }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//draw with HTML canvas in geo coordinates
|
|
68
|
+
cg.setCanvasTransform()
|
|
69
|
+
|
|
70
|
+
for (let cell of cells) {
|
|
71
|
+
//set fill color
|
|
72
|
+
const col = this.color ? this.color(cell[this.colorCol], resolution, statColor) : undefined
|
|
73
|
+
if (!col || col === 'none') continue
|
|
74
|
+
cg.ctx.fillStyle = col
|
|
75
|
+
|
|
76
|
+
//get offset
|
|
77
|
+
const offset = this.offset(cell, resolution, zf)
|
|
78
|
+
|
|
79
|
+
//compute position mosaic effect
|
|
80
|
+
const ll = mosaic(),
|
|
81
|
+
ul = mosaic(),
|
|
82
|
+
lr = mosaic(),
|
|
83
|
+
ur = mosaic()
|
|
84
|
+
|
|
85
|
+
//stroke
|
|
86
|
+
if (this.shadowFactor > 0) {
|
|
87
|
+
cg.ctx.beginPath()
|
|
88
|
+
cg.ctx.moveTo(cell.x + offset.dx + ll.x, cell.y + offset.dy + ll.y)
|
|
89
|
+
cg.ctx.lineTo(cell.x + offset.dx + resolution - lr.x, cell.y + offset.dy + lr.y)
|
|
90
|
+
cg.ctx.lineTo(cell.x + offset.dx + resolution - ur.x, cell.y + offset.dy + resolution - ur.y)
|
|
91
|
+
cg.ctx.stroke()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//fill
|
|
95
|
+
|
|
96
|
+
cg.ctx.beginPath()
|
|
97
|
+
cg.ctx.moveTo(cell.x + offset.dx + ll.x, cell.y + offset.dy + ll.y)
|
|
98
|
+
cg.ctx.lineTo(cell.x + offset.dx + resolution - lr.x, cell.y + offset.dy + lr.y)
|
|
99
|
+
cg.ctx.lineTo(cell.x + offset.dx + resolution - ur.x, cell.y + offset.dy + resolution - ur.y)
|
|
100
|
+
cg.ctx.lineTo(cell.x + offset.dx + ul.x, cell.y + offset.dy + resolution - ul.y)
|
|
101
|
+
cg.ctx.fill()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//update legends
|
|
105
|
+
this.updateLegends({ style: this, r: resolution, zf: zf, sColor: statColor })
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
9
|
-
*/
|
|
10
|
-
export class NinjaStarStyle extends Style {
|
|
11
|
-
/** @param {object} opts */
|
|
12
|
-
constructor(opts) {
|
|
13
|
-
super(opts)
|
|
14
|
-
opts = opts || {}
|
|
15
|
-
|
|
16
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
17
|
-
* @type {string} */
|
|
18
|
-
this.colorCol = opts.colorCol
|
|
19
|
-
|
|
20
|
-
/** A function returning the color of the cell.
|
|
21
|
-
* @type {function(number,number,import("../Style").Stat|undefined,number):string} */
|
|
22
|
-
this.color = opts.color || (() => '#EA6BAC') //(v,r,s,zf) => {}
|
|
23
|
-
|
|
24
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for size.
|
|
25
|
-
* @type {string} */
|
|
26
|
-
this.sizeCol = opts.sizeCol
|
|
27
|
-
|
|
28
|
-
/** A function returning the size of a cell, within [0,1]:
|
|
29
|
-
* - 0, nothing shown
|
|
30
|
-
* - 1, entire square
|
|
31
|
-
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
32
|
-
this.size = opts.size
|
|
33
|
-
|
|
34
|
-
/** A function returning the shape.
|
|
35
|
-
* @type {function(import("../Dataset").Cell):string} */
|
|
36
|
-
this.shape = opts.shape || (() => 'o')
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
*
|
|
41
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
42
|
-
* @param {number} r
|
|
43
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
44
|
-
*/
|
|
45
|
-
draw(cells, r, cg) {
|
|
46
|
-
//filter
|
|
47
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
48
|
-
|
|
49
|
-
//zoom factor
|
|
50
|
-
const zf = cg.getZf()
|
|
51
|
-
|
|
52
|
-
let statSize
|
|
53
|
-
if (this.sizeCol) {
|
|
54
|
-
//if size is used, sort cells by size so that the biggest are drawn first
|
|
55
|
-
cells.sort((c1, c2) => c2[this.sizeCol] - c1[this.sizeCol])
|
|
56
|
-
//and compute size variable statistics
|
|
57
|
-
statSize = Style.getStatistics(cells, (c) => c[this.sizeCol], true)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
let statColor
|
|
61
|
-
if (this.colorCol) {
|
|
62
|
-
//compute color variable statistics
|
|
63
|
-
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
//draw with HTML canvas
|
|
67
|
-
//in geo coordinates
|
|
68
|
-
cg.setCanvasTransform()
|
|
69
|
-
|
|
70
|
-
const r2 = r * 0.5
|
|
71
|
-
for (let cell of cells) {
|
|
72
|
-
//color
|
|
73
|
-
const col = this.color ? this.color(cell[this.colorCol], r, statColor, zf) : undefined
|
|
74
|
-
if (!col || col === 'none') continue
|
|
75
|
-
cg.ctx.fillStyle = col
|
|
76
|
-
|
|
77
|
-
//shape
|
|
78
|
-
const shape = this.shape ? this.shape(cell) : 'o'
|
|
79
|
-
if (shape === 'none') continue
|
|
80
|
-
|
|
81
|
-
//size
|
|
82
|
-
/** @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
83
|
-
let s_ = this.size || (() => 0.5)
|
|
84
|
-
//size - in geo unit
|
|
85
|
-
const sG2 = s_(cell[this.sizeCol], r, statSize, zf) * r2
|
|
86
|
-
|
|
87
|
-
//get offset
|
|
88
|
-
const offset = this.offset(cell, r, zf)
|
|
89
|
-
|
|
90
|
-
//center position
|
|
91
|
-
const cx = cell.x + r2
|
|
92
|
-
const cy = cell.y + r2
|
|
93
|
-
|
|
94
|
-
if (shape === 'p') {
|
|
95
|
-
cg.ctx.beginPath()
|
|
96
|
-
cg.ctx.moveTo(cx, cy + r2)
|
|
97
|
-
cg.ctx.lineTo(cx + sG2, cy + sG2)
|
|
98
|
-
cg.ctx.lineTo(cx + r2, cy)
|
|
99
|
-
cg.ctx.lineTo(cx + sG2, cy - sG2)
|
|
100
|
-
cg.ctx.lineTo(cx, cy - r2)
|
|
101
|
-
cg.ctx.lineTo(cx - sG2, cy - sG2)
|
|
102
|
-
cg.ctx.lineTo(cx - r2, cy)
|
|
103
|
-
cg.ctx.lineTo(cx - sG2, cy + sG2)
|
|
104
|
-
cg.ctx.fill()
|
|
105
|
-
} else if (shape === 'o') {
|
|
106
|
-
cg.ctx.beginPath()
|
|
107
|
-
cg.ctx.moveTo(cx, cy + sG2)
|
|
108
|
-
cg.ctx.lineTo(cx + r2, cy + r2)
|
|
109
|
-
cg.ctx.lineTo(cx + sG2, cy)
|
|
110
|
-
cg.ctx.lineTo(cx + r2, cy - r2)
|
|
111
|
-
cg.ctx.lineTo(cx, cy - sG2)
|
|
112
|
-
cg.ctx.lineTo(cx - r2, cy - r2)
|
|
113
|
-
cg.ctx.lineTo(cx - sG2, cy)
|
|
114
|
-
cg.ctx.lineTo(cx - r2, cy + r2)
|
|
115
|
-
cg.ctx.fill()
|
|
116
|
-
} else {
|
|
117
|
-
throw new Error('Unexpected shape:' + shape)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
//update legends
|
|
122
|
-
this.updateLegends({ style: this, r: r, zf: zf, sSize: statSize, sColor: statColor })
|
|
123
|
-
}
|
|
124
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
9
|
+
*/
|
|
10
|
+
export class NinjaStarStyle extends Style {
|
|
11
|
+
/** @param {object} opts */
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
super(opts)
|
|
14
|
+
opts = opts || {}
|
|
15
|
+
|
|
16
|
+
/** The name of the column/attribute of the tabular data where to retrieve the variable for color.
|
|
17
|
+
* @type {string} */
|
|
18
|
+
this.colorCol = opts.colorCol
|
|
19
|
+
|
|
20
|
+
/** A function returning the color of the cell.
|
|
21
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):string} */
|
|
22
|
+
this.color = opts.color || (() => '#EA6BAC') //(v,r,s,zf) => {}
|
|
23
|
+
|
|
24
|
+
/** The name of the column/attribute of the tabular data where to retrieve the variable for size.
|
|
25
|
+
* @type {string} */
|
|
26
|
+
this.sizeCol = opts.sizeCol
|
|
27
|
+
|
|
28
|
+
/** A function returning the size of a cell, within [0,1]:
|
|
29
|
+
* - 0, nothing shown
|
|
30
|
+
* - 1, entire square
|
|
31
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
32
|
+
this.size = opts.size
|
|
33
|
+
|
|
34
|
+
/** A function returning the shape.
|
|
35
|
+
* @type {function(import("../Dataset").Cell):string} */
|
|
36
|
+
this.shape = opts.shape || (() => 'o')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
42
|
+
* @param {number} r
|
|
43
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
44
|
+
*/
|
|
45
|
+
draw(cells, r, cg) {
|
|
46
|
+
//filter
|
|
47
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
48
|
+
|
|
49
|
+
//zoom factor
|
|
50
|
+
const zf = cg.getZf()
|
|
51
|
+
|
|
52
|
+
let statSize
|
|
53
|
+
if (this.sizeCol) {
|
|
54
|
+
//if size is used, sort cells by size so that the biggest are drawn first
|
|
55
|
+
cells.sort((c1, c2) => c2[this.sizeCol] - c1[this.sizeCol])
|
|
56
|
+
//and compute size variable statistics
|
|
57
|
+
statSize = Style.getStatistics(cells, (c) => c[this.sizeCol], true)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let statColor
|
|
61
|
+
if (this.colorCol) {
|
|
62
|
+
//compute color variable statistics
|
|
63
|
+
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//draw with HTML canvas
|
|
67
|
+
//in geo coordinates
|
|
68
|
+
cg.setCanvasTransform()
|
|
69
|
+
|
|
70
|
+
const r2 = r * 0.5
|
|
71
|
+
for (let cell of cells) {
|
|
72
|
+
//color
|
|
73
|
+
const col = this.color ? this.color(cell[this.colorCol], r, statColor, zf) : undefined
|
|
74
|
+
if (!col || col === 'none') continue
|
|
75
|
+
cg.ctx.fillStyle = col
|
|
76
|
+
|
|
77
|
+
//shape
|
|
78
|
+
const shape = this.shape ? this.shape(cell) : 'o'
|
|
79
|
+
if (shape === 'none') continue
|
|
80
|
+
|
|
81
|
+
//size
|
|
82
|
+
/** @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
83
|
+
let s_ = this.size || (() => 0.5)
|
|
84
|
+
//size - in geo unit
|
|
85
|
+
const sG2 = s_(cell[this.sizeCol], r, statSize, zf) * r2
|
|
86
|
+
|
|
87
|
+
//get offset
|
|
88
|
+
const offset = this.offset(cell, r, zf)
|
|
89
|
+
|
|
90
|
+
//center position
|
|
91
|
+
const cx = cell.x + r2
|
|
92
|
+
const cy = cell.y + r2
|
|
93
|
+
|
|
94
|
+
if (shape === 'p') {
|
|
95
|
+
cg.ctx.beginPath()
|
|
96
|
+
cg.ctx.moveTo(cx, cy + r2)
|
|
97
|
+
cg.ctx.lineTo(cx + sG2, cy + sG2)
|
|
98
|
+
cg.ctx.lineTo(cx + r2, cy)
|
|
99
|
+
cg.ctx.lineTo(cx + sG2, cy - sG2)
|
|
100
|
+
cg.ctx.lineTo(cx, cy - r2)
|
|
101
|
+
cg.ctx.lineTo(cx - sG2, cy - sG2)
|
|
102
|
+
cg.ctx.lineTo(cx - r2, cy)
|
|
103
|
+
cg.ctx.lineTo(cx - sG2, cy + sG2)
|
|
104
|
+
cg.ctx.fill()
|
|
105
|
+
} else if (shape === 'o') {
|
|
106
|
+
cg.ctx.beginPath()
|
|
107
|
+
cg.ctx.moveTo(cx, cy + sG2)
|
|
108
|
+
cg.ctx.lineTo(cx + r2, cy + r2)
|
|
109
|
+
cg.ctx.lineTo(cx + sG2, cy)
|
|
110
|
+
cg.ctx.lineTo(cx + r2, cy - r2)
|
|
111
|
+
cg.ctx.lineTo(cx, cy - sG2)
|
|
112
|
+
cg.ctx.lineTo(cx - r2, cy - r2)
|
|
113
|
+
cg.ctx.lineTo(cx - sG2, cy)
|
|
114
|
+
cg.ctx.lineTo(cx - r2, cy + r2)
|
|
115
|
+
cg.ctx.fill()
|
|
116
|
+
} else {
|
|
117
|
+
throw new Error('Unexpected shape:' + shape)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
//update legends
|
|
122
|
+
this.updateLegends({ style: this, r: r, zf: zf, sSize: statSize, sColor: statColor })
|
|
123
|
+
}
|
|
124
|
+
}
|