gridviz 3.0.35 → 3.0.37
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 +129 -129
- package/dist/gridviz.js +21056 -17487
- package/dist/gridviz.min.js +2 -2
- package/package.json +74 -74
- package/src/button/Button.js +67 -67
- package/src/button/FullscreenButton.js +121 -121
- package/src/button/ZoomButtons.js +103 -103
- package/src/core/Dataset.js +232 -154
- package/src/core/Drawable.js +78 -78
- package/src/core/GeoCanvas.js +443 -443
- package/src/core/Layer.js +23 -23
- package/src/core/Legend.js +108 -108
- package/src/core/Map.js +650 -568
- package/src/core/MultiResolutionDataset.js +93 -93
- package/src/core/Style.js +98 -98
- package/src/core/Tooltip.js +182 -182
- package/src/dataset/COGeo.js +25 -25
- package/src/dataset/CSVGrid.js +112 -112
- package/src/dataset/GeoTIFF.js +122 -122
- package/src/dataset/JSGrid.js +55 -55
- package/src/dataset/TiledGrid.js +311 -302
- package/src/dataset/worker.js +18 -18
- package/src/index.js +79 -79
- package/src/layer/BackgroundLayer.js +173 -173
- package/src/layer/BackgroundLayerImage.js +81 -81
- package/src/layer/BackgroundLayerWMS.js +104 -104
- package/src/layer/GeoJSONLayer.js +276 -276
- package/src/layer/GridLayer.js +166 -166
- package/src/layer/LabelLayer.js +194 -194
- package/src/legend/ColorCategoryLegend.js +109 -109
- package/src/legend/ColorDiscreteLegend.js +100 -100
- package/src/legend/ColorLegend.js +115 -115
- package/src/legend/OrientationLegend.js +89 -89
- package/src/legend/SizeLegend.js +224 -224
- package/src/legend/TernaryLegend.js +302 -302
- package/src/style/CompositionStyle.js +291 -291
- package/src/style/DotDensityStyle.js +133 -133
- package/src/style/ImageStyle.js +100 -100
- package/src/style/Interpolator.js +258 -258
- package/src/style/IsoFenceStyle.js +217 -217
- package/src/style/JoyPlotStyle.js +180 -180
- package/src/style/LegoStyle.js +132 -132
- package/src/style/MosaicStyle.js +99 -99
- package/src/style/NinjaStarStyle.js +102 -102
- package/src/style/PillarStyle.js +207 -207
- package/src/style/SegmentStyle.js +105 -105
- package/src/style/ShadingRayStyle.js +280 -280
- package/src/style/ShadingStyle.js +72 -72
- package/src/style/ShapeColorSizeStyle.js +147 -147
- package/src/style/SideCategoryStyle.js +112 -112
- package/src/style/SideStyle.js +217 -217
- package/src/style/SideTanakaStyle.js +154 -154
- package/src/style/SquareColorCategoryWebGLStyle.js +311 -294
- package/src/style/SquareColorWebGLStyle.js +126 -126
- package/src/style/StrokeStyle.js +135 -135
- package/src/style/TextStyle.js +110 -110
- package/src/style/TimeSeriesStyle.js +222 -222
- package/src/utils/WebGLRectangleColoring.js +106 -106
- package/src/utils/WebGLSquareColoring.js +114 -118
- package/src/utils/WebGLSquareColoringAdvanced.js +223 -227
- package/src/utils/WebGLSquareColoringKS.js +153 -153
- package/src/utils/scale.js +255 -255
- package/src/utils/stretching.js +120 -120
- package/src/utils/ternary.js +208 -208
- package/src/utils/utils.js +125 -125
- package/src/utils/webGLUtils.js +178 -73
- package/src/utils/zoomUtils.js +142 -142
|
@@ -1,180 +1,180 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../core/Style.js'
|
|
5
|
-
import { cellsToGrid } from '../utils/utils.js'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @module style
|
|
9
|
-
* @author Julien Gaffuri
|
|
10
|
-
*/
|
|
11
|
-
export class JoyPlotStyle extends Style {
|
|
12
|
-
/** @param {object} opts */
|
|
13
|
-
constructor(opts) {
|
|
14
|
-
super(opts)
|
|
15
|
-
opts = opts || {}
|
|
16
|
-
|
|
17
|
-
/** A function returning the height of a cell in geographical unit.
|
|
18
|
-
* @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
|
|
19
|
-
this.height = opts.height || ((c, r) => r * Math.random()) //(c,r,z,vs) => {}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
23
|
-
this.lineColor = opts.lineColor || ((y, ys, r, z) => '#BBB')
|
|
24
|
-
/**
|
|
25
|
-
* @type {function(number,{min:number, max:number},number,number):number} */
|
|
26
|
-
this.lineWidth = opts.lineWidth || ((y, ys, r, z) => z)
|
|
27
|
-
/**
|
|
28
|
-
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
29
|
-
this.fillColor = opts.fillColor || ((y, ys, r, z) => '#c08c5968')
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @param {Array.<import("../core/Dataset.js").Cell>} cells
|
|
34
|
-
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
|
|
35
|
-
* @param {number} resolution
|
|
36
|
-
* @override
|
|
37
|
-
*/
|
|
38
|
-
draw(cells, geoCanvas, resolution) {
|
|
39
|
-
//filter
|
|
40
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
const z = geoCanvas.view.z
|
|
44
|
-
const ctx = geoCanvas.offscreenCtx
|
|
45
|
-
|
|
46
|
-
//get view scale
|
|
47
|
-
const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
|
|
48
|
-
|
|
49
|
-
//index cells by y and x
|
|
50
|
-
/** @type {object} */
|
|
51
|
-
const ind = cellsToGrid(cells, cell => this.height(cell, resolution, z, viewScale))
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//make grid
|
|
55
|
-
/** @type {object} */
|
|
56
|
-
/*const grid = cellsToGrid2(cells, resolution, cell => this.height(cell, resolution, z, viewScale))
|
|
57
|
-
if (!grid.maxI || !grid.maxJ) return
|
|
58
|
-
|
|
59
|
-
//TODO
|
|
60
|
-
const ys = { min: grid.y0 + resolution * grid.minI, max: grid.y0 + resolution * grid.maxI }
|
|
61
|
-
|
|
62
|
-
//draw lines, row by row, stating from the top
|
|
63
|
-
ctx.lineJoin = 'round'
|
|
64
|
-
for (let i = grid.minI; i <= grid.maxI; i++) {
|
|
65
|
-
|
|
66
|
-
//Get row data
|
|
67
|
-
const row = grid[i]
|
|
68
|
-
if (!row) continue
|
|
69
|
-
|
|
70
|
-
// y of the row
|
|
71
|
-
const y = grid.y0 - i * resolution
|
|
72
|
-
|
|
73
|
-
//store the previous height
|
|
74
|
-
let hG_
|
|
75
|
-
|
|
76
|
-
for (let j = grid.minJ; j <= grid.maxJ; j++) {
|
|
77
|
-
//get column value
|
|
78
|
-
let hG = row[j]
|
|
79
|
-
if (!hG) hG = 0
|
|
80
|
-
|
|
81
|
-
// x of the cell
|
|
82
|
-
const x = grid.x0 + j * resolution
|
|
83
|
-
|
|
84
|
-
if (hG || hG_) {
|
|
85
|
-
//draw line only when at least one of both values is non-null
|
|
86
|
-
//TODO test bezierCurveTo
|
|
87
|
-
ctx.lineTo(x + resolution / 2, y + hG)
|
|
88
|
-
} else {
|
|
89
|
-
//else move the point
|
|
90
|
-
ctx.moveTo(x + resolution / 2, y)
|
|
91
|
-
}
|
|
92
|
-
//store the previous value
|
|
93
|
-
hG_ = hG
|
|
94
|
-
}
|
|
95
|
-
//last point
|
|
96
|
-
if (hG_) ctx.lineTo(grid.x0 + resolution * grid.maxJ + resolution / 2, y)
|
|
97
|
-
|
|
98
|
-
//draw fill
|
|
99
|
-
const fc = this.fillColor(y, ys, resolution, z)
|
|
100
|
-
if (fc && fc != 'none') {
|
|
101
|
-
ctx.fillStyle = fc
|
|
102
|
-
ctx.fill()
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
//draw line
|
|
106
|
-
const lc = this.lineColor(y, ys, resolution, z)
|
|
107
|
-
const lw = this.lineWidth(y, ys, resolution, z)
|
|
108
|
-
if (lc && lc != 'none' && lw > 0) {
|
|
109
|
-
ctx.strokeStyle = lc
|
|
110
|
-
ctx.lineWidth = lw
|
|
111
|
-
ctx.stroke()
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
*/
|
|
115
|
-
|
|
116
|
-
//compute extent
|
|
117
|
-
const e = geoCanvas.extGeo
|
|
118
|
-
if (!e) return
|
|
119
|
-
const xMin = Math.floor(e.xMin / resolution) * resolution
|
|
120
|
-
const xMax = Math.floor(e.xMax / resolution) * resolution
|
|
121
|
-
const yMin = Math.floor(e.yMin / resolution) * resolution
|
|
122
|
-
const yMax = Math.floor(e.yMax / resolution) * resolution
|
|
123
|
-
|
|
124
|
-
const ys = { min: yMin, max: yMax }
|
|
125
|
-
|
|
126
|
-
//draw lines, row by row, stating from the top
|
|
127
|
-
ctx.lineJoin = 'round'
|
|
128
|
-
for (let y = yMax; y >= yMin; y -= resolution) {
|
|
129
|
-
//get row
|
|
130
|
-
const row = ind[y]
|
|
131
|
-
|
|
132
|
-
//no row
|
|
133
|
-
if (!row) continue
|
|
134
|
-
|
|
135
|
-
//place first point
|
|
136
|
-
ctx.beginPath()
|
|
137
|
-
ctx.moveTo(xMin - resolution / 2, y)
|
|
138
|
-
|
|
139
|
-
//store the previous height
|
|
140
|
-
let hG_
|
|
141
|
-
|
|
142
|
-
//go through the line cells
|
|
143
|
-
for (let x = xMin; x <= xMax; x += resolution) {
|
|
144
|
-
//get column value
|
|
145
|
-
let hG = row[x]
|
|
146
|
-
if (!hG) hG = 0
|
|
147
|
-
|
|
148
|
-
if (hG || hG_) {
|
|
149
|
-
//draw line only when at least one of both values is non-null
|
|
150
|
-
//TODO test bezierCurveTo
|
|
151
|
-
ctx.lineTo(x + resolution / 2, y + hG)
|
|
152
|
-
} else {
|
|
153
|
-
//else move the point
|
|
154
|
-
ctx.moveTo(x + resolution / 2, y)
|
|
155
|
-
}
|
|
156
|
-
//store the previous value
|
|
157
|
-
hG_ = hG
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
//last point
|
|
161
|
-
if (hG_) ctx.lineTo(xMax + resolution / 2, y)
|
|
162
|
-
|
|
163
|
-
//draw fill
|
|
164
|
-
const fc = this.fillColor(y, ys, resolution, z)
|
|
165
|
-
if (fc && fc != 'none') {
|
|
166
|
-
ctx.fillStyle = fc
|
|
167
|
-
ctx.fill()
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
//draw line
|
|
171
|
-
const lc = this.lineColor(y, ys, resolution, z)
|
|
172
|
-
const lw = this.lineWidth(y, ys, resolution, z)
|
|
173
|
-
if (lc && lc != 'none' && lw > 0) {
|
|
174
|
-
ctx.strokeStyle = lc
|
|
175
|
-
ctx.lineWidth = lw
|
|
176
|
-
ctx.stroke()
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../core/Style.js'
|
|
5
|
+
import { cellsToGrid } from '../utils/utils.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @module style
|
|
9
|
+
* @author Julien Gaffuri
|
|
10
|
+
*/
|
|
11
|
+
export class JoyPlotStyle extends Style {
|
|
12
|
+
/** @param {object} opts */
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
super(opts)
|
|
15
|
+
opts = opts || {}
|
|
16
|
+
|
|
17
|
+
/** A function returning the height of a cell in geographical unit.
|
|
18
|
+
* @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
|
|
19
|
+
this.height = opts.height || ((c, r) => r * Math.random()) //(c,r,z,vs) => {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
23
|
+
this.lineColor = opts.lineColor || ((y, ys, r, z) => '#BBB')
|
|
24
|
+
/**
|
|
25
|
+
* @type {function(number,{min:number, max:number},number,number):number} */
|
|
26
|
+
this.lineWidth = opts.lineWidth || ((y, ys, r, z) => z)
|
|
27
|
+
/**
|
|
28
|
+
* @type {function(number,{min:number, max:number},number,number):string} */
|
|
29
|
+
this.fillColor = opts.fillColor || ((y, ys, r, z) => '#c08c5968')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {Array.<import("../core/Dataset.js").Cell>} cells
|
|
34
|
+
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
|
|
35
|
+
* @param {number} resolution
|
|
36
|
+
* @override
|
|
37
|
+
*/
|
|
38
|
+
draw(cells, geoCanvas, resolution) {
|
|
39
|
+
//filter
|
|
40
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
41
|
+
|
|
42
|
+
//
|
|
43
|
+
const z = geoCanvas.view.z
|
|
44
|
+
const ctx = geoCanvas.offscreenCtx
|
|
45
|
+
|
|
46
|
+
//get view scale
|
|
47
|
+
const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
|
|
48
|
+
|
|
49
|
+
//index cells by y and x
|
|
50
|
+
/** @type {object} */
|
|
51
|
+
const ind = cellsToGrid(cells, cell => this.height(cell, resolution, z, viewScale))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
//make grid
|
|
55
|
+
/** @type {object} */
|
|
56
|
+
/*const grid = cellsToGrid2(cells, resolution, cell => this.height(cell, resolution, z, viewScale))
|
|
57
|
+
if (!grid.maxI || !grid.maxJ) return
|
|
58
|
+
|
|
59
|
+
//TODO
|
|
60
|
+
const ys = { min: grid.y0 + resolution * grid.minI, max: grid.y0 + resolution * grid.maxI }
|
|
61
|
+
|
|
62
|
+
//draw lines, row by row, stating from the top
|
|
63
|
+
ctx.lineJoin = 'round'
|
|
64
|
+
for (let i = grid.minI; i <= grid.maxI; i++) {
|
|
65
|
+
|
|
66
|
+
//Get row data
|
|
67
|
+
const row = grid[i]
|
|
68
|
+
if (!row) continue
|
|
69
|
+
|
|
70
|
+
// y of the row
|
|
71
|
+
const y = grid.y0 - i * resolution
|
|
72
|
+
|
|
73
|
+
//store the previous height
|
|
74
|
+
let hG_
|
|
75
|
+
|
|
76
|
+
for (let j = grid.minJ; j <= grid.maxJ; j++) {
|
|
77
|
+
//get column value
|
|
78
|
+
let hG = row[j]
|
|
79
|
+
if (!hG) hG = 0
|
|
80
|
+
|
|
81
|
+
// x of the cell
|
|
82
|
+
const x = grid.x0 + j * resolution
|
|
83
|
+
|
|
84
|
+
if (hG || hG_) {
|
|
85
|
+
//draw line only when at least one of both values is non-null
|
|
86
|
+
//TODO test bezierCurveTo
|
|
87
|
+
ctx.lineTo(x + resolution / 2, y + hG)
|
|
88
|
+
} else {
|
|
89
|
+
//else move the point
|
|
90
|
+
ctx.moveTo(x + resolution / 2, y)
|
|
91
|
+
}
|
|
92
|
+
//store the previous value
|
|
93
|
+
hG_ = hG
|
|
94
|
+
}
|
|
95
|
+
//last point
|
|
96
|
+
if (hG_) ctx.lineTo(grid.x0 + resolution * grid.maxJ + resolution / 2, y)
|
|
97
|
+
|
|
98
|
+
//draw fill
|
|
99
|
+
const fc = this.fillColor(y, ys, resolution, z)
|
|
100
|
+
if (fc && fc != 'none') {
|
|
101
|
+
ctx.fillStyle = fc
|
|
102
|
+
ctx.fill()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//draw line
|
|
106
|
+
const lc = this.lineColor(y, ys, resolution, z)
|
|
107
|
+
const lw = this.lineWidth(y, ys, resolution, z)
|
|
108
|
+
if (lc && lc != 'none' && lw > 0) {
|
|
109
|
+
ctx.strokeStyle = lc
|
|
110
|
+
ctx.lineWidth = lw
|
|
111
|
+
ctx.stroke()
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
//compute extent
|
|
117
|
+
const e = geoCanvas.extGeo
|
|
118
|
+
if (!e) return
|
|
119
|
+
const xMin = Math.floor(e.xMin / resolution) * resolution
|
|
120
|
+
const xMax = Math.floor(e.xMax / resolution) * resolution
|
|
121
|
+
const yMin = Math.floor(e.yMin / resolution) * resolution
|
|
122
|
+
const yMax = Math.floor(e.yMax / resolution) * resolution
|
|
123
|
+
|
|
124
|
+
const ys = { min: yMin, max: yMax }
|
|
125
|
+
|
|
126
|
+
//draw lines, row by row, stating from the top
|
|
127
|
+
ctx.lineJoin = 'round'
|
|
128
|
+
for (let y = yMax; y >= yMin; y -= resolution) {
|
|
129
|
+
//get row
|
|
130
|
+
const row = ind[y]
|
|
131
|
+
|
|
132
|
+
//no row
|
|
133
|
+
if (!row) continue
|
|
134
|
+
|
|
135
|
+
//place first point
|
|
136
|
+
ctx.beginPath()
|
|
137
|
+
ctx.moveTo(xMin - resolution / 2, y)
|
|
138
|
+
|
|
139
|
+
//store the previous height
|
|
140
|
+
let hG_
|
|
141
|
+
|
|
142
|
+
//go through the line cells
|
|
143
|
+
for (let x = xMin; x <= xMax; x += resolution) {
|
|
144
|
+
//get column value
|
|
145
|
+
let hG = row[x]
|
|
146
|
+
if (!hG) hG = 0
|
|
147
|
+
|
|
148
|
+
if (hG || hG_) {
|
|
149
|
+
//draw line only when at least one of both values is non-null
|
|
150
|
+
//TODO test bezierCurveTo
|
|
151
|
+
ctx.lineTo(x + resolution / 2, y + hG)
|
|
152
|
+
} else {
|
|
153
|
+
//else move the point
|
|
154
|
+
ctx.moveTo(x + resolution / 2, y)
|
|
155
|
+
}
|
|
156
|
+
//store the previous value
|
|
157
|
+
hG_ = hG
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
//last point
|
|
161
|
+
if (hG_) ctx.lineTo(xMax + resolution / 2, y)
|
|
162
|
+
|
|
163
|
+
//draw fill
|
|
164
|
+
const fc = this.fillColor(y, ys, resolution, z)
|
|
165
|
+
if (fc && fc != 'none') {
|
|
166
|
+
ctx.fillStyle = fc
|
|
167
|
+
ctx.fill()
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//draw line
|
|
171
|
+
const lc = this.lineColor(y, ys, resolution, z)
|
|
172
|
+
const lw = this.lineWidth(y, ys, resolution, z)
|
|
173
|
+
if (lc && lc != 'none' && lw > 0) {
|
|
174
|
+
ctx.strokeStyle = lc
|
|
175
|
+
ctx.lineWidth = lw
|
|
176
|
+
ctx.stroke()
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
package/src/style/LegoStyle.js
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
//import { TanakaStyle } from './SideTanakaStyle___OLD.js'
|
|
5
|
-
import { StrokeStyle } from './StrokeStyle.js'
|
|
6
|
-
import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.js'
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @module style
|
|
15
|
-
* @author Julien Gaffuri
|
|
16
|
-
*/
|
|
17
|
-
export class LegoStyle {
|
|
18
|
-
static get(value, breaks, colors, opts = {}) {
|
|
19
|
-
opts = opts || {}
|
|
20
|
-
|
|
21
|
-
//the colors
|
|
22
|
-
//http://www.jennyscrayoncollection.com/2021/06/all-current-lego-colors.html
|
|
23
|
-
//https://leonawicz.github.io/legocolors/reference/figures/README-plot-1.png
|
|
24
|
-
/*opts.colors = opts.colors || [
|
|
25
|
-
'#00852b', //darker green
|
|
26
|
-
'#afd246', //light green
|
|
27
|
-
'#fac80a', //dark yellow
|
|
28
|
-
'#bb805a', //brown
|
|
29
|
-
'#d67923', //mostard
|
|
30
|
-
'#cb4e29', //redish
|
|
31
|
-
'#b40000', //red
|
|
32
|
-
'#720012', //dark red
|
|
33
|
-
//"purple",
|
|
34
|
-
//"#eee" //whithe
|
|
35
|
-
]*/
|
|
36
|
-
|
|
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
|
-
})
|
|
60
|
-
|
|
61
|
-
//style to show limits between pieces
|
|
62
|
-
const sst = new StrokeStyle({
|
|
63
|
-
strokeColor: () => '#666',
|
|
64
|
-
strokeWidth: (c, r, z) => 0.2 * z,
|
|
65
|
-
filter: opts.filter,
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
return [
|
|
69
|
-
cellStyle,
|
|
70
|
-
sst,
|
|
71
|
-
tanakaStyle,
|
|
72
|
-
new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright, filter: opts.filter }),
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @param {function(import('../core/Dataset.js').Cell):string} code
|
|
78
|
-
* @param {object} color
|
|
79
|
-
* @param {object} opts
|
|
80
|
-
* @returns {Array.<Style>}
|
|
81
|
-
*/
|
|
82
|
-
static getCategory(code, color, opts) {
|
|
83
|
-
opts = opts || {}
|
|
84
|
-
|
|
85
|
-
opts.colDark = opts.colDark || '#333'
|
|
86
|
-
opts.colBright = opts.colBright || '#aaa'
|
|
87
|
-
|
|
88
|
-
//
|
|
89
|
-
const s = new SquareColorCategoryWebGLStyle({ code: code, color: color })
|
|
90
|
-
//style to show limits between pieces
|
|
91
|
-
const sst = new StrokeStyle({ strokeColor: () => '#666', strokeWidth: (c, r, z) => 0.2 * z })
|
|
92
|
-
|
|
93
|
-
return [s, sst, new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright })]
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* A style to draw top circle of lego bricks.
|
|
99
|
-
*/
|
|
100
|
-
class LegoTopStyle extends Style {
|
|
101
|
-
/** @param {object|undefined} opts */
|
|
102
|
-
constructor(opts) {
|
|
103
|
-
super(opts)
|
|
104
|
-
opts = opts || {}
|
|
105
|
-
this.colDark = opts.colDark || '#333'
|
|
106
|
-
this.colBright = opts.colBright || '#aaa'
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
draw(cells, geoCanvas, r) {
|
|
110
|
-
//filter
|
|
111
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
112
|
-
const ctx = geoCanvas.offscreenCtx
|
|
113
|
-
|
|
114
|
-
ctx.lineWidth = 0.6 * geoCanvas.view.z
|
|
115
|
-
|
|
116
|
-
//dark part
|
|
117
|
-
ctx.strokeStyle = this.colDark
|
|
118
|
-
for (let c of cells) {
|
|
119
|
-
ctx.beginPath()
|
|
120
|
-
ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), true)
|
|
121
|
-
ctx.stroke()
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
//bright part
|
|
125
|
-
ctx.strokeStyle = this.colBright
|
|
126
|
-
for (let c of cells) {
|
|
127
|
-
ctx.beginPath()
|
|
128
|
-
ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), false)
|
|
129
|
-
ctx.stroke()
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
//import { TanakaStyle } from './SideTanakaStyle___OLD.js'
|
|
5
|
+
import { StrokeStyle } from './StrokeStyle.js'
|
|
6
|
+
import { SquareColorCategoryWebGLStyle } from './SquareColorCategoryWebGLStyle.js'
|
|
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
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @module style
|
|
15
|
+
* @author Julien Gaffuri
|
|
16
|
+
*/
|
|
17
|
+
export class LegoStyle {
|
|
18
|
+
static get(value, breaks, colors, opts = {}) {
|
|
19
|
+
opts = opts || {}
|
|
20
|
+
|
|
21
|
+
//the colors
|
|
22
|
+
//http://www.jennyscrayoncollection.com/2021/06/all-current-lego-colors.html
|
|
23
|
+
//https://leonawicz.github.io/legocolors/reference/figures/README-plot-1.png
|
|
24
|
+
/*opts.colors = opts.colors || [
|
|
25
|
+
'#00852b', //darker green
|
|
26
|
+
'#afd246', //light green
|
|
27
|
+
'#fac80a', //dark yellow
|
|
28
|
+
'#bb805a', //brown
|
|
29
|
+
'#d67923', //mostard
|
|
30
|
+
'#cb4e29', //redish
|
|
31
|
+
'#b40000', //red
|
|
32
|
+
'#720012', //dark red
|
|
33
|
+
//"purple",
|
|
34
|
+
//"#eee" //whithe
|
|
35
|
+
]*/
|
|
36
|
+
|
|
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
|
+
})
|
|
60
|
+
|
|
61
|
+
//style to show limits between pieces
|
|
62
|
+
const sst = new StrokeStyle({
|
|
63
|
+
strokeColor: () => '#666',
|
|
64
|
+
strokeWidth: (c, r, z) => 0.2 * z,
|
|
65
|
+
filter: opts.filter,
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return [
|
|
69
|
+
cellStyle,
|
|
70
|
+
sst,
|
|
71
|
+
tanakaStyle,
|
|
72
|
+
new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright, filter: opts.filter }),
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {function(import('../core/Dataset.js').Cell):string} code
|
|
78
|
+
* @param {object} color
|
|
79
|
+
* @param {object} opts
|
|
80
|
+
* @returns {Array.<Style>}
|
|
81
|
+
*/
|
|
82
|
+
static getCategory(code, color, opts) {
|
|
83
|
+
opts = opts || {}
|
|
84
|
+
|
|
85
|
+
opts.colDark = opts.colDark || '#333'
|
|
86
|
+
opts.colBright = opts.colBright || '#aaa'
|
|
87
|
+
|
|
88
|
+
//
|
|
89
|
+
const s = new SquareColorCategoryWebGLStyle({ code: code, color: color })
|
|
90
|
+
//style to show limits between pieces
|
|
91
|
+
const sst = new StrokeStyle({ strokeColor: () => '#666', strokeWidth: (c, r, z) => 0.2 * z })
|
|
92
|
+
|
|
93
|
+
return [s, sst, new LegoTopStyle({ colDark: opts.colDark, colBright: opts.colBright })]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* A style to draw top circle of lego bricks.
|
|
99
|
+
*/
|
|
100
|
+
class LegoTopStyle extends Style {
|
|
101
|
+
/** @param {object|undefined} opts */
|
|
102
|
+
constructor(opts) {
|
|
103
|
+
super(opts)
|
|
104
|
+
opts = opts || {}
|
|
105
|
+
this.colDark = opts.colDark || '#333'
|
|
106
|
+
this.colBright = opts.colBright || '#aaa'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
draw(cells, geoCanvas, r) {
|
|
110
|
+
//filter
|
|
111
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
112
|
+
const ctx = geoCanvas.offscreenCtx
|
|
113
|
+
|
|
114
|
+
ctx.lineWidth = 0.6 * geoCanvas.view.z
|
|
115
|
+
|
|
116
|
+
//dark part
|
|
117
|
+
ctx.strokeStyle = this.colDark
|
|
118
|
+
for (let c of cells) {
|
|
119
|
+
ctx.beginPath()
|
|
120
|
+
ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), true)
|
|
121
|
+
ctx.stroke()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
//bright part
|
|
125
|
+
ctx.strokeStyle = this.colBright
|
|
126
|
+
for (let c of cells) {
|
|
127
|
+
ctx.beginPath()
|
|
128
|
+
ctx.arc(c.x + r * 0.5, c.y + r * 0.5, r * 0.55 * 0.5, Math.PI / 4, -Math.PI * (3 / 4), false)
|
|
129
|
+
ctx.stroke()
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|