gladly-plot 0.0.4 → 0.0.6
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 +9 -2
- package/package.json +10 -11
- package/src/axes/Axis.js +401 -0
- package/src/{AxisLink.js → axes/AxisLink.js} +6 -2
- package/src/{AxisQuantityKindRegistry.js → axes/AxisQuantityKindRegistry.js} +7 -0
- package/src/axes/AxisRegistry.js +179 -0
- package/src/axes/Camera.js +47 -0
- package/src/axes/ColorAxisRegistry.js +101 -0
- package/src/{FilterAxisRegistry.js → axes/FilterAxisRegistry.js} +63 -0
- package/src/axes/TickLabelAtlas.js +99 -0
- package/src/axes/ZoomController.js +463 -0
- package/src/colorscales/BivariateColorscales.js +205 -0
- package/src/colorscales/ColorscaleRegistry.js +144 -0
- package/src/compute/ComputationRegistry.js +179 -0
- package/src/compute/axisFilter.js +59 -0
- package/src/compute/conv.js +286 -0
- package/src/compute/elementwise.js +72 -0
- package/src/compute/fft.js +378 -0
- package/src/compute/filter.js +229 -0
- package/src/compute/hist.js +285 -0
- package/src/compute/kde.js +120 -0
- package/src/compute/scatter2dInterpolate.js +277 -0
- package/src/compute/util.js +196 -0
- package/src/core/ComputePipeline.js +153 -0
- package/src/core/GlBase.js +141 -0
- package/src/core/Layer.js +59 -0
- package/src/core/LayerType.js +433 -0
- package/src/core/Plot.js +1213 -0
- package/src/core/PlotGroup.js +204 -0
- package/src/core/ShaderQueue.js +73 -0
- package/src/data/ColumnData.js +269 -0
- package/src/data/Computation.js +95 -0
- package/src/data/Data.js +270 -0
- package/src/{Colorbar.js → floats/Colorbar.js} +19 -5
- package/src/floats/Colorbar2d.js +77 -0
- package/src/{Filterbar.js → floats/Filterbar.js} +18 -4
- package/src/{FilterbarFloat.js → floats/Float.js} +73 -30
- package/src/{EpsgUtils.js → geo/EpsgUtils.js} +1 -1
- package/src/index.js +47 -22
- package/src/layers/BarsLayer.js +168 -0
- package/src/{ColorbarLayer.js → layers/ColorbarLayer.js} +12 -16
- package/src/layers/ColorbarLayer2d.js +86 -0
- package/src/{FilterbarLayer.js → layers/FilterbarLayer.js} +6 -5
- package/src/layers/LinesLayer.js +185 -0
- package/src/layers/PointsLayer.js +118 -0
- package/src/layers/ScatterShared.js +98 -0
- package/src/{TileLayer.js → layers/TileLayer.js} +24 -20
- package/src/math/mat4.js +100 -0
- package/src/Axis.js +0 -48
- package/src/AxisRegistry.js +0 -54
- package/src/ColorAxisRegistry.js +0 -49
- package/src/ColorscaleRegistry.js +0 -52
- package/src/Data.js +0 -67
- package/src/Float.js +0 -159
- package/src/Layer.js +0 -44
- package/src/LayerType.js +0 -209
- package/src/Plot.js +0 -1073
- package/src/ScatterLayer.js +0 -287
- /package/src/{MatplotlibColorscales.js → colorscales/MatplotlibColorscales.js} +0 -0
- /package/src/{LayerTypeRegistry.js → core/LayerTypeRegistry.js} +0 -0
package/src/Float.js
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { Colorbar } from "./Colorbar.js"
|
|
2
|
-
import { Plot } from "./Plot.js"
|
|
3
|
-
|
|
4
|
-
const DRAG_BAR_HEIGHT = 12
|
|
5
|
-
const MIN_WIDTH = 80
|
|
6
|
-
const MIN_HEIGHT = DRAG_BAR_HEIGHT + 30
|
|
7
|
-
|
|
8
|
-
// Default sizes include the drag bar so the colorbar content area is unchanged.
|
|
9
|
-
const DEFAULT_SIZE = {
|
|
10
|
-
horizontal: { width: 220, height: 70 + DRAG_BAR_HEIGHT },
|
|
11
|
-
vertical: { width: 70, height: 220 + DRAG_BAR_HEIGHT }
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class Float {
|
|
15
|
-
constructor(parentPlot, colorAxisName, {
|
|
16
|
-
orientation = "horizontal",
|
|
17
|
-
x = 10,
|
|
18
|
-
y = 10,
|
|
19
|
-
width,
|
|
20
|
-
height,
|
|
21
|
-
margin
|
|
22
|
-
} = {}) {
|
|
23
|
-
const defaults = DEFAULT_SIZE[orientation]
|
|
24
|
-
const w = width ?? defaults.width
|
|
25
|
-
const h = height ?? defaults.height
|
|
26
|
-
|
|
27
|
-
// Outer floating container
|
|
28
|
-
this._el = document.createElement('div')
|
|
29
|
-
Object.assign(this._el.style, {
|
|
30
|
-
position: 'absolute',
|
|
31
|
-
left: x + 'px',
|
|
32
|
-
top: y + 'px',
|
|
33
|
-
width: w + 'px',
|
|
34
|
-
height: h + 'px',
|
|
35
|
-
zIndex: '10',
|
|
36
|
-
boxSizing: 'border-box',
|
|
37
|
-
background: 'rgba(255,255,255,0.88)',
|
|
38
|
-
border: '1px solid #aaa',
|
|
39
|
-
borderRadius: '4px',
|
|
40
|
-
boxShadow: '0 2px 8px rgba(0,0,0,0.25)',
|
|
41
|
-
overflow: 'hidden'
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
// Ensure parent is positioned so our absolute child is contained within it
|
|
45
|
-
const parentEl = parentPlot.container
|
|
46
|
-
if (getComputedStyle(parentEl).position === 'static') {
|
|
47
|
-
parentEl.style.position = 'relative'
|
|
48
|
-
}
|
|
49
|
-
parentEl.appendChild(this._el)
|
|
50
|
-
|
|
51
|
-
// Drag bar — thin strip at the top; dragging here moves the float
|
|
52
|
-
this._dragBar = document.createElement('div')
|
|
53
|
-
Object.assign(this._dragBar.style, {
|
|
54
|
-
position: 'absolute',
|
|
55
|
-
top: '0',
|
|
56
|
-
left: '0',
|
|
57
|
-
right: '0',
|
|
58
|
-
height: DRAG_BAR_HEIGHT + 'px',
|
|
59
|
-
cursor: 'grab',
|
|
60
|
-
background: 'rgba(0,0,0,0.07)',
|
|
61
|
-
borderBottom: '1px solid rgba(0,0,0,0.12)',
|
|
62
|
-
zIndex: '1'
|
|
63
|
-
})
|
|
64
|
-
this._el.appendChild(this._dragBar)
|
|
65
|
-
|
|
66
|
-
// Resize handle — bottom-right corner
|
|
67
|
-
this._resizeHandle = document.createElement('div')
|
|
68
|
-
Object.assign(this._resizeHandle.style, {
|
|
69
|
-
position: 'absolute',
|
|
70
|
-
right: '0',
|
|
71
|
-
bottom: '0',
|
|
72
|
-
width: '12px',
|
|
73
|
-
height: '12px',
|
|
74
|
-
cursor: 'se-resize',
|
|
75
|
-
background: 'rgba(0,0,0,0.18)',
|
|
76
|
-
borderTopLeftRadius: '3px',
|
|
77
|
-
zIndex: '3'
|
|
78
|
-
})
|
|
79
|
-
this._el.appendChild(this._resizeHandle)
|
|
80
|
-
|
|
81
|
-
// Sub-container for the colorbar — sits below the drag bar
|
|
82
|
-
this._colorbarEl = document.createElement('div')
|
|
83
|
-
Object.assign(this._colorbarEl.style, {
|
|
84
|
-
position: 'absolute',
|
|
85
|
-
top: DRAG_BAR_HEIGHT + 'px',
|
|
86
|
-
left: '0',
|
|
87
|
-
right: '0',
|
|
88
|
-
bottom: '0'
|
|
89
|
-
})
|
|
90
|
-
this._el.appendChild(this._colorbarEl)
|
|
91
|
-
|
|
92
|
-
this._colorbar = new Colorbar(this._colorbarEl, parentPlot, colorAxisName, { orientation, margin })
|
|
93
|
-
|
|
94
|
-
this._setupInteraction()
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
_setupInteraction() {
|
|
98
|
-
let mode = null // 'drag' | 'resize'
|
|
99
|
-
let startX, startY, startLeft, startTop, startW, startH
|
|
100
|
-
|
|
101
|
-
const onDragBarMouseDown = (e) => {
|
|
102
|
-
mode = 'drag'
|
|
103
|
-
startX = e.clientX
|
|
104
|
-
startY = e.clientY
|
|
105
|
-
startLeft = parseInt(this._el.style.left, 10)
|
|
106
|
-
startTop = parseInt(this._el.style.top, 10)
|
|
107
|
-
this._dragBar.style.cursor = 'grabbing'
|
|
108
|
-
e.preventDefault()
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const onResizeMouseDown = (e) => {
|
|
112
|
-
mode = 'resize'
|
|
113
|
-
startX = e.clientX
|
|
114
|
-
startY = e.clientY
|
|
115
|
-
startW = this._el.offsetWidth
|
|
116
|
-
startH = this._el.offsetHeight
|
|
117
|
-
e.preventDefault()
|
|
118
|
-
e.stopPropagation()
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const onMouseMove = (e) => {
|
|
122
|
-
if (!mode) return
|
|
123
|
-
const dx = e.clientX - startX
|
|
124
|
-
const dy = e.clientY - startY
|
|
125
|
-
if (mode === 'drag') {
|
|
126
|
-
this._el.style.left = (startLeft + dx) + 'px'
|
|
127
|
-
this._el.style.top = (startTop + dy) + 'px'
|
|
128
|
-
} else {
|
|
129
|
-
this._el.style.width = Math.max(MIN_WIDTH, startW + dx) + 'px'
|
|
130
|
-
this._el.style.height = Math.max(MIN_HEIGHT, startH + dy) + 'px'
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const onMouseUp = () => {
|
|
135
|
-
if (mode === 'drag') this._dragBar.style.cursor = 'grab'
|
|
136
|
-
mode = null
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
this._dragBar.addEventListener('mousedown', onDragBarMouseDown)
|
|
140
|
-
this._resizeHandle.addEventListener('mousedown', onResizeMouseDown)
|
|
141
|
-
document.addEventListener('mousemove', onMouseMove)
|
|
142
|
-
document.addEventListener('mouseup', onMouseUp)
|
|
143
|
-
|
|
144
|
-
this._cleanupInteraction = () => {
|
|
145
|
-
this._dragBar.removeEventListener('mousedown', onDragBarMouseDown)
|
|
146
|
-
this._resizeHandle.removeEventListener('mousedown', onResizeMouseDown)
|
|
147
|
-
document.removeEventListener('mousemove', onMouseMove)
|
|
148
|
-
document.removeEventListener('mouseup', onMouseUp)
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
destroy() {
|
|
153
|
-
this._cleanupInteraction()
|
|
154
|
-
this._colorbar.destroy()
|
|
155
|
-
this._el.remove()
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
Plot._FloatClass = Float
|
package/src/Layer.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export class Layer {
|
|
2
|
-
constructor({ type, attributes, uniforms, nameMap = {}, domains = {}, lineWidth = 1, primitive = "points", xAxis = "xaxis_bottom", yAxis = "yaxis_left", xAxisQuantityKind, yAxisQuantityKind, colorAxes = [], filterAxes = [], vertexCount = null, instanceCount = null, attributeDivisors = {}, blend = null }) {
|
|
3
|
-
// Validate that all attributes are typed arrays
|
|
4
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
5
|
-
if (!(value instanceof Float32Array)) {
|
|
6
|
-
throw new Error(`Attribute '${key}' must be Float32Array`)
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// Validate colorAxes: must be an array of quantity kind strings
|
|
11
|
-
for (const quantityKind of colorAxes) {
|
|
12
|
-
if (typeof quantityKind !== 'string') {
|
|
13
|
-
throw new Error(`Color axis quantity kind must be a string, got ${typeof quantityKind}`)
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Validate filterAxes: must be an array of quantity kind strings
|
|
18
|
-
for (const quantityKind of filterAxes) {
|
|
19
|
-
if (typeof quantityKind !== 'string') {
|
|
20
|
-
throw new Error(`Filter axis quantity kind must be a string, got ${typeof quantityKind}`)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
this.type = type
|
|
25
|
-
this.attributes = attributes
|
|
26
|
-
this.uniforms = uniforms
|
|
27
|
-
this.nameMap = nameMap
|
|
28
|
-
this.domains = domains
|
|
29
|
-
this.lineWidth = lineWidth
|
|
30
|
-
this.primitive = primitive
|
|
31
|
-
this.xAxis = xAxis
|
|
32
|
-
this.yAxis = yAxis
|
|
33
|
-
this.xAxisQuantityKind = xAxisQuantityKind
|
|
34
|
-
this.yAxisQuantityKind = yAxisQuantityKind
|
|
35
|
-
// colorAxes: string[] — quantity kinds of color axes; attribute named by quantityKind holds the data
|
|
36
|
-
this.colorAxes = colorAxes
|
|
37
|
-
// filterAxes: string[] — quantity kinds of filter axes; attribute named by quantityKind holds the data
|
|
38
|
-
this.filterAxes = filterAxes
|
|
39
|
-
this.vertexCount = vertexCount
|
|
40
|
-
this.instanceCount = instanceCount
|
|
41
|
-
this.attributeDivisors = attributeDivisors
|
|
42
|
-
this.blend = blend
|
|
43
|
-
}
|
|
44
|
-
}
|
package/src/LayerType.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { Layer } from "./Layer.js"
|
|
2
|
-
import { buildColorGlsl } from "./ColorscaleRegistry.js"
|
|
3
|
-
import { buildFilterGlsl } from "./FilterAxisRegistry.js"
|
|
4
|
-
|
|
5
|
-
function buildSpatialGlsl() {
|
|
6
|
-
return `float normalize_axis(float v, vec2 domain, float scaleType) {
|
|
7
|
-
float vt = scaleType > 0.5 ? log(v) : v;
|
|
8
|
-
float d0 = scaleType > 0.5 ? log(domain.x) : domain.x;
|
|
9
|
-
float d1 = scaleType > 0.5 ? log(domain.y) : domain.y;
|
|
10
|
-
return (vt - d0) / (d1 - d0);
|
|
11
|
-
}`
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function buildApplyColorGlsl() {
|
|
15
|
-
return `uniform float u_pickingMode;
|
|
16
|
-
uniform float u_pickLayerIndex;
|
|
17
|
-
varying float v_pickId;
|
|
18
|
-
vec4 gladly_apply_color(vec4 color) {
|
|
19
|
-
if (u_pickingMode > 0.5) {
|
|
20
|
-
float layerIdx = u_pickLayerIndex + 1.0;
|
|
21
|
-
float dataIdx = floor(v_pickId + 0.5);
|
|
22
|
-
return vec4(
|
|
23
|
-
layerIdx / 255.0,
|
|
24
|
-
floor(dataIdx / 65536.0) / 255.0,
|
|
25
|
-
floor(mod(dataIdx, 65536.0) / 256.0) / 255.0,
|
|
26
|
-
mod(dataIdx, 256.0) / 255.0
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
return color;
|
|
30
|
-
}`
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function injectPickIdAssignment(src) {
|
|
34
|
-
const lastBrace = src.lastIndexOf('}')
|
|
35
|
-
if (lastBrace === -1) return src
|
|
36
|
-
return src.slice(0, lastBrace) + ' v_pickId = a_pickId;\n}'
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function injectInto(src, helpers) {
|
|
40
|
-
const injected = helpers.filter(Boolean).join('\n')
|
|
41
|
-
if (!injected) return src
|
|
42
|
-
const versionRe = /^[ \t]*#version[^\n]*\n?/
|
|
43
|
-
const versionMatch = src.match(versionRe)
|
|
44
|
-
const version = versionMatch ? versionMatch[0] : ''
|
|
45
|
-
const rest = version ? src.slice(version.length) : src
|
|
46
|
-
const precisionRe = /^\s*precision\s+\S+\s+\S+\s*;\s*$/mg
|
|
47
|
-
const precisions = rest.match(precisionRe) ?? []
|
|
48
|
-
const body = rest.replace(precisionRe, '')
|
|
49
|
-
return version + precisions.join('\n') + '\n' + injected + '\n' + body
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export class LayerType {
|
|
53
|
-
constructor({
|
|
54
|
-
name,
|
|
55
|
-
// Optional static axis declarations (for schema/introspection — no function call needed)
|
|
56
|
-
xAxis, xAxisQuantityKind,
|
|
57
|
-
yAxis, yAxisQuantityKind,
|
|
58
|
-
colorAxisQuantityKinds,
|
|
59
|
-
filterAxisQuantityKinds,
|
|
60
|
-
// Optional dynamic resolver — overrides statics wherever it returns a non-undefined value
|
|
61
|
-
getAxisConfig,
|
|
62
|
-
// GPU rendering
|
|
63
|
-
vert, frag, schema, createLayer, createDrawCommand
|
|
64
|
-
}) {
|
|
65
|
-
this.name = name
|
|
66
|
-
// Static declarations stored as-is (undefined = not declared)
|
|
67
|
-
this.xAxis = xAxis
|
|
68
|
-
this.xAxisQuantityKind = xAxisQuantityKind
|
|
69
|
-
this.yAxis = yAxis
|
|
70
|
-
this.yAxisQuantityKind = yAxisQuantityKind
|
|
71
|
-
this.colorAxisQuantityKinds = colorAxisQuantityKinds ?? []
|
|
72
|
-
this.filterAxisQuantityKinds = filterAxisQuantityKinds ?? []
|
|
73
|
-
this.vert = vert
|
|
74
|
-
this.frag = frag
|
|
75
|
-
|
|
76
|
-
if (schema) this._schema = schema
|
|
77
|
-
if (createLayer) this._createLayer = createLayer
|
|
78
|
-
if (getAxisConfig) this._getAxisConfig = getAxisConfig
|
|
79
|
-
if (createDrawCommand) this.createDrawCommand = createDrawCommand
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
createDrawCommand(regl, layer) {
|
|
83
|
-
const nm = layer.nameMap
|
|
84
|
-
// Rename an internal name to the shader-visible name via nameMap (identity if absent).
|
|
85
|
-
const shaderName = (internalName) => nm[internalName] ?? internalName
|
|
86
|
-
// Build a single-entry uniform object with renamed key reading from the internal prop name.
|
|
87
|
-
const u = (internalName) => ({ [shaderName(internalName)]: regl.prop(internalName) })
|
|
88
|
-
|
|
89
|
-
const isInstanced = layer.instanceCount !== null
|
|
90
|
-
const pickCount = isInstanced ? layer.instanceCount : (layer.vertexCount ?? layer.attributes.x?.length ?? 0)
|
|
91
|
-
const pickIds = new Float32Array(pickCount)
|
|
92
|
-
for (let i = 0; i < pickCount; i++) pickIds[i] = i
|
|
93
|
-
|
|
94
|
-
const attributes = {
|
|
95
|
-
...Object.fromEntries(
|
|
96
|
-
Object.entries(layer.attributes).map(([key, buffer]) => {
|
|
97
|
-
const divisor = layer.attributeDivisors[key]
|
|
98
|
-
const attrObj = divisor !== undefined ? { buffer, divisor } : { buffer }
|
|
99
|
-
return [shaderName(key), attrObj]
|
|
100
|
-
})
|
|
101
|
-
),
|
|
102
|
-
a_pickId: isInstanced ? { buffer: regl.buffer(pickIds), divisor: 1 } : regl.buffer(pickIds)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const uniforms = {
|
|
106
|
-
...u("xDomain"),
|
|
107
|
-
...u("yDomain"),
|
|
108
|
-
...u("xScaleType"),
|
|
109
|
-
...u("yScaleType"),
|
|
110
|
-
u_pickingMode: regl.prop('u_pickingMode'),
|
|
111
|
-
u_pickLayerIndex: regl.prop('u_pickLayerIndex'),
|
|
112
|
-
...Object.fromEntries(
|
|
113
|
-
Object.entries(layer.uniforms).map(([key, value]) => [shaderName(key), value])
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Add per-color-axis uniforms (colorscale index + range + scale type), keyed by quantity kind
|
|
118
|
-
for (const qk of layer.colorAxes) {
|
|
119
|
-
Object.assign(uniforms, u(`colorscale_${qk}`), u(`color_range_${qk}`), u(`color_scale_type_${qk}`))
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Add per-filter-axis uniforms (vec4: [min, max, hasMin, hasMax] + scale type), keyed by quantity kind
|
|
123
|
-
for (const qk of layer.filterAxes) {
|
|
124
|
-
Object.assign(uniforms, u(`filter_range_${qk}`), u(`filter_scale_type_${qk}`))
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Inject GLSL helpers before the layer shader body.
|
|
128
|
-
const spatialGlsl = buildSpatialGlsl()
|
|
129
|
-
const colorGlsl = layer.colorAxes.length > 0 ? buildColorGlsl() : ''
|
|
130
|
-
const filterGlsl = layer.filterAxes.length > 0 ? buildFilterGlsl() : ''
|
|
131
|
-
const pickVertDecls = `attribute float a_pickId;\nvarying float v_pickId;`
|
|
132
|
-
|
|
133
|
-
const drawConfig = {
|
|
134
|
-
vert: injectPickIdAssignment(injectInto(this.vert, [spatialGlsl, filterGlsl, pickVertDecls])),
|
|
135
|
-
frag: injectInto(this.frag, [buildApplyColorGlsl(), colorGlsl, filterGlsl]),
|
|
136
|
-
attributes,
|
|
137
|
-
uniforms,
|
|
138
|
-
viewport: regl.prop("viewport"),
|
|
139
|
-
primitive: layer.primitive,
|
|
140
|
-
lineWidth: layer.lineWidth,
|
|
141
|
-
count: regl.prop("count"),
|
|
142
|
-
...(layer.blend ? { blend: layer.blend } : {})
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (layer.instanceCount !== null) {
|
|
146
|
-
drawConfig.instances = regl.prop("instances")
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return regl(drawConfig)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
schema(data) {
|
|
153
|
-
if (this._schema) return this._schema(data)
|
|
154
|
-
throw new Error(`LayerType '${this.name}' does not implement schema()`)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Resolves axis config by merging static declarations with dynamic getAxisConfig output.
|
|
158
|
-
// Dynamic values (non-undefined) override static values.
|
|
159
|
-
resolveAxisConfig(parameters, data) {
|
|
160
|
-
const resolved = {
|
|
161
|
-
xAxis: this.xAxis,
|
|
162
|
-
xAxisQuantityKind: this.xAxisQuantityKind,
|
|
163
|
-
yAxis: this.yAxis,
|
|
164
|
-
yAxisQuantityKind: this.yAxisQuantityKind,
|
|
165
|
-
colorAxisQuantityKinds: [...this.colorAxisQuantityKinds],
|
|
166
|
-
filterAxisQuantityKinds: [...this.filterAxisQuantityKinds],
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (this._getAxisConfig) {
|
|
170
|
-
const dynamic = this._getAxisConfig.call(this, parameters, data)
|
|
171
|
-
if (dynamic.xAxis !== undefined) resolved.xAxis = dynamic.xAxis
|
|
172
|
-
if (dynamic.xAxisQuantityKind !== undefined) resolved.xAxisQuantityKind = dynamic.xAxisQuantityKind
|
|
173
|
-
if (dynamic.yAxis !== undefined) resolved.yAxis = dynamic.yAxis
|
|
174
|
-
if (dynamic.yAxisQuantityKind !== undefined) resolved.yAxisQuantityKind = dynamic.yAxisQuantityKind
|
|
175
|
-
if (dynamic.colorAxisQuantityKinds !== undefined) resolved.colorAxisQuantityKinds = dynamic.colorAxisQuantityKinds
|
|
176
|
-
if (dynamic.filterAxisQuantityKinds !== undefined) resolved.filterAxisQuantityKinds = dynamic.filterAxisQuantityKinds
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return resolved
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
createLayer(parameters, data) {
|
|
183
|
-
if (!this._createLayer) {
|
|
184
|
-
throw new Error(`LayerType '${this.name}' does not implement createLayer()`)
|
|
185
|
-
}
|
|
186
|
-
const gpuConfigs = this._createLayer.call(this, parameters, data)
|
|
187
|
-
const axisConfig = this.resolveAxisConfig(parameters, data)
|
|
188
|
-
|
|
189
|
-
return gpuConfigs.map(gpuConfig => new Layer({
|
|
190
|
-
type: this,
|
|
191
|
-
attributes: gpuConfig.attributes ?? {},
|
|
192
|
-
uniforms: gpuConfig.uniforms ?? {},
|
|
193
|
-
nameMap: gpuConfig.nameMap ?? {},
|
|
194
|
-
domains: gpuConfig.domains ?? {},
|
|
195
|
-
lineWidth: gpuConfig.lineWidth ?? 1,
|
|
196
|
-
primitive: gpuConfig.primitive ?? "points",
|
|
197
|
-
vertexCount: gpuConfig.vertexCount ?? null,
|
|
198
|
-
instanceCount: gpuConfig.instanceCount ?? null,
|
|
199
|
-
attributeDivisors: gpuConfig.attributeDivisors ?? {},
|
|
200
|
-
blend: gpuConfig.blend ?? null,
|
|
201
|
-
xAxis: axisConfig.xAxis,
|
|
202
|
-
yAxis: axisConfig.yAxis,
|
|
203
|
-
xAxisQuantityKind: axisConfig.xAxisQuantityKind,
|
|
204
|
-
yAxisQuantityKind: axisConfig.yAxisQuantityKind,
|
|
205
|
-
colorAxes: axisConfig.colorAxisQuantityKinds,
|
|
206
|
-
filterAxes: axisConfig.filterAxisQuantityKinds,
|
|
207
|
-
}))
|
|
208
|
-
}
|
|
209
|
-
}
|