gridviz 3.0.28 → 3.0.29
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 +4 -1
- package/dist/gridviz.js +221 -111
- package/dist/gridviz.min.js +1 -1
- package/package.json +1 -1
- package/src/index.js +1 -2
- package/src/style/LegoStyle.js +30 -8
- package/src/style/ShadingStyle.js +4 -4
- package/src/style/SideTanakaStyle.js +142 -0
- package/src/style/{TanakaStyle.js → SideTanakaStyle___OLD.js} +1 -4
- package/src/utils/scale.js +15 -0
- package/src/style/ContourStyle.js +0 -21
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -24,10 +24,9 @@ export { TextStyle } from './style/TextStyle.js'
|
|
|
24
24
|
export { PillarStyle } from './style/PillarStyle.js'
|
|
25
25
|
export { SideStyle } from './style/SideStyle.js'
|
|
26
26
|
export { ShadingStyle } from './style/ShadingStyle.js'
|
|
27
|
-
//export { ContourStyle } from './style/ContourStyle.js'
|
|
28
27
|
export { SideCategoryStyle } from './style/SideCategoryStyle.js'
|
|
29
28
|
export { DotDensityStyle } from './style/DotDensityStyle.js'
|
|
30
|
-
export {
|
|
29
|
+
export { SideTanakaStyle } from './style/SideTanakaStyle.js'
|
|
31
30
|
export { LegoStyle } from './style/LegoStyle.js'
|
|
32
31
|
export { SquareColorWebGLStyle } from './style/SquareColorWebGLStyle.js'
|
|
33
32
|
export { SquareColorCategoryWebGLStyle } from './style/SquareColorCategoryWebGLStyle.js'
|
package/src/style/LegoStyle.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { TanakaStyle } from './
|
|
4
|
+
//import { TanakaStyle } from './SideTanakaStyle___OLD.js'
|
|
5
5
|
import { StrokeStyle } from './StrokeStyle.js'
|
|
6
6
|
import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.js'
|
|
7
7
|
import { Style } from '../core/Style.js'
|
|
8
|
+
//import { SideStyle } from './SideStyle.js'
|
|
9
|
+
import { classifier as clFun, colorClassifier as cclFun } from '../utils/scale.js'
|
|
10
|
+
import { SideTanakaStyle } from './SideTanakaStyle.js'
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
14
|
* @module style
|
|
@@ -30,12 +34,30 @@ export class LegoStyle {
|
|
|
30
34
|
//"#eee" //whithe
|
|
31
35
|
]*/
|
|
32
36
|
|
|
33
|
-
opts.
|
|
34
|
-
opts.
|
|
35
|
-
|
|
37
|
+
opts.colorDark = opts.colorDark || '#333'
|
|
38
|
+
opts.colorBright = opts.colorBright || '#aaa'
|
|
39
|
+
|
|
40
|
+
//make classifier
|
|
41
|
+
const classifier = clFun(breaks)
|
|
42
|
+
const classifier2 = cell => classifier(value(cell))
|
|
43
|
+
//make colors table
|
|
44
|
+
const colorsDict = {}
|
|
45
|
+
for (let i = 0; i < colors.length; i++) colorsDict[i + ''] = colors[i]
|
|
46
|
+
|
|
47
|
+
//make cell fill style
|
|
48
|
+
const cellStyle = new SquareColorCategoryWebGLStyle({
|
|
49
|
+
code: classifier2,
|
|
50
|
+
color: colorsDict,
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
//make tanaka side style
|
|
54
|
+
const tanakaStyle = new SideTanakaStyle({
|
|
55
|
+
classifier: () => classifier2,
|
|
56
|
+
colorDark : opts.colorDark,
|
|
57
|
+
colorBright : opts.colorBright,
|
|
58
|
+
diamond: opts.diamond,
|
|
59
|
+
})
|
|
36
60
|
|
|
37
|
-
//reuse tanaka as basis
|
|
38
|
-
const ts = TanakaStyle.get(value, breaks, colors, opts)
|
|
39
61
|
//style to show limits between pieces
|
|
40
62
|
const sst = new StrokeStyle({
|
|
41
63
|
strokeColor: () => '#666',
|
|
@@ -44,9 +66,9 @@ export class LegoStyle {
|
|
|
44
66
|
})
|
|
45
67
|
|
|
46
68
|
return [
|
|
47
|
-
|
|
69
|
+
cellStyle,
|
|
48
70
|
sst,
|
|
49
|
-
|
|
71
|
+
tanakaStyle,
|
|
50
72
|
new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright, filter: opts.filter }),
|
|
51
73
|
]
|
|
52
74
|
}
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
import { SideStyle } from './SideStyle.js'
|
|
5
5
|
import { max } from 'd3-array'
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
/** @typedef {{ x:number, y:number, or:"v"|"h", c1:(import('../core/Dataset.js').Cell)|undefined, c2:(import('../core/Dataset.js').Cell)|undefined }} Side */
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* @module style
|
|
@@ -28,7 +30,7 @@ export class ShadingStyle extends SideStyle {
|
|
|
28
30
|
const elevation = opts.elevation
|
|
29
31
|
|
|
30
32
|
// compute side value as elevation difference and attach to side
|
|
31
|
-
const sideValue = (side) => {
|
|
33
|
+
const sideValue = (/** @type {Side} */ side) => {
|
|
32
34
|
if (!side.c1) side.v = 0
|
|
33
35
|
else if (!side.c2) side.v = 0
|
|
34
36
|
else if (!side.c1[elevation]) side.v = 0
|
|
@@ -55,7 +57,5 @@ export class ShadingStyle extends SideStyle {
|
|
|
55
57
|
|
|
56
58
|
this.width = (_, r, z) => opts.width | Math.min(2 * z, r / 3)
|
|
57
59
|
this.diamond = opts.diamond
|
|
58
|
-
|
|
59
60
|
}
|
|
60
|
-
|
|
61
61
|
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../core/Style.js'
|
|
5
|
+
import { SideStyle } from './SideStyle.js'
|
|
6
|
+
|
|
7
|
+
/** @typedef {{ x:number, y:number, or:"v"|"h", c1:(import('../core/Dataset.js').Cell)|undefined, c2:(import('../core/Dataset.js').Cell)|undefined }} Side */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {function(Array.<Side>,number, number):*} SideViewScale */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @module style
|
|
14
|
+
* @author Julien Gaffuri
|
|
15
|
+
*/
|
|
16
|
+
export class SideTanakaStyle extends Style {
|
|
17
|
+
/** @param {object} opts */
|
|
18
|
+
constructor(opts = {}) {
|
|
19
|
+
super(opts)
|
|
20
|
+
|
|
21
|
+
/** A function returning the cells classifier.
|
|
22
|
+
* The cell classifier is a function that for each cell returns its class number (int).
|
|
23
|
+
*/
|
|
24
|
+
this.classifier = opts.classifier || ((cells, resolution, z) => c => 1)
|
|
25
|
+
|
|
26
|
+
/** A function returning the width of a cell side, in geo unit
|
|
27
|
+
* @type {function(Side, number, number, number, object):number} */
|
|
28
|
+
this.width = opts.width || ((side, sideValue, resolution, z, sidesScale) => Math.abs(sideValue) * Math.min(2 * z, resolution / 3))
|
|
29
|
+
|
|
30
|
+
/** A function returning the length of a cell side, in geo unit
|
|
31
|
+
* @type {function(Side, number, number, object):number} */
|
|
32
|
+
this.length = opts.length || ((side, resolution, z, sidesScale) => resolution)
|
|
33
|
+
|
|
34
|
+
// the dark color: for side facing away from light (coming from NW)
|
|
35
|
+
this.colorDark = opts.colorDark || '#111'
|
|
36
|
+
// the bright color: for side facing the light (coming from NW)
|
|
37
|
+
this.colorBright = opts.colorBright || '#ddd'
|
|
38
|
+
|
|
39
|
+
/** Set to A or true so that the side is drawn as a diamond */
|
|
40
|
+
this.diamond = opts.diamond
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {Array.<import("../core/Dataset.js").Cell>} cells
|
|
45
|
+
* @param {number} resolution
|
|
46
|
+
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
|
|
47
|
+
*/
|
|
48
|
+
draw(cells, geoCanvas, resolution) {
|
|
49
|
+
//filter
|
|
50
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
51
|
+
|
|
52
|
+
//
|
|
53
|
+
const z = geoCanvas.view.z
|
|
54
|
+
const ctx = geoCanvas.offscreenCtx
|
|
55
|
+
|
|
56
|
+
//get cell classifier
|
|
57
|
+
const classifier = this.classifier(cells, resolution, z)
|
|
58
|
+
|
|
59
|
+
//get side value: class change difference
|
|
60
|
+
const getSideValue = (/** @type {{ c1: Side; c2: Side; }} */ side) => {
|
|
61
|
+
const cl1 = side.c1 ? classifier(side.c1) : undefined
|
|
62
|
+
const cl2 = side.c2 ? classifier(side.c2) : undefined
|
|
63
|
+
if (cl1 === undefined && cl2 === undefined) return undefined
|
|
64
|
+
if (cl1 === undefined) return cl2
|
|
65
|
+
if (cl2 === undefined) return -cl1
|
|
66
|
+
return cl2 - cl1
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//build sides
|
|
70
|
+
//TODO build only those with different codes ?
|
|
71
|
+
/** @type {Array.<Side>} */
|
|
72
|
+
const sides = SideStyle.buildSides(cells, resolution)
|
|
73
|
+
if (sides.length == 0) return
|
|
74
|
+
|
|
75
|
+
//get side view scale
|
|
76
|
+
const viewScale = this.viewScale ? this.viewScale(sides, resolution, z) : undefined
|
|
77
|
+
|
|
78
|
+
//draw sides
|
|
79
|
+
ctx.lineCap = 'butt'
|
|
80
|
+
const r2 = resolution * 0.5
|
|
81
|
+
for (let side of sides) {
|
|
82
|
+
|
|
83
|
+
//get side value
|
|
84
|
+
const v = getSideValue(side)
|
|
85
|
+
if (v === undefined || v === 0) continue
|
|
86
|
+
|
|
87
|
+
//color
|
|
88
|
+
/** @type {string|undefined} */
|
|
89
|
+
const col = ((v < 0 && side.or === 'h') || (v > 0 && side.or === 'v')) ? this.colorBright : this.colorDark
|
|
90
|
+
if (!col || col == 'none') continue
|
|
91
|
+
|
|
92
|
+
if (this.diamond) {
|
|
93
|
+
//set color
|
|
94
|
+
ctx.fillStyle = col
|
|
95
|
+
|
|
96
|
+
//draw diamond
|
|
97
|
+
const x = side.x,
|
|
98
|
+
y = side.y
|
|
99
|
+
ctx.beginPath()
|
|
100
|
+
ctx.moveTo(x - r2, y)
|
|
101
|
+
ctx.lineTo(x, y + r2)
|
|
102
|
+
ctx.lineTo(x + r2, y)
|
|
103
|
+
ctx.lineTo(x, y - r2)
|
|
104
|
+
ctx.closePath()
|
|
105
|
+
ctx.fill()
|
|
106
|
+
} else {
|
|
107
|
+
//width
|
|
108
|
+
/** @type {number|undefined} */
|
|
109
|
+
const wG = this.width ? this.width(side, v, resolution, z, viewScale) : undefined
|
|
110
|
+
if (!wG || wG <= 0) continue
|
|
111
|
+
|
|
112
|
+
//length
|
|
113
|
+
/** @type {number|undefined} */
|
|
114
|
+
const lG = this.length ? this.length(side, resolution, z, viewScale) : undefined
|
|
115
|
+
if (!lG || lG <= 0) continue
|
|
116
|
+
const lG2 = lG * 0.5
|
|
117
|
+
|
|
118
|
+
//set width
|
|
119
|
+
ctx.lineWidth = wG
|
|
120
|
+
//set color
|
|
121
|
+
ctx.strokeStyle = col
|
|
122
|
+
|
|
123
|
+
//draw segment with correct orientation
|
|
124
|
+
const x = side.x,
|
|
125
|
+
y = side.y
|
|
126
|
+
ctx.beginPath()
|
|
127
|
+
if (side.or === 'v') {
|
|
128
|
+
ctx.moveTo(x, y - lG2)
|
|
129
|
+
ctx.lineTo(x, y + lG2)
|
|
130
|
+
} else {
|
|
131
|
+
ctx.moveTo(x - lG2, y)
|
|
132
|
+
ctx.lineTo(x + lG2, y)
|
|
133
|
+
}
|
|
134
|
+
ctx.stroke()
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//update legends
|
|
139
|
+
this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { SideStyle } from './SideStyle.js'
|
|
5
|
-
import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.js'
|
|
6
|
-
import { classifier as clFun, colorClassifier as cclFun } from '../utils/scale.js'
|
|
7
4
|
|
|
8
5
|
/**
|
|
9
6
|
* @see https://manifold.net/doc/mfd9/example__tanaka_contours.htm
|
|
@@ -17,7 +14,7 @@ export class TanakaStyle {
|
|
|
17
14
|
* @param {Array.<number>} breaks The break values
|
|
18
15
|
* @param {Array.<string>} colors The colors, one more than the break values
|
|
19
16
|
* @param {object} opts
|
|
20
|
-
* @returns {Array.<import("../core/Style").Style>}
|
|
17
|
+
* @returns {Array.<import("../core/Style.js").Style>}
|
|
21
18
|
*/
|
|
22
19
|
static get(value, breaks, colors, opts = {}) {
|
|
23
20
|
//shadow colors
|
package/src/utils/scale.js
CHANGED
|
@@ -168,6 +168,7 @@ export const viewScaleCombination = (obj) => {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
|
|
171
172
|
/**
|
|
172
173
|
* Return a classifier function from break values.
|
|
173
174
|
* The classifier function returns the class id (from 0 to breaks.length) from a value to classifiy.
|
|
@@ -188,6 +189,20 @@ export function classifier(breaks) {
|
|
|
188
189
|
return classifier
|
|
189
190
|
}
|
|
190
191
|
|
|
192
|
+
/**
|
|
193
|
+
* @param {number} min
|
|
194
|
+
* @param {number} max
|
|
195
|
+
* @param {number} nbClass
|
|
196
|
+
*/
|
|
197
|
+
export function classifierMinMax(min, max, nbClass) {
|
|
198
|
+
const breaks = []
|
|
199
|
+
const step = (max - min) / nbClass
|
|
200
|
+
for (let i = 1; i < nbClass; i++) breaks.push(min + i * step)
|
|
201
|
+
return classifier(breaks)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
191
206
|
/**
|
|
192
207
|
* Return a color classifier function from break values.
|
|
193
208
|
* The classifier function returns the color from a value to classifiy.
|
|
@@ -1,21 +0,0 @@
|
|
|
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
|
-
* @module style
|
|
11
|
-
* @author Julien Gaffuri
|
|
12
|
-
*/
|
|
13
|
-
export class ContourStyle extends SideStyle {
|
|
14
|
-
/** @param {object} opts */
|
|
15
|
-
constructor(opts) {
|
|
16
|
-
super(opts)
|
|
17
|
-
//opts = opts || {}
|
|
18
|
-
|
|
19
|
-
//TODO
|
|
20
|
-
}
|
|
21
|
-
}
|