gridviz 2.1.11 → 2.1.13
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 +125 -125
- package/dist/gridviz.js +8254 -7887
- package/dist/gridviz.min.js +1 -1
- package/package.json +77 -77
- package/src/App.js +758 -705
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +113 -113
- package/src/GeoCanvas.js +420 -420
- package/src/LabelLayer.js +190 -190
- package/src/Layer.js +103 -103
- package/src/Legend.js +86 -86
- package/src/LineLayer.js +150 -150
- package/src/Style.js +129 -129
- package/src/Tooltip.js +180 -180
- package/src/button/Button.js +54 -0
- package/src/button/FullscreenButton.js +98 -0
- package/src/button/ZoomButtons.js +72 -0
- 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/LGrid.js +54 -54
- package/src/dataset/TiledGrid.js +264 -264
- package/src/index.js +71 -71
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +103 -103
- package/src/legend/ColorLegend.js +128 -124
- package/src/legend/SegmentOrientationLegend.js +87 -87
- package/src/legend/SegmentWidthLegend.js +101 -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/IsoFenceStyle.js +262 -262
- 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 +125 -125
- package/src/style/PillarStyle.js +230 -230
- package/src/style/SegmentStyle.js +142 -142
- package/src/style/ShapeColorSizeStyle.js +152 -126
- package/src/style/SideCatStyle.js +172 -172
- package/src/style/SideStyle.js +216 -216
- 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/style/TimeSeriesStyle.js +259 -250
- 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,54 +1,54 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { SideStyle } from './SideStyle.js'
|
|
5
|
-
|
|
6
|
-
/** @typedef {{x:number,y:number,or:"v"|"h",value:number}} Side */
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @author Julien Gaffuri
|
|
11
|
-
*/
|
|
12
|
-
export class ContourStyle extends SideStyle {
|
|
13
|
-
/** @param {object} opts */
|
|
14
|
-
constructor(opts) {
|
|
15
|
-
super(opts)
|
|
16
|
-
opts = opts || {}
|
|
17
|
-
|
|
18
|
-
/** @type {number} */
|
|
19
|
-
//opts.interval = opts.interval || 100
|
|
20
|
-
|
|
21
|
-
/** @type {Array.<number>} */
|
|
22
|
-
opts.breaks = opts.breaks || [100, 1000, 10000, 100000, 1000000]
|
|
23
|
-
|
|
24
|
-
/** @type {function(Side,number,number):string} */
|
|
25
|
-
opts.width = opts.width || (() => 1) //(s, r, zf) => ...
|
|
26
|
-
|
|
27
|
-
/** @type {function(Side,number,number):string} */
|
|
28
|
-
opts.color = opts.color || (() => '#E7A935') //(s, r, zf) => ...
|
|
29
|
-
|
|
30
|
-
//override method for contour drawing
|
|
31
|
-
|
|
32
|
-
const getClass = function (v) {
|
|
33
|
-
if (v == undefined) return 0
|
|
34
|
-
for (let i = 0; i < opts.breaks.length; i++) if (v < opts.breaks[i]) return i
|
|
35
|
-
return opts.breaks.length
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
this.value = (v1, v2, r, s, zf) => {
|
|
39
|
-
//if (!v1 || !v2) return 0
|
|
40
|
-
return Math.abs(getClass(v2) - getClass(v1))
|
|
41
|
-
|
|
42
|
-
//check if v1 - v2 cross a contour line
|
|
43
|
-
//const r1 = Math.floor(v1 / opts.interval);
|
|
44
|
-
//const r2 = Math.floor(v2 / opts.interval);
|
|
45
|
-
//return Math.abs(r2 - r1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
//same color for all
|
|
49
|
-
this.color = (side, r, s, zf) => (side.value ? opts.color(side, r, zf) : undefined)
|
|
50
|
-
|
|
51
|
-
//width: multiple of
|
|
52
|
-
this.width = (side, r, s, zf) => side.value * zf * opts.width(side, r, zf)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { SideStyle } from './SideStyle.js'
|
|
5
|
+
|
|
6
|
+
/** @typedef {{x:number,y:number,or:"v"|"h",value:number}} Side */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @author Julien Gaffuri
|
|
11
|
+
*/
|
|
12
|
+
export class ContourStyle extends SideStyle {
|
|
13
|
+
/** @param {object} opts */
|
|
14
|
+
constructor(opts) {
|
|
15
|
+
super(opts)
|
|
16
|
+
opts = opts || {}
|
|
17
|
+
|
|
18
|
+
/** @type {number} */
|
|
19
|
+
//opts.interval = opts.interval || 100
|
|
20
|
+
|
|
21
|
+
/** @type {Array.<number>} */
|
|
22
|
+
opts.breaks = opts.breaks || [100, 1000, 10000, 100000, 1000000]
|
|
23
|
+
|
|
24
|
+
/** @type {function(Side,number,number):string} */
|
|
25
|
+
opts.width = opts.width || (() => 1) //(s, r, zf) => ...
|
|
26
|
+
|
|
27
|
+
/** @type {function(Side,number,number):string} */
|
|
28
|
+
opts.color = opts.color || (() => '#E7A935') //(s, r, zf) => ...
|
|
29
|
+
|
|
30
|
+
//override method for contour drawing
|
|
31
|
+
|
|
32
|
+
const getClass = function (v) {
|
|
33
|
+
if (v == undefined) return 0
|
|
34
|
+
for (let i = 0; i < opts.breaks.length; i++) if (v < opts.breaks[i]) return i
|
|
35
|
+
return opts.breaks.length
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
this.value = (v1, v2, r, s, zf) => {
|
|
39
|
+
//if (!v1 || !v2) return 0
|
|
40
|
+
return Math.abs(getClass(v2) - getClass(v1))
|
|
41
|
+
|
|
42
|
+
//check if v1 - v2 cross a contour line
|
|
43
|
+
//const r1 = Math.floor(v1 / opts.interval);
|
|
44
|
+
//const r2 = Math.floor(v2 / opts.interval);
|
|
45
|
+
//return Math.abs(r2 - r1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//same color for all
|
|
49
|
+
this.color = (side, r, s, zf) => (side.value ? opts.color(side, r, zf) : undefined)
|
|
50
|
+
|
|
51
|
+
//width: multiple of
|
|
52
|
+
this.width = (side, r, s, zf) => side.value * zf * opts.width(side, r, zf)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,156 +1,156 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
import { randomNormal } from 'd3-random'
|
|
6
|
-
import { checkWebGLSupport, makeWebGLCanvas } from '../utils/webGLUtils.js'
|
|
7
|
-
import { WebGLSquareColoring } from '../utils/WebGLSquareColoring.js'
|
|
8
|
-
import { color } from 'd3-color'
|
|
9
|
-
import { monitor, monitorDuration } from '../utils/Utils.js'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
* @author Julien Gaffuri
|
|
14
|
-
*/
|
|
15
|
-
export class DotDensityStyle extends Style {
|
|
16
|
-
/** @param {object} opts */
|
|
17
|
-
constructor(opts) {
|
|
18
|
-
super(opts)
|
|
19
|
-
opts = opts || {}
|
|
20
|
-
|
|
21
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for dot number.
|
|
22
|
-
* @type {string} */
|
|
23
|
-
this.nbCol = opts.nbCol
|
|
24
|
-
|
|
25
|
-
/** A function returning the number of dots for a cell value.
|
|
26
|
-
* @type {function(number,number,import("../Style").Stat,number):number} */
|
|
27
|
-
this.nb = opts.nb || ((v, r, s, zf) => (((0.3 * r * r) / (zf * zf)) * v) / s.max)
|
|
28
|
-
|
|
29
|
-
/** The color of the dots. Same color for all dots within a cell.
|
|
30
|
-
* @type {function(import("../Dataset").Cell):string} */
|
|
31
|
-
this.color = opts.color || (() => '#FF5733')
|
|
32
|
-
|
|
33
|
-
/** A function returning the size of the dots, in geo unit.
|
|
34
|
-
* @type {function(number,number):number} */
|
|
35
|
-
this.dotSize = opts.dotSize //|| ((r, zf) => ...
|
|
36
|
-
|
|
37
|
-
/** A function returning the sigma of the distribution from the resolution, in geo unit.
|
|
38
|
-
* @type {function(number,number):number} */
|
|
39
|
-
this.sigma = opts.sigma //|| ((r,zf) => ...
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Draw cells as text.
|
|
44
|
-
*
|
|
45
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
46
|
-
* @param {number} r
|
|
47
|
-
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
48
|
-
*/
|
|
49
|
-
draw(cells, r, cg) {
|
|
50
|
-
if (monitor) monitorDuration('*** DotDensityStyle draw')
|
|
51
|
-
|
|
52
|
-
//filter
|
|
53
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
54
|
-
|
|
55
|
-
//zoom factor
|
|
56
|
-
const zf = cg.getZf()
|
|
57
|
-
|
|
58
|
-
let stat
|
|
59
|
-
if (this.nbCol) stat = Style.getStatistics(cells, (c) => c[this.nbCol], true)
|
|
60
|
-
if (!stat) return
|
|
61
|
-
|
|
62
|
-
//size of the dots
|
|
63
|
-
const sGeo = this.dotSize ? this.dotSize(r, zf) : 2 * zf
|
|
64
|
-
|
|
65
|
-
//make random function
|
|
66
|
-
const sig = this.sigma ? this.sigma(r, zf) : r * 0.4
|
|
67
|
-
const rand = randomNormal(0, sig)
|
|
68
|
-
|
|
69
|
-
if (monitor) monitorDuration(' preparation')
|
|
70
|
-
|
|
71
|
-
if (checkWebGLSupport()) {
|
|
72
|
-
//create canvas and webgl renderer
|
|
73
|
-
const cvWGL = makeWebGLCanvas(cg.w + '', cg.h + '')
|
|
74
|
-
if (!cvWGL) {
|
|
75
|
-
console.error('No webGL')
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
//create webGL program
|
|
80
|
-
const prog = new WebGLSquareColoring(cvWGL.gl, sGeo / zf)
|
|
81
|
-
|
|
82
|
-
if (monitor) monitorDuration(' webgl creation')
|
|
83
|
-
|
|
84
|
-
const r2 = r / 2
|
|
85
|
-
|
|
86
|
-
let col, offset, nb, cx, cy, cc
|
|
87
|
-
for (let c of cells) {
|
|
88
|
-
//get color
|
|
89
|
-
col = this.color(c)
|
|
90
|
-
if (!col || col === 'none') continue
|
|
91
|
-
|
|
92
|
-
//get offset
|
|
93
|
-
offset = this.offset(c, r, zf)
|
|
94
|
-
|
|
95
|
-
//number of dots
|
|
96
|
-
nb = this.nb(c[this.nbCol], r, stat, zf)
|
|
97
|
-
|
|
98
|
-
//cell center
|
|
99
|
-
cx = c.x + offset.dx + r2
|
|
100
|
-
cy = c.y + offset.dy + r2
|
|
101
|
-
|
|
102
|
-
//convert color
|
|
103
|
-
cc = color(col)
|
|
104
|
-
if (!cc) return
|
|
105
|
-
|
|
106
|
-
//random points
|
|
107
|
-
for (let i = 0; i <= nb; i++)
|
|
108
|
-
prog.addPointData2(cx + rand(), cy + rand(), cc.r, cc.g, cc.b, cc.opacity)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (monitor) monitorDuration(' data preparation')
|
|
112
|
-
|
|
113
|
-
//draw
|
|
114
|
-
prog.draw(cg.getWebGLTransform())
|
|
115
|
-
|
|
116
|
-
if (monitor) monitorDuration(' webgl drawing')
|
|
117
|
-
|
|
118
|
-
//draw in canvas geo
|
|
119
|
-
cg.initCanvasTransform()
|
|
120
|
-
cg.ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
121
|
-
|
|
122
|
-
if (monitor) monitorDuration(' canvas drawing')
|
|
123
|
-
} else {
|
|
124
|
-
//draw with HTML canvas
|
|
125
|
-
|
|
126
|
-
//draw in geo coordinates
|
|
127
|
-
cg.setCanvasTransform()
|
|
128
|
-
|
|
129
|
-
for (let c of cells) {
|
|
130
|
-
//get color
|
|
131
|
-
const col = this.color(c)
|
|
132
|
-
if (!col || col === 'none') continue
|
|
133
|
-
//set color
|
|
134
|
-
cg.ctx.fillStyle = col
|
|
135
|
-
|
|
136
|
-
//get offset
|
|
137
|
-
const offset = this.offset(c, r, zf)
|
|
138
|
-
|
|
139
|
-
//number of dots
|
|
140
|
-
const nb = this.nb(c[this.nbCol], r, stat, zf)
|
|
141
|
-
|
|
142
|
-
//draw random dots
|
|
143
|
-
const cx = c.x + offset.dx + r / 2,
|
|
144
|
-
cy = c.y + offset.dy + r / 2
|
|
145
|
-
for (let i = 0; i <= nb; i++) {
|
|
146
|
-
cg.ctx.fillRect(cx + rand(), cy + rand(), sGeo, sGeo)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
//update legends
|
|
152
|
-
this.updateLegends({ style: this, r: r, zf: zf })
|
|
153
|
-
|
|
154
|
-
if (monitor) monitorDuration('*** DotDensityStyle end draw')
|
|
155
|
-
}
|
|
156
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
import { randomNormal } from 'd3-random'
|
|
6
|
+
import { checkWebGLSupport, makeWebGLCanvas } from '../utils/webGLUtils.js'
|
|
7
|
+
import { WebGLSquareColoring } from '../utils/WebGLSquareColoring.js'
|
|
8
|
+
import { color } from 'd3-color'
|
|
9
|
+
import { monitor, monitorDuration } from '../utils/Utils.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @author Julien Gaffuri
|
|
14
|
+
*/
|
|
15
|
+
export class DotDensityStyle extends Style {
|
|
16
|
+
/** @param {object} opts */
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
super(opts)
|
|
19
|
+
opts = opts || {}
|
|
20
|
+
|
|
21
|
+
/** The name of the column/attribute of the tabular data where to retrieve the variable for dot number.
|
|
22
|
+
* @type {string} */
|
|
23
|
+
this.nbCol = opts.nbCol
|
|
24
|
+
|
|
25
|
+
/** A function returning the number of dots for a cell value.
|
|
26
|
+
* @type {function(number,number,import("../Style").Stat,number):number} */
|
|
27
|
+
this.nb = opts.nb || ((v, r, s, zf) => (((0.3 * r * r) / (zf * zf)) * v) / s.max)
|
|
28
|
+
|
|
29
|
+
/** The color of the dots. Same color for all dots within a cell.
|
|
30
|
+
* @type {function(import("../Dataset").Cell):string} */
|
|
31
|
+
this.color = opts.color || (() => '#FF5733')
|
|
32
|
+
|
|
33
|
+
/** A function returning the size of the dots, in geo unit.
|
|
34
|
+
* @type {function(number,number):number} */
|
|
35
|
+
this.dotSize = opts.dotSize //|| ((r, zf) => ...
|
|
36
|
+
|
|
37
|
+
/** A function returning the sigma of the distribution from the resolution, in geo unit.
|
|
38
|
+
* @type {function(number,number):number} */
|
|
39
|
+
this.sigma = opts.sigma //|| ((r,zf) => ...
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Draw cells as text.
|
|
44
|
+
*
|
|
45
|
+
* @param {Array.<import("../Dataset").Cell>} cells
|
|
46
|
+
* @param {number} r
|
|
47
|
+
* @param {import("../GeoCanvas").GeoCanvas} cg
|
|
48
|
+
*/
|
|
49
|
+
draw(cells, r, cg) {
|
|
50
|
+
if (monitor) monitorDuration('*** DotDensityStyle draw')
|
|
51
|
+
|
|
52
|
+
//filter
|
|
53
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
54
|
+
|
|
55
|
+
//zoom factor
|
|
56
|
+
const zf = cg.getZf()
|
|
57
|
+
|
|
58
|
+
let stat
|
|
59
|
+
if (this.nbCol) stat = Style.getStatistics(cells, (c) => c[this.nbCol], true)
|
|
60
|
+
if (!stat) return
|
|
61
|
+
|
|
62
|
+
//size of the dots
|
|
63
|
+
const sGeo = this.dotSize ? this.dotSize(r, zf) : 2 * zf
|
|
64
|
+
|
|
65
|
+
//make random function
|
|
66
|
+
const sig = this.sigma ? this.sigma(r, zf) : r * 0.4
|
|
67
|
+
const rand = randomNormal(0, sig)
|
|
68
|
+
|
|
69
|
+
if (monitor) monitorDuration(' preparation')
|
|
70
|
+
|
|
71
|
+
if (checkWebGLSupport()) {
|
|
72
|
+
//create canvas and webgl renderer
|
|
73
|
+
const cvWGL = makeWebGLCanvas(cg.w + '', cg.h + '')
|
|
74
|
+
if (!cvWGL) {
|
|
75
|
+
console.error('No webGL')
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//create webGL program
|
|
80
|
+
const prog = new WebGLSquareColoring(cvWGL.gl, sGeo / zf)
|
|
81
|
+
|
|
82
|
+
if (monitor) monitorDuration(' webgl creation')
|
|
83
|
+
|
|
84
|
+
const r2 = r / 2
|
|
85
|
+
|
|
86
|
+
let col, offset, nb, cx, cy, cc
|
|
87
|
+
for (let c of cells) {
|
|
88
|
+
//get color
|
|
89
|
+
col = this.color(c)
|
|
90
|
+
if (!col || col === 'none') continue
|
|
91
|
+
|
|
92
|
+
//get offset
|
|
93
|
+
offset = this.offset(c, r, zf)
|
|
94
|
+
|
|
95
|
+
//number of dots
|
|
96
|
+
nb = this.nb(c[this.nbCol], r, stat, zf)
|
|
97
|
+
|
|
98
|
+
//cell center
|
|
99
|
+
cx = c.x + offset.dx + r2
|
|
100
|
+
cy = c.y + offset.dy + r2
|
|
101
|
+
|
|
102
|
+
//convert color
|
|
103
|
+
cc = color(col)
|
|
104
|
+
if (!cc) return
|
|
105
|
+
|
|
106
|
+
//random points
|
|
107
|
+
for (let i = 0; i <= nb; i++)
|
|
108
|
+
prog.addPointData2(cx + rand(), cy + rand(), cc.r, cc.g, cc.b, cc.opacity)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (monitor) monitorDuration(' data preparation')
|
|
112
|
+
|
|
113
|
+
//draw
|
|
114
|
+
prog.draw(cg.getWebGLTransform())
|
|
115
|
+
|
|
116
|
+
if (monitor) monitorDuration(' webgl drawing')
|
|
117
|
+
|
|
118
|
+
//draw in canvas geo
|
|
119
|
+
cg.initCanvasTransform()
|
|
120
|
+
cg.ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
121
|
+
|
|
122
|
+
if (monitor) monitorDuration(' canvas drawing')
|
|
123
|
+
} else {
|
|
124
|
+
//draw with HTML canvas
|
|
125
|
+
|
|
126
|
+
//draw in geo coordinates
|
|
127
|
+
cg.setCanvasTransform()
|
|
128
|
+
|
|
129
|
+
for (let c of cells) {
|
|
130
|
+
//get color
|
|
131
|
+
const col = this.color(c)
|
|
132
|
+
if (!col || col === 'none') continue
|
|
133
|
+
//set color
|
|
134
|
+
cg.ctx.fillStyle = col
|
|
135
|
+
|
|
136
|
+
//get offset
|
|
137
|
+
const offset = this.offset(c, r, zf)
|
|
138
|
+
|
|
139
|
+
//number of dots
|
|
140
|
+
const nb = this.nb(c[this.nbCol], r, stat, zf)
|
|
141
|
+
|
|
142
|
+
//draw random dots
|
|
143
|
+
const cx = c.x + offset.dx + r / 2,
|
|
144
|
+
cy = c.y + offset.dy + r / 2
|
|
145
|
+
for (let i = 0; i <= nb; i++) {
|
|
146
|
+
cg.ctx.fillRect(cx + rand(), cy + rand(), sGeo, sGeo)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//update legends
|
|
152
|
+
this.updateLegends({ style: this, r: r, zf: zf })
|
|
153
|
+
|
|
154
|
+
if (monitor) monitorDuration('*** DotDensityStyle end draw')
|
|
155
|
+
}
|
|
156
|
+
}
|