gridviz 2.1.9 → 2.1.11
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 +8036 -8024
- package/dist/gridviz.min.js +1 -1
- package/package.json +77 -77
- package/src/App.js +705 -705
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +113 -101
- 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/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 +124 -124
- 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/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 +126 -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 +250 -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
package/src/style/PillarStyle.js
CHANGED
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../Style.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @author Julien Gaffuri
|
|
8
|
-
*/
|
|
9
|
-
export class PillarStyle extends Style {
|
|
10
|
-
//TODO make a webGL version ?
|
|
11
|
-
|
|
12
|
-
/** @param {object} opts */
|
|
13
|
-
constructor(opts) {
|
|
14
|
-
super(opts)
|
|
15
|
-
opts = opts || {}
|
|
16
|
-
|
|
17
|
-
/** @type {string} */
|
|
18
|
-
this.heightCol = opts.heightCol
|
|
19
|
-
|
|
20
|
-
/** A function returning the height of the line representing a cell, in geo unit
|
|
21
|
-
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
22
|
-
this.height = opts.height
|
|
23
|
-
|
|
24
|
-
/** @type {string} */
|
|
25
|
-
this.colorCol = opts.colorCol
|
|
26
|
-
|
|
27
|
-
/** A function returning the color of the line representing a cell.
|
|
28
|
-
* @type {function(number,number,import("../Style").Stat|undefined):string} */
|
|
29
|
-
this.color = opts.color || (() => '#c08c59') //bb
|
|
30
|
-
|
|
31
|
-
/** @type {string} */
|
|
32
|
-
this.widthCol = opts.widthCol
|
|
33
|
-
|
|
34
|
-
/** A function returning the width of the line representing a cell, in geo unit
|
|
35
|
-
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
36
|
-
this.width = opts.width || ((v, r) => 0.5 * r)
|
|
37
|
-
|
|
38
|
-
/** @type {boolean} */
|
|
39
|
-
this.simple = opts.simple == true
|
|
40
|
-
|
|
41
|
-
/** @type {number} */
|
|
42
|
-
this.viewHeightFactor = opts.viewHeightFactor || 1.5
|
|
43
|
-
//0,0 is the center
|
|
44
|
-
/** @type {number} */
|
|
45
|
-
this.viewSX = opts.viewSX == undefined ? 0 : opts.viewSX
|
|
46
|
-
/** @type {number} */
|
|
47
|
-
this.viewSY = opts.viewSY == undefined ? -0.5 : opts.viewSY
|
|
48
|
-
|
|
49
|
-
//TODO replace with sun location ?
|
|
50
|
-
/** @type {number} */
|
|
51
|
-
this.shadowDirection =
|
|
52
|
-
opts.shadowDirection == undefined ? (-40.3 * Math.PI) / 180.0 : opts.shadowDirection
|
|
53
|
-
/** @type {number} */
|
|
54
|
-
this.shadowFactor = opts.shadowFactor || 0.3
|
|
55
|
-
/** @type {string} */
|
|
56
|
-
this.shadowColor = opts.shadowColor || '#00000033'
|
|
57
|
-
|
|
58
|
-
/** @type {string} */
|
|
59
|
-
this.outlineCol = opts.outlineCol || '#FFFFFF'
|
|
60
|
-
/** @type {number} */
|
|
61
|
-
this.outlineWidthPix = opts.outlineWidthPix == undefined ? 0.5 : opts.outlineWidthPix
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Draw cells as segments.
|
|
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
|
-
let statHeight
|
|
79
|
-
if (this.heightCol) {
|
|
80
|
-
//compute size variable statistics
|
|
81
|
-
statHeight = Style.getStatistics(cells, (c) => c[this.heightCol], true)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
let statColor
|
|
85
|
-
if (this.colorCol) {
|
|
86
|
-
//compute color variable statistics
|
|
87
|
-
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
let statWidth
|
|
91
|
-
if (this.widthCol) {
|
|
92
|
-
//and compute size variable statistics
|
|
93
|
-
statWidth = Style.getStatistics(cells, (c) => c[this.widthCol], true)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
//get view center geo position
|
|
97
|
-
const cvx = cg.getCenter().x + this.viewSX * cg.w * zf
|
|
98
|
-
const cvy = cg.getCenter().y + this.viewSY * cg.h * zf
|
|
99
|
-
//get view height
|
|
100
|
-
const H = this.viewHeightFactor * (cg.w + cg.h) * 0.5 * zf
|
|
101
|
-
|
|
102
|
-
//sort cells by y and x
|
|
103
|
-
//const distToViewCenter = (c) => { const dx = cvx - c.x, dy = cvy - c.y; return Math.sqrt(dx * dx + dy * dy) }
|
|
104
|
-
cells.sort((c1, c2) => 100000000 * (c2.y - c1.y) + c1.x - c2.x)
|
|
105
|
-
|
|
106
|
-
cg.ctx.lineCap = this.simple ? 'butt' : 'round'
|
|
107
|
-
|
|
108
|
-
//draw in geo coordinates
|
|
109
|
-
cg.setCanvasTransform()
|
|
110
|
-
|
|
111
|
-
//draw shadows
|
|
112
|
-
cg.ctx.strokeStyle = this.shadowColor
|
|
113
|
-
cg.ctx.fillStyle = this.shadowColor
|
|
114
|
-
for (let c of cells) {
|
|
115
|
-
//width
|
|
116
|
-
/** @type {number|undefined} */
|
|
117
|
-
const wG = this.width ? this.width(c[this.widthCol], r, statWidth, zf) : undefined
|
|
118
|
-
if (!wG || wG < 0) continue
|
|
119
|
-
|
|
120
|
-
//height
|
|
121
|
-
/** @type {number|undefined} */
|
|
122
|
-
const hG = this.height ? this.height(c[this.heightCol], r, statHeight, zf) : undefined
|
|
123
|
-
if (!hG || hG < 0) continue
|
|
124
|
-
|
|
125
|
-
//get offset
|
|
126
|
-
//TODO use that
|
|
127
|
-
const offset = this.offset(c, r, zf)
|
|
128
|
-
|
|
129
|
-
//set width
|
|
130
|
-
cg.ctx.lineWidth = wG
|
|
131
|
-
|
|
132
|
-
//compute cell centre postition
|
|
133
|
-
const cx = c.x + r / 2
|
|
134
|
-
const cy = c.y + r / 2
|
|
135
|
-
const ls = hG * this.shadowFactor
|
|
136
|
-
|
|
137
|
-
//draw segment
|
|
138
|
-
cg.ctx.beginPath()
|
|
139
|
-
cg.ctx.moveTo(cx, cy)
|
|
140
|
-
cg.ctx.lineTo(cx + ls * Math.cos(this.shadowDirection), cy + ls * Math.sin(this.shadowDirection))
|
|
141
|
-
cg.ctx.stroke()
|
|
142
|
-
|
|
143
|
-
/*
|
|
144
|
-
if (this.simple) {
|
|
145
|
-
//draw base circle
|
|
146
|
-
cg.ctx.beginPath();
|
|
147
|
-
cg.ctx.arc(
|
|
148
|
-
cx, cy,
|
|
149
|
-
wG * 0.5,
|
|
150
|
-
0, 2 * Math.PI, false);
|
|
151
|
-
//cg.ctx.stroke();
|
|
152
|
-
cg.ctx.fill();
|
|
153
|
-
}*/
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
//draw pillars
|
|
157
|
-
for (let c of cells) {
|
|
158
|
-
//color
|
|
159
|
-
/** @type {string|undefined} */
|
|
160
|
-
const col = this.color ? this.color(c[this.colorCol], r, statColor) : undefined
|
|
161
|
-
if (!col) continue
|
|
162
|
-
|
|
163
|
-
//width
|
|
164
|
-
/** @type {number|undefined} */
|
|
165
|
-
const wG = this.width ? this.width(c[this.widthCol], r, statWidth, zf) : undefined
|
|
166
|
-
if (!wG || wG < 0) continue
|
|
167
|
-
|
|
168
|
-
//height
|
|
169
|
-
/** @type {number|undefined} */
|
|
170
|
-
const hG = this.height ? this.height(c[this.heightCol], r, statHeight, zf) : undefined
|
|
171
|
-
if (!hG || hG < 0) continue
|
|
172
|
-
|
|
173
|
-
//get offset
|
|
174
|
-
//TODO use that
|
|
175
|
-
const offset = this.offset(c, r, zf)
|
|
176
|
-
|
|
177
|
-
//compute cell centre postition
|
|
178
|
-
const cx = c.x + r / 2
|
|
179
|
-
const cy = c.y + r / 2
|
|
180
|
-
|
|
181
|
-
//compute angle
|
|
182
|
-
const dx = cx - cvx,
|
|
183
|
-
dy = cy - cvy
|
|
184
|
-
const a = Math.atan2(dy, dx)
|
|
185
|
-
const D = Math.sqrt(dx * dx + dy * dy)
|
|
186
|
-
const d = (D * hG) / (H - hG)
|
|
187
|
-
|
|
188
|
-
if (this.simple) {
|
|
189
|
-
//draw segment
|
|
190
|
-
cg.ctx.strokeStyle = col
|
|
191
|
-
cg.ctx.lineWidth = wG
|
|
192
|
-
cg.ctx.beginPath()
|
|
193
|
-
cg.ctx.moveTo(cx, cy)
|
|
194
|
-
cg.ctx.lineTo(cx + d * Math.cos(a), cy + d * Math.sin(a))
|
|
195
|
-
cg.ctx.stroke()
|
|
196
|
-
} else {
|
|
197
|
-
//draw background segment
|
|
198
|
-
cg.ctx.strokeStyle = this.outlineCol
|
|
199
|
-
cg.ctx.lineWidth = wG + 2 * this.outlineWidthPix * zf
|
|
200
|
-
cg.ctx.beginPath()
|
|
201
|
-
cg.ctx.moveTo(cx, cy)
|
|
202
|
-
cg.ctx.lineTo(cx + d * Math.cos(a), cy + d * Math.sin(a))
|
|
203
|
-
cg.ctx.stroke()
|
|
204
|
-
|
|
205
|
-
//draw segment
|
|
206
|
-
cg.ctx.strokeStyle = col
|
|
207
|
-
cg.ctx.lineWidth = wG
|
|
208
|
-
cg.ctx.beginPath()
|
|
209
|
-
cg.ctx.moveTo(cx, cy)
|
|
210
|
-
cg.ctx.lineTo(cx + d * Math.cos(a), cy + d * Math.sin(a))
|
|
211
|
-
cg.ctx.stroke()
|
|
212
|
-
|
|
213
|
-
//draw top circle
|
|
214
|
-
cg.ctx.strokeStyle = this.outlineCol
|
|
215
|
-
//cg.ctx.fillStyle = "#c08c59"
|
|
216
|
-
cg.ctx.lineWidth = this.outlineWidthPix * zf
|
|
217
|
-
cg.ctx.beginPath()
|
|
218
|
-
cg.ctx.arc(cx + d * Math.cos(a), cy + d * Math.sin(a), wG * 0.5, 0, 2 * Math.PI, false)
|
|
219
|
-
cg.ctx.stroke()
|
|
220
|
-
//cg.ctx.fill();
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
//in case...
|
|
225
|
-
cg.ctx.lineCap = 'butt'
|
|
226
|
-
|
|
227
|
-
//update legends
|
|
228
|
-
this.updateLegends({ style: this, r: r, zf: zf, sColor: statColor })
|
|
229
|
-
}
|
|
230
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../Style.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @author Julien Gaffuri
|
|
8
|
+
*/
|
|
9
|
+
export class PillarStyle extends Style {
|
|
10
|
+
//TODO make a webGL version ?
|
|
11
|
+
|
|
12
|
+
/** @param {object} opts */
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
super(opts)
|
|
15
|
+
opts = opts || {}
|
|
16
|
+
|
|
17
|
+
/** @type {string} */
|
|
18
|
+
this.heightCol = opts.heightCol
|
|
19
|
+
|
|
20
|
+
/** A function returning the height of the line representing a cell, in geo unit
|
|
21
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
22
|
+
this.height = opts.height
|
|
23
|
+
|
|
24
|
+
/** @type {string} */
|
|
25
|
+
this.colorCol = opts.colorCol
|
|
26
|
+
|
|
27
|
+
/** A function returning the color of the line representing a cell.
|
|
28
|
+
* @type {function(number,number,import("../Style").Stat|undefined):string} */
|
|
29
|
+
this.color = opts.color || (() => '#c08c59') //bb
|
|
30
|
+
|
|
31
|
+
/** @type {string} */
|
|
32
|
+
this.widthCol = opts.widthCol
|
|
33
|
+
|
|
34
|
+
/** A function returning the width of the line representing a cell, in geo unit
|
|
35
|
+
* @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
36
|
+
this.width = opts.width || ((v, r) => 0.5 * r)
|
|
37
|
+
|
|
38
|
+
/** @type {boolean} */
|
|
39
|
+
this.simple = opts.simple == true
|
|
40
|
+
|
|
41
|
+
/** @type {number} */
|
|
42
|
+
this.viewHeightFactor = opts.viewHeightFactor || 1.5
|
|
43
|
+
//0,0 is the center
|
|
44
|
+
/** @type {number} */
|
|
45
|
+
this.viewSX = opts.viewSX == undefined ? 0 : opts.viewSX
|
|
46
|
+
/** @type {number} */
|
|
47
|
+
this.viewSY = opts.viewSY == undefined ? -0.5 : opts.viewSY
|
|
48
|
+
|
|
49
|
+
//TODO replace with sun location ?
|
|
50
|
+
/** @type {number} */
|
|
51
|
+
this.shadowDirection =
|
|
52
|
+
opts.shadowDirection == undefined ? (-40.3 * Math.PI) / 180.0 : opts.shadowDirection
|
|
53
|
+
/** @type {number} */
|
|
54
|
+
this.shadowFactor = opts.shadowFactor || 0.3
|
|
55
|
+
/** @type {string} */
|
|
56
|
+
this.shadowColor = opts.shadowColor || '#00000033'
|
|
57
|
+
|
|
58
|
+
/** @type {string} */
|
|
59
|
+
this.outlineCol = opts.outlineCol || '#FFFFFF'
|
|
60
|
+
/** @type {number} */
|
|
61
|
+
this.outlineWidthPix = opts.outlineWidthPix == undefined ? 0.5 : opts.outlineWidthPix
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Draw cells as segments.
|
|
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
|
+
let statHeight
|
|
79
|
+
if (this.heightCol) {
|
|
80
|
+
//compute size variable statistics
|
|
81
|
+
statHeight = Style.getStatistics(cells, (c) => c[this.heightCol], true)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let statColor
|
|
85
|
+
if (this.colorCol) {
|
|
86
|
+
//compute color variable statistics
|
|
87
|
+
statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let statWidth
|
|
91
|
+
if (this.widthCol) {
|
|
92
|
+
//and compute size variable statistics
|
|
93
|
+
statWidth = Style.getStatistics(cells, (c) => c[this.widthCol], true)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
//get view center geo position
|
|
97
|
+
const cvx = cg.getCenter().x + this.viewSX * cg.w * zf
|
|
98
|
+
const cvy = cg.getCenter().y + this.viewSY * cg.h * zf
|
|
99
|
+
//get view height
|
|
100
|
+
const H = this.viewHeightFactor * (cg.w + cg.h) * 0.5 * zf
|
|
101
|
+
|
|
102
|
+
//sort cells by y and x
|
|
103
|
+
//const distToViewCenter = (c) => { const dx = cvx - c.x, dy = cvy - c.y; return Math.sqrt(dx * dx + dy * dy) }
|
|
104
|
+
cells.sort((c1, c2) => 100000000 * (c2.y - c1.y) + c1.x - c2.x)
|
|
105
|
+
|
|
106
|
+
cg.ctx.lineCap = this.simple ? 'butt' : 'round'
|
|
107
|
+
|
|
108
|
+
//draw in geo coordinates
|
|
109
|
+
cg.setCanvasTransform()
|
|
110
|
+
|
|
111
|
+
//draw shadows
|
|
112
|
+
cg.ctx.strokeStyle = this.shadowColor
|
|
113
|
+
cg.ctx.fillStyle = this.shadowColor
|
|
114
|
+
for (let c of cells) {
|
|
115
|
+
//width
|
|
116
|
+
/** @type {number|undefined} */
|
|
117
|
+
const wG = this.width ? this.width(c[this.widthCol], r, statWidth, zf) : undefined
|
|
118
|
+
if (!wG || wG < 0) continue
|
|
119
|
+
|
|
120
|
+
//height
|
|
121
|
+
/** @type {number|undefined} */
|
|
122
|
+
const hG = this.height ? this.height(c[this.heightCol], r, statHeight, zf) : undefined
|
|
123
|
+
if (!hG || hG < 0) continue
|
|
124
|
+
|
|
125
|
+
//get offset
|
|
126
|
+
//TODO use that
|
|
127
|
+
const offset = this.offset(c, r, zf)
|
|
128
|
+
|
|
129
|
+
//set width
|
|
130
|
+
cg.ctx.lineWidth = wG
|
|
131
|
+
|
|
132
|
+
//compute cell centre postition
|
|
133
|
+
const cx = c.x + r / 2
|
|
134
|
+
const cy = c.y + r / 2
|
|
135
|
+
const ls = hG * this.shadowFactor
|
|
136
|
+
|
|
137
|
+
//draw segment
|
|
138
|
+
cg.ctx.beginPath()
|
|
139
|
+
cg.ctx.moveTo(cx, cy)
|
|
140
|
+
cg.ctx.lineTo(cx + ls * Math.cos(this.shadowDirection), cy + ls * Math.sin(this.shadowDirection))
|
|
141
|
+
cg.ctx.stroke()
|
|
142
|
+
|
|
143
|
+
/*
|
|
144
|
+
if (this.simple) {
|
|
145
|
+
//draw base circle
|
|
146
|
+
cg.ctx.beginPath();
|
|
147
|
+
cg.ctx.arc(
|
|
148
|
+
cx, cy,
|
|
149
|
+
wG * 0.5,
|
|
150
|
+
0, 2 * Math.PI, false);
|
|
151
|
+
//cg.ctx.stroke();
|
|
152
|
+
cg.ctx.fill();
|
|
153
|
+
}*/
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
//draw pillars
|
|
157
|
+
for (let c of cells) {
|
|
158
|
+
//color
|
|
159
|
+
/** @type {string|undefined} */
|
|
160
|
+
const col = this.color ? this.color(c[this.colorCol], r, statColor) : undefined
|
|
161
|
+
if (!col) continue
|
|
162
|
+
|
|
163
|
+
//width
|
|
164
|
+
/** @type {number|undefined} */
|
|
165
|
+
const wG = this.width ? this.width(c[this.widthCol], r, statWidth, zf) : undefined
|
|
166
|
+
if (!wG || wG < 0) continue
|
|
167
|
+
|
|
168
|
+
//height
|
|
169
|
+
/** @type {number|undefined} */
|
|
170
|
+
const hG = this.height ? this.height(c[this.heightCol], r, statHeight, zf) : undefined
|
|
171
|
+
if (!hG || hG < 0) continue
|
|
172
|
+
|
|
173
|
+
//get offset
|
|
174
|
+
//TODO use that
|
|
175
|
+
const offset = this.offset(c, r, zf)
|
|
176
|
+
|
|
177
|
+
//compute cell centre postition
|
|
178
|
+
const cx = c.x + r / 2
|
|
179
|
+
const cy = c.y + r / 2
|
|
180
|
+
|
|
181
|
+
//compute angle
|
|
182
|
+
const dx = cx - cvx,
|
|
183
|
+
dy = cy - cvy
|
|
184
|
+
const a = Math.atan2(dy, dx)
|
|
185
|
+
const D = Math.sqrt(dx * dx + dy * dy)
|
|
186
|
+
const d = (D * hG) / (H - hG)
|
|
187
|
+
|
|
188
|
+
if (this.simple) {
|
|
189
|
+
//draw segment
|
|
190
|
+
cg.ctx.strokeStyle = col
|
|
191
|
+
cg.ctx.lineWidth = wG
|
|
192
|
+
cg.ctx.beginPath()
|
|
193
|
+
cg.ctx.moveTo(cx, cy)
|
|
194
|
+
cg.ctx.lineTo(cx + d * Math.cos(a), cy + d * Math.sin(a))
|
|
195
|
+
cg.ctx.stroke()
|
|
196
|
+
} else {
|
|
197
|
+
//draw background segment
|
|
198
|
+
cg.ctx.strokeStyle = this.outlineCol
|
|
199
|
+
cg.ctx.lineWidth = wG + 2 * this.outlineWidthPix * zf
|
|
200
|
+
cg.ctx.beginPath()
|
|
201
|
+
cg.ctx.moveTo(cx, cy)
|
|
202
|
+
cg.ctx.lineTo(cx + d * Math.cos(a), cy + d * Math.sin(a))
|
|
203
|
+
cg.ctx.stroke()
|
|
204
|
+
|
|
205
|
+
//draw segment
|
|
206
|
+
cg.ctx.strokeStyle = col
|
|
207
|
+
cg.ctx.lineWidth = wG
|
|
208
|
+
cg.ctx.beginPath()
|
|
209
|
+
cg.ctx.moveTo(cx, cy)
|
|
210
|
+
cg.ctx.lineTo(cx + d * Math.cos(a), cy + d * Math.sin(a))
|
|
211
|
+
cg.ctx.stroke()
|
|
212
|
+
|
|
213
|
+
//draw top circle
|
|
214
|
+
cg.ctx.strokeStyle = this.outlineCol
|
|
215
|
+
//cg.ctx.fillStyle = "#c08c59"
|
|
216
|
+
cg.ctx.lineWidth = this.outlineWidthPix * zf
|
|
217
|
+
cg.ctx.beginPath()
|
|
218
|
+
cg.ctx.arc(cx + d * Math.cos(a), cy + d * Math.sin(a), wG * 0.5, 0, 2 * Math.PI, false)
|
|
219
|
+
cg.ctx.stroke()
|
|
220
|
+
//cg.ctx.fill();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
//in case...
|
|
225
|
+
cg.ctx.lineCap = 'butt'
|
|
226
|
+
|
|
227
|
+
//update legends
|
|
228
|
+
this.updateLegends({ style: this, r: r, zf: zf, sColor: statColor })
|
|
229
|
+
}
|
|
230
|
+
}
|