gridviz 2.1.6 → 2.1.8
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 +1 -0
- package/dist/gridviz.js +70 -48
- package/dist/gridviz.min.js +1 -1
- package/package.json +2 -2
- package/src/style/IsoFenceStyle.js +71 -49
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gridviz",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "Visualization tool for gridded statistics",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"statistics",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"start-dev": "webpack --config webpack.config.dev.cjs",
|
|
42
42
|
"server": "webpack serve -c webpack.config.dev.js --static ./",
|
|
43
43
|
"doc": "./node_modules/.bin/jsdoc src/ src/dataset src/legend src/style -d docs/jsdoc",
|
|
44
|
-
"
|
|
44
|
+
"bp": "webpack --config webpack.config.prod.cjs",
|
|
45
45
|
"test": "jest"
|
|
46
46
|
},
|
|
47
47
|
"files": [
|
|
@@ -30,15 +30,25 @@ export class IsoFenceStyle extends Style {
|
|
|
30
30
|
|
|
31
31
|
/** The perspective angle.
|
|
32
32
|
* @type {number} */
|
|
33
|
-
this.angle = opts.angle != undefined ? opts.angle :
|
|
33
|
+
this.angle = opts.angle != undefined ? opts.angle : 50
|
|
34
34
|
|
|
35
35
|
/** A function returning the corner line stroke style.
|
|
36
36
|
* @type {function(import('../Dataset.js').Cell,number,number,number):string} */
|
|
37
|
-
this.cornerLineStrokeColor = opts.cornerLineStrokeColor || ((c, r, zf, angle) => "#
|
|
37
|
+
this.cornerLineStrokeColor = opts.cornerLineStrokeColor || ((c, r, zf, angle) => "#999")
|
|
38
38
|
|
|
39
39
|
/** A function returning the corner line width.
|
|
40
40
|
* @type {function(import('../Dataset.js').Cell,number,number,number):number} */
|
|
41
41
|
this.cornerLineWidth = opts.cornerLineWidth || ((c, r, zf, angle) => (angle % 90 == 0 ? 0 : 0.8 * zf))
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Show vertical cross-sections.
|
|
45
|
+
* @type {boolean} */
|
|
46
|
+
this.sVert = opts.sVert != undefined ? opts.sVert : true
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Show horizontal cross-sections.
|
|
50
|
+
* @type {boolean} */
|
|
51
|
+
this.sHor = opts.sHor != undefined ? opts.sHor : true
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
/**
|
|
@@ -72,6 +82,10 @@ export class IsoFenceStyle extends Style {
|
|
|
72
82
|
//half resolution
|
|
73
83
|
const r2 = r / 2
|
|
74
84
|
|
|
85
|
+
//get offset
|
|
86
|
+
// @ts-ignore
|
|
87
|
+
const offset = this.offset(undefined, r, zf), dx = offset.dx, dy = offset.dy
|
|
88
|
+
|
|
75
89
|
//height
|
|
76
90
|
/** @type {function(number,number,import("../Style").Stat|undefined,number):number} */
|
|
77
91
|
let h_ = this.height
|
|
@@ -80,46 +94,50 @@ export class IsoFenceStyle extends Style {
|
|
|
80
94
|
/** @type {Array.<Side>} */
|
|
81
95
|
const sides = []
|
|
82
96
|
|
|
83
|
-
//make horizontal sides
|
|
97
|
+
//make horizontal sides - except when angle%180=0
|
|
84
98
|
//sort cells by x and y
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
let
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
if (this.angle % 180 != 90 && this.sVert) {
|
|
100
|
+
cells.sort((c1, c2) => (c2.x == c1.x ? c1.y - c2.y : c1.x - c2.x))
|
|
101
|
+
let c1 = cells[0]
|
|
102
|
+
for (let i = 1; i < cells.length; i++) {
|
|
103
|
+
let c2 = cells[i]
|
|
104
|
+
|
|
105
|
+
if ((c1.y + r == c2.y) && (c1.x == c2.x))
|
|
106
|
+
//cells in same column and touch along horizontal side
|
|
107
|
+
//make shared side
|
|
108
|
+
sides.push({ x: c1.x + r2, y: c2.y, or: 'h', c1: c1, c2: c2 })
|
|
109
|
+
else {
|
|
110
|
+
//cells do not touch along horizontal side
|
|
111
|
+
//make two sides: top one for c1, bottom for c2
|
|
112
|
+
sides.push({ x: c1.x + r2, y: c1.y + r, or: 'h', c1: c1, c2: undefined })
|
|
113
|
+
sides.push({ x: c2.x + r2, y: c2.y, or: 'h', c1: undefined, c2: c2 })
|
|
114
|
+
}
|
|
100
115
|
|
|
101
|
-
|
|
116
|
+
c1 = c2
|
|
117
|
+
}
|
|
102
118
|
}
|
|
103
119
|
|
|
104
|
-
//make vertical sides
|
|
120
|
+
//make vertical sides - except when angle%180=90
|
|
105
121
|
//sort cells by y and x
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
let
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
if (this.angle % 180 != 0 && this.sHor) {
|
|
123
|
+
cells.sort((c1, c2) => (c2.y == c1.y ? c1.x - c2.x : c1.y - c2.y))
|
|
124
|
+
let c1 = cells[0]
|
|
125
|
+
for (let i = 1; i < cells.length; i++) {
|
|
126
|
+
let c2 = cells[i]
|
|
127
|
+
|
|
128
|
+
if ((c1.x + r == c2.x) && (c1.y == c2.y))
|
|
129
|
+
//cells in same row and touch along vertical side
|
|
130
|
+
//make shared side
|
|
131
|
+
sides.push({ x: c2.x, y: c1.y + r2, or: 'v', c1: c1, c2: c2 })
|
|
132
|
+
else {
|
|
133
|
+
//cells do not touch along vertical side
|
|
134
|
+
//make two sides: right one for c1, left for c2
|
|
135
|
+
sides.push({ x: c1.x + r, y: c1.y + r2, or: 'v', c1: c1, c2: undefined })
|
|
136
|
+
sides.push({ x: c2.x, y: c2.y + r2, or: 'v', c1: undefined, c2: c2 })
|
|
137
|
+
}
|
|
121
138
|
|
|
122
|
-
|
|
139
|
+
c1 = c2
|
|
140
|
+
}
|
|
123
141
|
}
|
|
124
142
|
|
|
125
143
|
//
|
|
@@ -176,23 +194,23 @@ export class IsoFenceStyle extends Style {
|
|
|
176
194
|
if (s.or == "h") {
|
|
177
195
|
//horizontal side - vertical section
|
|
178
196
|
//bottom left
|
|
179
|
-
cg.ctx.moveTo(s.x + h1 * cos, s.y - r2 + h1 * sin)
|
|
197
|
+
cg.ctx.moveTo(s.x + h1 * cos + dx, s.y - r2 + h1 * sin + dy)
|
|
180
198
|
//top left
|
|
181
|
-
cg.ctx.lineTo(s.x + h2 * cos, s.y + r2 + h2 * sin)
|
|
199
|
+
cg.ctx.lineTo(s.x + h2 * cos + dx, s.y + r2 + h2 * sin + dy)
|
|
182
200
|
//top right
|
|
183
|
-
cg.ctx.lineTo(s.x + h2n * cos, s.y + r2 + h2n * sin)
|
|
201
|
+
cg.ctx.lineTo(s.x + h2n * cos + dx, s.y + r2 + h2n * sin + dy)
|
|
184
202
|
//bottom right
|
|
185
|
-
cg.ctx.lineTo(s.x + h1n * cos, s.y - r2 + h1n * sin)
|
|
203
|
+
cg.ctx.lineTo(s.x + h1n * cos + dx, s.y - r2 + h1n * sin + dy)
|
|
186
204
|
} else {
|
|
187
205
|
//vertical side - horizontal section
|
|
188
206
|
//bottom left
|
|
189
|
-
cg.ctx.moveTo(s.x - r2 + h1 * cos, s.y + h1 * sin)
|
|
207
|
+
cg.ctx.moveTo(s.x - r2 + h1 * cos + dx, s.y + h1 * sin + dy)
|
|
190
208
|
//bottom right
|
|
191
|
-
cg.ctx.lineTo(s.x + r2 + h2 * cos, s.y + h2 * sin)
|
|
209
|
+
cg.ctx.lineTo(s.x + r2 + h2 * cos + dx, s.y + h2 * sin + dy)
|
|
192
210
|
//top right
|
|
193
|
-
cg.ctx.lineTo(s.x + r2 + h2n * cos, s.y + h2n * sin)
|
|
211
|
+
cg.ctx.lineTo(s.x + r2 + h2n * cos + dx, s.y + h2n * sin + dy)
|
|
194
212
|
//top left
|
|
195
|
-
cg.ctx.lineTo(s.x - r2 + h1n * cos, s.y + h1n * sin)
|
|
213
|
+
cg.ctx.lineTo(s.x - r2 + h1n * cos + dx, s.y + h1n * sin + dy)
|
|
196
214
|
}
|
|
197
215
|
cg.ctx.closePath()
|
|
198
216
|
|
|
@@ -208,15 +226,19 @@ export class IsoFenceStyle extends Style {
|
|
|
208
226
|
|
|
209
227
|
//draw corner lines
|
|
210
228
|
for (let c of cells) {
|
|
211
|
-
//height - in geo
|
|
212
|
-
const hG = h_(c[this.heightCol], r, stat, zf)
|
|
213
229
|
|
|
230
|
+
//line style
|
|
231
|
+
const lw = this.cornerLineWidth ? this.cornerLineWidth(c, r, zf, this.angle) : 0.8 * zf
|
|
232
|
+
if (lw == 0) continue
|
|
214
233
|
cg.ctx.strokeStyle = this.cornerLineStrokeColor ? this.cornerLineStrokeColor(c, r, zf, this.angle) : "#333"
|
|
215
|
-
cg.ctx.lineWidth =
|
|
234
|
+
cg.ctx.lineWidth = lw
|
|
235
|
+
|
|
236
|
+
//height - in geo
|
|
237
|
+
const hG = h_(c[this.heightCol], r, stat, zf)
|
|
216
238
|
|
|
217
239
|
cg.ctx.beginPath()
|
|
218
|
-
cg.ctx.moveTo(c.x + r2, c.y + r2)
|
|
219
|
-
cg.ctx.lineTo(c.x + r2 + hG * cos, c.y + r2 + hG * sin)
|
|
240
|
+
cg.ctx.moveTo(c.x + r2 + dx, c.y + r2 + dy)
|
|
241
|
+
cg.ctx.lineTo(c.x + r2 + hG * cos + dx, c.y + r2 + hG * sin + dy)
|
|
220
242
|
cg.ctx.closePath()
|
|
221
243
|
cg.ctx.stroke()
|
|
222
244
|
}
|