gladly-plot 0.0.4 → 0.0.5
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/package.json +2 -2
- package/src/axes/Axis.js +253 -0
- package/src/{AxisQuantityKindRegistry.js → axes/AxisQuantityKindRegistry.js} +7 -0
- package/src/{AxisRegistry.js → axes/AxisRegistry.js} +48 -0
- package/src/axes/ColorAxisRegistry.js +93 -0
- package/src/{FilterAxisRegistry.js → axes/FilterAxisRegistry.js} +63 -0
- package/src/axes/ZoomController.js +141 -0
- package/src/colorscales/BivariateColorscales.js +205 -0
- package/src/colorscales/ColorscaleRegistry.js +124 -0
- package/src/compute/ComputationRegistry.js +237 -0
- package/src/compute/axisFilter.js +47 -0
- package/src/compute/conv.js +230 -0
- package/src/compute/fft.js +292 -0
- package/src/compute/filter.js +227 -0
- package/src/compute/hist.js +180 -0
- package/src/compute/kde.js +102 -0
- package/src/{Layer.js → core/Layer.js} +4 -3
- package/src/{LayerType.js → core/LayerType.js} +72 -7
- package/src/core/Plot.js +735 -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} +17 -30
- package/src/{EpsgUtils.js → geo/EpsgUtils.js} +1 -1
- package/src/index.js +35 -22
- package/src/{ColorbarLayer.js → layers/ColorbarLayer.js} +2 -2
- package/src/layers/ColorbarLayer2d.js +97 -0
- package/src/{FilterbarLayer.js → layers/FilterbarLayer.js} +2 -2
- package/src/layers/HistogramLayer.js +212 -0
- package/src/layers/LinesLayer.js +199 -0
- package/src/layers/PointsLayer.js +114 -0
- package/src/layers/ScatterShared.js +142 -0
- package/src/{TileLayer.js → layers/TileLayer.js} +4 -4
- package/src/Axis.js +0 -48
- package/src/ColorAxisRegistry.js +0 -49
- package/src/ColorscaleRegistry.js +0 -52
- package/src/Float.js +0 -159
- package/src/Plot.js +0 -1073
- package/src/ScatterLayer.js +0 -287
- /package/src/{AxisLink.js → axes/AxisLink.js} +0 -0
- /package/src/{MatplotlibColorscales.js → colorscales/MatplotlibColorscales.js} +0 -0
- /package/src/{Data.js → core/Data.js} +0 -0
- /package/src/{LayerTypeRegistry.js → core/LayerTypeRegistry.js} +0 -0
package/src/ScatterLayer.js
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import { LayerType } from "./LayerType.js"
|
|
2
|
-
import { AXES } from "./AxisRegistry.js"
|
|
3
|
-
import { registerLayerType } from "./LayerTypeRegistry.js"
|
|
4
|
-
import { Data } from "./Data.js"
|
|
5
|
-
|
|
6
|
-
const POINTS_VERT = `
|
|
7
|
-
precision mediump float;
|
|
8
|
-
attribute float x;
|
|
9
|
-
attribute float y;
|
|
10
|
-
attribute float color_data;
|
|
11
|
-
uniform vec2 xDomain;
|
|
12
|
-
uniform vec2 yDomain;
|
|
13
|
-
uniform float xScaleType;
|
|
14
|
-
uniform float yScaleType;
|
|
15
|
-
varying float value;
|
|
16
|
-
void main() {
|
|
17
|
-
float nx = normalize_axis(x, xDomain, xScaleType);
|
|
18
|
-
float ny = normalize_axis(y, yDomain, yScaleType);
|
|
19
|
-
gl_Position = vec4(nx*2.0-1.0, ny*2.0-1.0, 0, 1);
|
|
20
|
-
gl_PointSize = 4.0;
|
|
21
|
-
value = color_data;
|
|
22
|
-
}
|
|
23
|
-
`
|
|
24
|
-
|
|
25
|
-
const POINTS_FRAG = `
|
|
26
|
-
precision mediump float;
|
|
27
|
-
uniform int colorscale;
|
|
28
|
-
uniform vec2 color_range;
|
|
29
|
-
uniform float color_scale_type;
|
|
30
|
-
uniform float alphaBlend;
|
|
31
|
-
varying float value;
|
|
32
|
-
void main() {
|
|
33
|
-
gl_FragColor = map_color_s(colorscale, color_range, value, color_scale_type, alphaBlend);
|
|
34
|
-
}
|
|
35
|
-
`
|
|
36
|
-
|
|
37
|
-
// Lines mode uses instanced rendering:
|
|
38
|
-
// - Template: 2 vertices with a_endPoint in {0.0, 1.0} (divisor=0 → interpolates)
|
|
39
|
-
// - Per-segment: a_x0/x1, a_y0/y1, a_v0/v1, a_seg0/seg1 (divisor=1 → constant per instance)
|
|
40
|
-
//
|
|
41
|
-
// Because a_v0 and a_v1 are instanced, they are the same at both template vertices for a given
|
|
42
|
-
// segment, so varyings set from them are constant across the line (no GPU interpolation).
|
|
43
|
-
// Only v_t (from a_endPoint) interpolates, giving the position along the segment.
|
|
44
|
-
//
|
|
45
|
-
// Segment boundary handling: when a_seg0 != a_seg1, collapse both template vertices to
|
|
46
|
-
// (a_x0, a_y0) producing a zero-length degenerate line that the rasterizer discards.
|
|
47
|
-
|
|
48
|
-
const LINES_VERT = `
|
|
49
|
-
precision mediump float;
|
|
50
|
-
attribute float a_endPoint;
|
|
51
|
-
attribute float a_x0, a_y0;
|
|
52
|
-
attribute float a_x1, a_y1;
|
|
53
|
-
attribute float a_v0, a_v1;
|
|
54
|
-
attribute float a_seg0, a_seg1;
|
|
55
|
-
uniform vec2 xDomain;
|
|
56
|
-
uniform vec2 yDomain;
|
|
57
|
-
uniform float xScaleType;
|
|
58
|
-
uniform float yScaleType;
|
|
59
|
-
varying float v_color_start;
|
|
60
|
-
varying float v_color_end;
|
|
61
|
-
varying float v_t;
|
|
62
|
-
void main() {
|
|
63
|
-
float same_seg = abs(a_seg0 - a_seg1) < 0.5 ? 1.0 : 0.0;
|
|
64
|
-
float t = same_seg * a_endPoint;
|
|
65
|
-
float x = mix(a_x0, a_x1, t);
|
|
66
|
-
float y = mix(a_y0, a_y1, t);
|
|
67
|
-
float nx = normalize_axis(x, xDomain, xScaleType);
|
|
68
|
-
float ny = normalize_axis(y, yDomain, yScaleType);
|
|
69
|
-
gl_Position = vec4(nx * 2.0 - 1.0, ny * 2.0 - 1.0, 0, 1);
|
|
70
|
-
v_color_start = a_v0;
|
|
71
|
-
v_color_end = a_v1;
|
|
72
|
-
v_t = a_endPoint;
|
|
73
|
-
}
|
|
74
|
-
`
|
|
75
|
-
|
|
76
|
-
const LINES_FRAG = `
|
|
77
|
-
precision mediump float;
|
|
78
|
-
uniform int colorscale;
|
|
79
|
-
uniform vec2 color_range;
|
|
80
|
-
uniform float color_scale_type;
|
|
81
|
-
uniform float alphaBlend;
|
|
82
|
-
uniform float u_lineColorMode;
|
|
83
|
-
varying float v_color_start;
|
|
84
|
-
varying float v_color_end;
|
|
85
|
-
varying float v_t;
|
|
86
|
-
void main() {
|
|
87
|
-
float value = u_lineColorMode > 0.5
|
|
88
|
-
? (v_t < 0.5 ? v_color_start : v_color_end)
|
|
89
|
-
: mix(v_color_start, v_color_end, v_t);
|
|
90
|
-
gl_FragColor = map_color_s(colorscale, color_range, value, color_scale_type, alphaBlend);
|
|
91
|
-
}
|
|
92
|
-
`
|
|
93
|
-
|
|
94
|
-
class ScatterLayerType extends LayerType {
|
|
95
|
-
constructor() {
|
|
96
|
-
super({ name: "scatter", vert: POINTS_VERT, frag: POINTS_FRAG })
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
_getAxisConfig(parameters, data) {
|
|
100
|
-
const d = Data.wrap(data)
|
|
101
|
-
const { xData, yData, vData, xAxis, yAxis } = parameters
|
|
102
|
-
return {
|
|
103
|
-
xAxis,
|
|
104
|
-
xAxisQuantityKind: d.getQuantityKind(xData) ?? xData,
|
|
105
|
-
yAxis,
|
|
106
|
-
yAxisQuantityKind: d.getQuantityKind(yData) ?? yData,
|
|
107
|
-
colorAxisQuantityKinds: [d.getQuantityKind(vData) ?? vData],
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
schema(data) {
|
|
112
|
-
const dataProperties = Data.wrap(data).columns()
|
|
113
|
-
return {
|
|
114
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
115
|
-
type: "object",
|
|
116
|
-
properties: {
|
|
117
|
-
xData: {
|
|
118
|
-
type: "string",
|
|
119
|
-
enum: dataProperties,
|
|
120
|
-
description: "Property name in data object for x coordinates"
|
|
121
|
-
},
|
|
122
|
-
yData: {
|
|
123
|
-
type: "string",
|
|
124
|
-
enum: dataProperties,
|
|
125
|
-
description: "Property name in data object for y coordinates"
|
|
126
|
-
},
|
|
127
|
-
vData: {
|
|
128
|
-
type: "string",
|
|
129
|
-
enum: dataProperties,
|
|
130
|
-
description: "Property name in data object for color values; also used as the color axis quantity kind"
|
|
131
|
-
},
|
|
132
|
-
xAxis: {
|
|
133
|
-
type: "string",
|
|
134
|
-
enum: AXES.filter(a => a.includes("x")),
|
|
135
|
-
default: "xaxis_bottom",
|
|
136
|
-
description: "Which x-axis to use for this layer"
|
|
137
|
-
},
|
|
138
|
-
yAxis: {
|
|
139
|
-
type: "string",
|
|
140
|
-
enum: AXES.filter(a => a.includes("y")),
|
|
141
|
-
default: "yaxis_left",
|
|
142
|
-
description: "Which y-axis to use for this layer"
|
|
143
|
-
},
|
|
144
|
-
alphaBlend: {
|
|
145
|
-
type: "boolean",
|
|
146
|
-
default: false,
|
|
147
|
-
description: "Map the normalized color value to alpha so low values fade to transparent"
|
|
148
|
-
},
|
|
149
|
-
mode: {
|
|
150
|
-
type: "string",
|
|
151
|
-
enum: ["points", "lines"],
|
|
152
|
-
default: "points",
|
|
153
|
-
description: "Render as individual points or connected lines"
|
|
154
|
-
},
|
|
155
|
-
lineSegmentIdData: {
|
|
156
|
-
type: "string",
|
|
157
|
-
enum: dataProperties,
|
|
158
|
-
description: "Column for segment IDs; only consecutive points sharing the same ID are connected"
|
|
159
|
-
},
|
|
160
|
-
lineColorMode: {
|
|
161
|
-
type: "string",
|
|
162
|
-
enum: ["gradient", "midpoint"],
|
|
163
|
-
default: "gradient",
|
|
164
|
-
description: "Color mode for lines: gradient interpolates vData linearly; midpoint uses each endpoint's color up to the segment center"
|
|
165
|
-
},
|
|
166
|
-
lineWidth: {
|
|
167
|
-
type: "number",
|
|
168
|
-
default: 1.0,
|
|
169
|
-
minimum: 1,
|
|
170
|
-
description: "Line width in pixels (note: browsers may clamp values above 1)"
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
required: ["xData", "yData", "vData"]
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
_createLayer(parameters, data) {
|
|
178
|
-
const d = Data.wrap(data)
|
|
179
|
-
const {
|
|
180
|
-
xData, yData, vData,
|
|
181
|
-
alphaBlend = false,
|
|
182
|
-
mode = "points",
|
|
183
|
-
lineSegmentIdData,
|
|
184
|
-
lineColorMode = "gradient",
|
|
185
|
-
lineWidth = 1.0,
|
|
186
|
-
} = parameters
|
|
187
|
-
|
|
188
|
-
const xQK = d.getQuantityKind(xData) ?? xData
|
|
189
|
-
const yQK = d.getQuantityKind(yData) ?? yData
|
|
190
|
-
const vQK = d.getQuantityKind(vData) ?? vData
|
|
191
|
-
|
|
192
|
-
const srcX = d.getData(xData)
|
|
193
|
-
const srcY = d.getData(yData)
|
|
194
|
-
const srcV = d.getData(vData)
|
|
195
|
-
|
|
196
|
-
if (!srcX) throw new Error(`Data column '${xData}' not found`)
|
|
197
|
-
if (!srcY) throw new Error(`Data column '${yData}' not found`)
|
|
198
|
-
if (!srcV) throw new Error(`Data column '${vData}' not found`)
|
|
199
|
-
|
|
200
|
-
const domains = {}
|
|
201
|
-
const xDomain = d.getDomain(xData)
|
|
202
|
-
const yDomain = d.getDomain(yData)
|
|
203
|
-
const vDomain = d.getDomain(vData)
|
|
204
|
-
if (xDomain) domains[xQK] = xDomain
|
|
205
|
-
if (yDomain) domains[yQK] = yDomain
|
|
206
|
-
if (vDomain) domains[vQK] = vDomain
|
|
207
|
-
|
|
208
|
-
const blendConfig = alphaBlend ? {
|
|
209
|
-
enable: true,
|
|
210
|
-
func: { srcRGB: 'src alpha', dstRGB: 'one minus src alpha', srcAlpha: 0, dstAlpha: 1 },
|
|
211
|
-
} : null
|
|
212
|
-
|
|
213
|
-
if (mode === "lines") {
|
|
214
|
-
const N = srcX.length
|
|
215
|
-
const segIds = lineSegmentIdData ? d.getData(lineSegmentIdData) : null
|
|
216
|
-
// Zero-init array used when no segment IDs: abs(0-0) < 0.5 → always same segment
|
|
217
|
-
const zeroSegs = new Float32Array(N - 1)
|
|
218
|
-
const seg0 = segIds ? segIds.subarray(0, N - 1) : zeroSegs
|
|
219
|
-
const seg1 = segIds ? segIds.subarray(1, N) : zeroSegs
|
|
220
|
-
|
|
221
|
-
return [{
|
|
222
|
-
attributes: {
|
|
223
|
-
a_endPoint: new Float32Array([0.0, 1.0]),
|
|
224
|
-
a_x0: srcX.subarray(0, N - 1),
|
|
225
|
-
a_x1: srcX.subarray(1, N),
|
|
226
|
-
a_y0: srcY.subarray(0, N - 1),
|
|
227
|
-
a_y1: srcY.subarray(1, N),
|
|
228
|
-
a_v0: srcV.subarray(0, N - 1),
|
|
229
|
-
a_v1: srcV.subarray(1, N),
|
|
230
|
-
a_seg0: seg0,
|
|
231
|
-
a_seg1: seg1,
|
|
232
|
-
},
|
|
233
|
-
attributeDivisors: {
|
|
234
|
-
a_x0: 1, a_x1: 1,
|
|
235
|
-
a_y0: 1, a_y1: 1,
|
|
236
|
-
a_v0: 1, a_v1: 1,
|
|
237
|
-
a_seg0: 1, a_seg1: 1,
|
|
238
|
-
},
|
|
239
|
-
uniforms: {
|
|
240
|
-
alphaBlend: alphaBlend ? 1.0 : 0.0,
|
|
241
|
-
u_lineColorMode: lineColorMode === "midpoint" ? 1.0 : 0.0,
|
|
242
|
-
},
|
|
243
|
-
nameMap: {
|
|
244
|
-
[`colorscale_${vQK}`]: 'colorscale',
|
|
245
|
-
[`color_range_${vQK}`]: 'color_range',
|
|
246
|
-
[`color_scale_type_${vQK}`]: 'color_scale_type',
|
|
247
|
-
},
|
|
248
|
-
domains,
|
|
249
|
-
primitive: "lines",
|
|
250
|
-
lineWidth,
|
|
251
|
-
vertexCount: 2,
|
|
252
|
-
instanceCount: N - 1,
|
|
253
|
-
blend: blendConfig,
|
|
254
|
-
}]
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Points mode — existing behaviour
|
|
258
|
-
return [{
|
|
259
|
-
attributes: { x: srcX, y: srcY, [vQK]: srcV },
|
|
260
|
-
uniforms: { alphaBlend: alphaBlend ? 1.0 : 0.0 },
|
|
261
|
-
domains,
|
|
262
|
-
nameMap: {
|
|
263
|
-
[vQK]: 'color_data',
|
|
264
|
-
[`colorscale_${vQK}`]: 'colorscale',
|
|
265
|
-
[`color_range_${vQK}`]: 'color_range',
|
|
266
|
-
[`color_scale_type_${vQK}`]: 'color_scale_type',
|
|
267
|
-
},
|
|
268
|
-
blend: blendConfig,
|
|
269
|
-
}]
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Swap vert/frag to the lines variants before letting the parent build the draw command,
|
|
273
|
-
// then restore. JS is single-threaded so the temporary swap is safe.
|
|
274
|
-
createDrawCommand(regl, layer) {
|
|
275
|
-
if (layer.primitive === "lines") {
|
|
276
|
-
this.vert = LINES_VERT
|
|
277
|
-
this.frag = LINES_FRAG
|
|
278
|
-
} else {
|
|
279
|
-
this.vert = POINTS_VERT
|
|
280
|
-
this.frag = POINTS_FRAG
|
|
281
|
-
}
|
|
282
|
-
return super.createDrawCommand(regl, layer)
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export const scatterLayerType = new ScatterLayerType()
|
|
287
|
-
registerLayerType("scatter", scatterLayerType)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|