gladly-plot 0.0.5 → 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 +320 -172
- package/src/axes/AxisLink.js +6 -2
- package/src/axes/AxisRegistry.js +116 -39
- package/src/axes/Camera.js +47 -0
- package/src/axes/ColorAxisRegistry.js +10 -2
- package/src/axes/FilterAxisRegistry.js +1 -1
- package/src/axes/TickLabelAtlas.js +99 -0
- package/src/axes/ZoomController.js +446 -124
- package/src/colorscales/ColorscaleRegistry.js +30 -10
- package/src/compute/ComputationRegistry.js +126 -184
- package/src/compute/axisFilter.js +21 -9
- package/src/compute/conv.js +64 -8
- package/src/compute/elementwise.js +72 -0
- package/src/compute/fft.js +106 -20
- package/src/compute/filter.js +105 -103
- package/src/compute/hist.js +247 -142
- package/src/compute/kde.js +64 -46
- 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 +22 -8
- package/src/core/LayerType.js +251 -92
- package/src/core/Plot.js +630 -152
- 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/floats/Float.js +56 -0
- package/src/index.js +16 -4
- package/src/layers/BarsLayer.js +168 -0
- package/src/layers/ColorbarLayer.js +10 -14
- package/src/layers/ColorbarLayer2d.js +13 -24
- package/src/layers/FilterbarLayer.js +4 -3
- package/src/layers/LinesLayer.js +108 -122
- package/src/layers/PointsLayer.js +73 -69
- package/src/layers/ScatterShared.js +62 -106
- package/src/layers/TileLayer.js +20 -16
- package/src/math/mat4.js +100 -0
- package/src/core/Data.js +0 -67
- package/src/layers/HistogramLayer.js +0 -212
|
@@ -3,6 +3,7 @@ import { registerLayerType } from "../core/LayerTypeRegistry.js"
|
|
|
3
3
|
|
|
4
4
|
export const filterbarLayerType = new LayerType({
|
|
5
5
|
name: "filterbar",
|
|
6
|
+
suppressWarnings: true,
|
|
6
7
|
|
|
7
8
|
getAxisConfig: function(parameters) {
|
|
8
9
|
const { filterAxis, orientation = "horizontal" } = parameters
|
|
@@ -16,15 +17,15 @@ export const filterbarLayerType = new LayerType({
|
|
|
16
17
|
|
|
17
18
|
// Nothing is rendered — vertexCount is always 0.
|
|
18
19
|
// These minimal shaders satisfy the WebGL compiler but never execute.
|
|
19
|
-
vert:
|
|
20
|
+
vert: `#version 300 es
|
|
20
21
|
precision mediump float;
|
|
21
22
|
uniform vec2 xDomain;
|
|
22
23
|
uniform vec2 yDomain;
|
|
23
24
|
void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }
|
|
24
25
|
`,
|
|
25
|
-
frag:
|
|
26
|
+
frag: `#version 300 es
|
|
26
27
|
precision mediump float;
|
|
27
|
-
void main() {
|
|
28
|
+
void main() { fragColor = gladly_apply_color(vec4(0.0, 0.0, 0.0, 0.0)); }
|
|
28
29
|
`,
|
|
29
30
|
|
|
30
31
|
schema: () => ({
|
package/src/layers/LinesLayer.js
CHANGED
|
@@ -1,117 +1,94 @@
|
|
|
1
1
|
// Lines mode uses instanced rendering:
|
|
2
|
-
// - Template: 2 vertices with a_endPoint in {0.0, 1.0} (divisor=0 →
|
|
3
|
-
// - Per-segment
|
|
4
|
-
//
|
|
5
|
-
// Because a_v0 and a_v1 are instanced, they are the same at both template vertices for a given
|
|
6
|
-
// segment, so varyings set from them are constant across the line (no GPU interpolation).
|
|
7
|
-
// Only v_t (from a_endPoint) interpolates, giving the position along the segment.
|
|
2
|
+
// - Template: 2 vertices with a_endPoint in {0.0, 1.0} (divisor=0 → per-vertex)
|
|
3
|
+
// - Per-segment data (x0/x1, y0/y1, v0/v1, seg0/seg1, f0/f1) sampled from GPU textures
|
|
4
|
+
// using a_pickId (= gl_InstanceID) + 0.0 or + 1.0 as the index.
|
|
8
5
|
//
|
|
9
6
|
// Segment boundary handling: when a_seg0 != a_seg1, collapse both template vertices to
|
|
10
7
|
// (a_x0, a_y0) producing a zero-length degenerate line that the rasterizer discards.
|
|
11
8
|
|
|
12
9
|
import { ScatterLayerTypeBase } from "./ScatterShared.js"
|
|
13
|
-
import { Data } from "../
|
|
10
|
+
import { Data } from "../data/Data.js"
|
|
14
11
|
import { registerLayerType } from "../core/LayerTypeRegistry.js"
|
|
12
|
+
import { EXPRESSION_REF_OPT, resolveQuantityKind, resolveExprToColumn } from "../compute/ComputationRegistry.js"
|
|
15
13
|
|
|
16
|
-
function makeLinesVert(hasFilter) {
|
|
17
|
-
return
|
|
14
|
+
function makeLinesVert(hasFilter, hasSegIds, hasV, hasV2, hasZ) {
|
|
15
|
+
return `#version 300 es
|
|
18
16
|
precision mediump float;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
${
|
|
17
|
+
in float a_endPoint;
|
|
18
|
+
in float a_x0;
|
|
19
|
+
in float a_y0;
|
|
20
|
+
${hasZ ? 'in float a_z0;\n in float a_z1;' : ''}
|
|
21
|
+
in float a_x1;
|
|
22
|
+
in float a_y1;
|
|
23
|
+
${hasV ? 'in float a_v0;\n in float a_v1;' : ''}
|
|
24
|
+
${hasV2 ? 'in float a_v20;\n in float a_v21;' : ''}
|
|
25
|
+
${hasSegIds ? 'in float a_seg0;\n in float a_seg1;' : ''}
|
|
26
|
+
${hasFilter ? 'in float a_f0;\n in float a_f1;' : ''}
|
|
26
27
|
uniform vec2 xDomain;
|
|
27
28
|
uniform vec2 yDomain;
|
|
28
29
|
uniform float xScaleType;
|
|
29
30
|
uniform float yScaleType;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
out float v_color_start;
|
|
32
|
+
out float v_color_end;
|
|
33
|
+
out float v_color2_start;
|
|
34
|
+
out float v_color2_end;
|
|
35
|
+
out float v_t;
|
|
35
36
|
void main() {
|
|
36
|
-
float same_seg = abs(a_seg0 - a_seg1) < 0.5 ? 1.0 : 0.0;
|
|
37
|
-
${hasFilter ? 'if (!
|
|
37
|
+
float same_seg = ${hasSegIds ? 'abs(a_seg0 - a_seg1) < 0.5 ? 1.0 : 0.0' : '1.0'};
|
|
38
|
+
${hasFilter ? 'if (!filter_(a_f0) || !filter_(a_f1)) same_seg = 0.0;' : ''}
|
|
38
39
|
float t = same_seg * a_endPoint;
|
|
39
40
|
float x = mix(a_x0, a_x1, t);
|
|
40
41
|
float y = mix(a_y0, a_y1, t);
|
|
41
|
-
float
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
v_color2_end = a_v21;
|
|
42
|
+
${hasZ ? 'float z = mix(a_z0, a_z1, t);\n gl_Position = plot_pos_3d(vec3(x, y, z));'
|
|
43
|
+
: 'gl_Position = plot_pos(vec2(x, y));'}
|
|
44
|
+
v_color_start = ${hasV ? 'a_v0' : '0.0'};
|
|
45
|
+
v_color_end = ${hasV ? 'a_v1' : '0.0'};
|
|
46
|
+
v_color2_start = ${hasV2 ? 'a_v20' : '0.0'};
|
|
47
|
+
v_color2_end = ${hasV2 ? 'a_v21' : '0.0'};
|
|
48
48
|
v_t = a_endPoint;
|
|
49
49
|
}
|
|
50
50
|
`
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
function makeLinesFrag(hasFirst, hasSecond) {
|
|
54
|
+
return `#version 300 es
|
|
54
55
|
precision mediump float;
|
|
55
|
-
|
|
56
|
-
uniform int colorscale;
|
|
57
|
-
uniform vec2 color_range;
|
|
58
|
-
uniform float color_scale_type;
|
|
59
|
-
|
|
60
|
-
uniform int colorscale2;
|
|
61
|
-
uniform vec2 color_range2;
|
|
62
|
-
uniform float color_scale_type2;
|
|
63
|
-
|
|
64
|
-
uniform float alphaBlend;
|
|
65
56
|
uniform float u_lineColorMode;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
varying float v_color2_end;
|
|
72
|
-
varying float v_t;
|
|
73
|
-
|
|
57
|
+
in float v_color_start;
|
|
58
|
+
in float v_color_end;
|
|
59
|
+
in float v_color2_start;
|
|
60
|
+
in float v_color2_end;
|
|
61
|
+
in float v_t;
|
|
74
62
|
void main() {
|
|
63
|
+
${!hasFirst ? `
|
|
64
|
+
fragColor = vec4(0.0, 0.0, 0.0, 1.0);` : hasSecond ? `
|
|
75
65
|
float value = u_lineColorMode > 0.5
|
|
76
66
|
? (v_t < 0.5 ? v_color_start : v_color_end)
|
|
77
67
|
: mix(v_color_start, v_color_end, v_t);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
colorscale2, color_range2, value2, color_scale_type2
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
if (alphaBlend > 0.5) {
|
|
90
|
-
gl_FragColor.a *= gl_FragColor.a;
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
gl_FragColor = map_color_s(colorscale, color_range, value, color_scale_type, alphaBlend);
|
|
94
|
-
}
|
|
68
|
+
float value2 = u_lineColorMode > 0.5
|
|
69
|
+
? (v_t < 0.5 ? v_color2_start : v_color2_end)
|
|
70
|
+
: mix(v_color2_start, v_color2_end, v_t);
|
|
71
|
+
fragColor = map_color_2d_(vec2(value, value2));` : `
|
|
72
|
+
float value = u_lineColorMode > 0.5
|
|
73
|
+
? (v_t < 0.5 ? v_color_start : v_color_end)
|
|
74
|
+
: mix(v_color_start, v_color_end, v_t);
|
|
75
|
+
fragColor = map_color_(value);`}
|
|
95
76
|
}
|
|
96
77
|
`
|
|
78
|
+
}
|
|
97
79
|
|
|
98
80
|
class LinesLayerType extends ScatterLayerTypeBase {
|
|
99
81
|
constructor() {
|
|
100
|
-
super({ name: "lines", vert: makeLinesVert(false), frag:
|
|
82
|
+
super({ name: "lines", vert: makeLinesVert(false, false, false, false), frag: makeLinesFrag(false, false) })
|
|
101
83
|
}
|
|
102
84
|
|
|
103
85
|
schema(data) {
|
|
104
|
-
const
|
|
86
|
+
const d = Data.wrap(data)
|
|
105
87
|
return {
|
|
106
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
107
88
|
type: "object",
|
|
108
89
|
properties: {
|
|
109
|
-
...this._commonSchemaProperties(
|
|
110
|
-
lineSegmentIdData:
|
|
111
|
-
type: "string",
|
|
112
|
-
enum: dataProperties,
|
|
113
|
-
description: "Column for segment IDs; only consecutive points sharing the same ID are connected"
|
|
114
|
-
},
|
|
90
|
+
...this._commonSchemaProperties(d),
|
|
91
|
+
lineSegmentIdData: EXPRESSION_REF_OPT,
|
|
115
92
|
lineColorMode: {
|
|
116
93
|
type: "string",
|
|
117
94
|
enum: ["gradient", "midpoint"],
|
|
@@ -125,73 +102,82 @@ class LinesLayerType extends ScatterLayerTypeBase {
|
|
|
125
102
|
description: "Line width in pixels (note: browsers may clamp values above 1)"
|
|
126
103
|
}
|
|
127
104
|
},
|
|
128
|
-
required: ["xData", "yData", "
|
|
105
|
+
required: ["xData", "yData", "zData", "zAxis"]
|
|
129
106
|
}
|
|
130
107
|
}
|
|
131
108
|
|
|
132
|
-
_createLayer(parameters, data) {
|
|
109
|
+
async _createLayer(regl, parameters, data, plot) {
|
|
133
110
|
const d = Data.wrap(data)
|
|
134
|
-
const { lineSegmentIdData, lineColorMode = "gradient", lineWidth = 1.0 } = parameters
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
const
|
|
111
|
+
const { lineSegmentIdData: lineSegmentIdDataRaw, lineColorMode = "gradient", lineWidth = 1.0 } = parameters
|
|
112
|
+
const lineSegmentIdData = (lineSegmentIdDataRaw == null || lineSegmentIdDataRaw === "none") ? null : lineSegmentIdDataRaw
|
|
113
|
+
const { xData, yData, zData: zDataOrig, vData: vDataOrig, vData2: vData2Orig, fData: fDataOrig } = parameters
|
|
114
|
+
const zData = (zDataOrig == null || zDataOrig === "none") ? null : zDataOrig
|
|
115
|
+
const vData = (vDataOrig == null || vDataOrig === "none") ? null : vDataOrig
|
|
116
|
+
const vData2 = (vData2Orig == null || vData2Orig === "none") ? null : vData2Orig
|
|
117
|
+
const fData = (fDataOrig == null || fDataOrig === "none") ? null : fDataOrig
|
|
118
|
+
|
|
119
|
+
const xQK = resolveQuantityKind(xData, d) ?? xData
|
|
120
|
+
const yQK = resolveQuantityKind(yData, d) ?? yData
|
|
121
|
+
const zQK = zData ? (resolveQuantityKind(zData, d) ?? zData) : null
|
|
122
|
+
const vQK = vData ? (resolveQuantityKind(vData, d) ?? vData) : null
|
|
123
|
+
const vQK2 = vData2 ? (resolveQuantityKind(vData2, d) ?? vData2) : null
|
|
124
|
+
|
|
125
|
+
const colX = await resolveExprToColumn(xData, d, regl, plot)
|
|
126
|
+
const colY = await resolveExprToColumn(yData, d, regl, plot)
|
|
127
|
+
const colZ = zData ? await resolveExprToColumn(zData, d, regl, plot) : null
|
|
128
|
+
const colV = vData ? await resolveExprToColumn(vData, d, regl, plot) : null
|
|
129
|
+
const colV2 = vData2 ? await resolveExprToColumn(vData2, d, regl, plot) : null
|
|
130
|
+
const colF = fData ? await resolveExprToColumn(fData, d, regl, plot) : null
|
|
131
|
+
const colSeg = lineSegmentIdData ? await resolveExprToColumn(lineSegmentIdData, d, regl, plot) : null
|
|
132
|
+
|
|
133
|
+
if (!colX) throw new Error(`Data column '${xData}' not found`)
|
|
134
|
+
if (!colY) throw new Error(`Data column '${yData}' not found`)
|
|
135
|
+
|
|
136
|
+
const N = colX.length
|
|
137
|
+
const domains = this._buildDomains(d, xData, yData, zData, vData, vData2, xQK, yQK, zQK, vQK, vQK2)
|
|
138
|
+
|
|
139
|
+
// For vData: if a string column, offset-sample start/end; if a computed expression,
|
|
140
|
+
// pass through as-is (both endpoints get the same value, matching old behaviour).
|
|
141
|
+
const vAttr0 = vData ? (colV ? colV.withOffset('0.0') : vData) : null
|
|
142
|
+
const vAttr1 = vData ? (colV ? colV.withOffset('1.0') : vData) : null
|
|
143
|
+
const vAttr20 = vData2 ? (colV2 ? colV2.withOffset('0.0') : vData2) : null
|
|
144
|
+
const vAttr21 = vData2 ? (colV2 ? colV2.withOffset('1.0') : vData2) : null
|
|
147
145
|
|
|
148
146
|
return [{
|
|
149
147
|
attributes: {
|
|
150
148
|
a_endPoint: new Float32Array([0.0, 1.0]),
|
|
151
|
-
a_x0:
|
|
152
|
-
a_x1:
|
|
153
|
-
a_y0:
|
|
154
|
-
a_y1:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
a_seg1: seg1,
|
|
161
|
-
...(fData ? {
|
|
162
|
-
a_f0: srcF.subarray(0, N - 1),
|
|
163
|
-
a_f1: srcF.subarray(1, N),
|
|
164
|
-
} : {}),
|
|
165
|
-
},
|
|
166
|
-
attributeDivisors: {
|
|
167
|
-
a_x0: 1, a_x1: 1,
|
|
168
|
-
a_y0: 1, a_y1: 1,
|
|
169
|
-
a_v0: 1, a_v1: 1,
|
|
170
|
-
a_v20: 1, a_v21: 1,
|
|
171
|
-
a_seg0: 1, a_seg1: 1,
|
|
172
|
-
...(fData ? { a_f0: 1, a_f1: 1 } : {}),
|
|
149
|
+
a_x0: colX.withOffset('0.0'),
|
|
150
|
+
a_x1: colX.withOffset('1.0'),
|
|
151
|
+
a_y0: colY.withOffset('0.0'),
|
|
152
|
+
a_y1: colY.withOffset('1.0'),
|
|
153
|
+
...(colZ ? { a_z0: colZ.withOffset('0.0'), a_z1: colZ.withOffset('1.0') } : {}),
|
|
154
|
+
...(vAttr0 !== null ? { a_v0: vAttr0, a_v1: vAttr1 } : {}),
|
|
155
|
+
...(vAttr20 !== null ? { a_v20: vAttr20, a_v21: vAttr21 } : {}),
|
|
156
|
+
...(colSeg ? { a_seg0: colSeg.withOffset('0.0'), a_seg1: colSeg.withOffset('1.0') } : {}),
|
|
157
|
+
...(fData ? { a_f0: colF.withOffset('0.0'), a_f1: colF.withOffset('1.0') } : {}),
|
|
173
158
|
},
|
|
174
159
|
uniforms: {
|
|
175
|
-
alphaBlend: alphaBlend ? 1.0 : 0.0,
|
|
176
160
|
u_lineColorMode: lineColorMode === "midpoint" ? 1.0 : 0.0,
|
|
177
|
-
u_useSecondColor: useSecond,
|
|
178
|
-
...(vData ? {} : { colorscale: 0, color_range: [0, 1], color_scale_type: 0.0 }),
|
|
179
|
-
...(vData2 ? {} : { colorscale2: 0, color_range2: [0, 1], color_scale_type2: 0.0 })
|
|
180
161
|
},
|
|
181
|
-
nameMap: this._buildNameMap(vData, vQK, vData2, vQK2, fData, fQK),
|
|
182
162
|
domains,
|
|
183
163
|
primitive: "lines",
|
|
184
164
|
lineWidth,
|
|
185
165
|
vertexCount: 2,
|
|
186
166
|
instanceCount: N - 1,
|
|
187
|
-
blend: blendConfig,
|
|
188
167
|
}]
|
|
189
168
|
}
|
|
190
169
|
|
|
191
|
-
createDrawCommand(regl, layer) {
|
|
192
|
-
const hasFilter
|
|
193
|
-
|
|
194
|
-
|
|
170
|
+
async createDrawCommand(regl, layer, plot) {
|
|
171
|
+
const hasFilter = Object.keys(layer.filterAxes).length > 0
|
|
172
|
+
const hasFirst = '' in layer.colorAxes
|
|
173
|
+
const hasSecond = '2' in layer.colorAxes
|
|
174
|
+
const hasSegIds = 'a_seg0' in layer.attributes
|
|
175
|
+
const hasV = 'a_v0' in layer.attributes
|
|
176
|
+
const hasV2 = 'a_v20' in layer.attributes
|
|
177
|
+
const hasZ = 'a_z0' in layer.attributes
|
|
178
|
+
this.vert = makeLinesVert(hasFilter, hasSegIds, hasV, hasV2, hasZ)
|
|
179
|
+
this.frag = makeLinesFrag(hasFirst, hasSecond)
|
|
180
|
+
return await super.createDrawCommand(regl, layer, plot)
|
|
195
181
|
}
|
|
196
182
|
}
|
|
197
183
|
|
|
@@ -1,112 +1,116 @@
|
|
|
1
1
|
import { ScatterLayerTypeBase } from "./ScatterShared.js"
|
|
2
|
-
import { Data } from "../
|
|
2
|
+
import { Data } from "../data/Data.js"
|
|
3
3
|
import { registerLayerType } from "../core/LayerTypeRegistry.js"
|
|
4
|
+
import { resolveQuantityKind } from "../compute/ComputationRegistry.js"
|
|
4
5
|
|
|
5
|
-
function makePointsVert(hasFilter) {
|
|
6
|
-
return
|
|
6
|
+
function makePointsVert(hasFilter, hasZ) {
|
|
7
|
+
return `#version 300 es
|
|
7
8
|
precision mediump float;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
in float x;
|
|
10
|
+
in float y;
|
|
11
|
+
${hasZ ? 'in float z;' : ''}
|
|
12
|
+
in float color_data;
|
|
13
|
+
in float color_data2;
|
|
14
|
+
${hasFilter ? 'in float filter_data;' : ''}
|
|
13
15
|
uniform vec2 xDomain;
|
|
14
16
|
uniform vec2 yDomain;
|
|
15
17
|
uniform float xScaleType;
|
|
16
18
|
uniform float yScaleType;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
uniform float u_pointSize;
|
|
20
|
+
out float value;
|
|
21
|
+
out float value2;
|
|
19
22
|
void main() {
|
|
20
|
-
${hasFilter ? 'if (!
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
gl_Position = vec4(nx*2.0-1.0, ny*2.0-1.0, 0, 1);
|
|
24
|
-
gl_PointSize = 4.0;
|
|
23
|
+
${hasFilter ? 'if (!filter_(filter_data)) { gl_Position = vec4(2.0, 2.0, 2.0, 1.0); return; }' : ''}
|
|
24
|
+
${hasZ ? 'gl_Position = plot_pos_3d(vec3(x, y, z));' : 'gl_Position = plot_pos(vec2(x, y));'}
|
|
25
|
+
gl_PointSize = u_pointSize;
|
|
25
26
|
value = color_data;
|
|
26
27
|
value2 = color_data2;
|
|
27
28
|
}
|
|
28
29
|
`
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
function makePointsFrag(hasFirst, hasSecond) {
|
|
33
|
+
return `#version 300 es
|
|
32
34
|
precision mediump float;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
uniform float color_scale_type;
|
|
36
|
-
|
|
37
|
-
uniform int colorscale2;
|
|
38
|
-
uniform vec2 color_range2;
|
|
39
|
-
uniform float color_scale_type2;
|
|
40
|
-
|
|
41
|
-
uniform float alphaBlend;
|
|
42
|
-
uniform float u_useSecondColor;
|
|
43
|
-
|
|
44
|
-
varying float value;
|
|
45
|
-
varying float value2;
|
|
46
|
-
|
|
35
|
+
in float value;
|
|
36
|
+
in float value2;
|
|
47
37
|
void main() {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
gl_FragColor = map_color_s(colorscale, color_range, value, color_scale_type, alphaBlend);
|
|
58
|
-
}
|
|
38
|
+
${hasFirst
|
|
39
|
+
? (hasSecond
|
|
40
|
+
? 'fragColor = map_color_2d_(vec2(value, value2));'
|
|
41
|
+
: 'fragColor = map_color_2d_x_(value);')
|
|
42
|
+
: (hasSecond
|
|
43
|
+
? 'fragColor = map_color_2d_y_2(value2);'
|
|
44
|
+
: 'fragColor = vec4(0.0, 0.0, 0.0, 1.0);')}
|
|
59
45
|
}
|
|
60
46
|
`
|
|
47
|
+
}
|
|
61
48
|
|
|
62
49
|
class PointsLayerType extends ScatterLayerTypeBase {
|
|
63
50
|
constructor() {
|
|
64
|
-
super({ name: "points", vert: makePointsVert(false), frag:
|
|
51
|
+
super({ name: "points", vert: makePointsVert(false), frag: makePointsFrag(false) })
|
|
65
52
|
}
|
|
66
53
|
|
|
67
54
|
schema(data) {
|
|
68
|
-
const
|
|
55
|
+
const d = Data.wrap(data)
|
|
69
56
|
return {
|
|
70
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
71
57
|
type: "object",
|
|
72
|
-
properties:
|
|
73
|
-
|
|
58
|
+
properties: {
|
|
59
|
+
...this._commonSchemaProperties(d),
|
|
60
|
+
pointSize: { type: "integer", default: 4, minimum: 1 },
|
|
61
|
+
},
|
|
62
|
+
required: ["xData", "yData", "zData", "zAxis", "pointSize"]
|
|
74
63
|
}
|
|
75
64
|
}
|
|
76
65
|
|
|
77
|
-
_createLayer(parameters, data) {
|
|
66
|
+
_createLayer(regl, parameters, data, plot) {
|
|
78
67
|
const d = Data.wrap(data)
|
|
79
|
-
const {
|
|
80
|
-
|
|
68
|
+
const { vData: vDataRaw, vData2: vData2Raw, fData: fDataRaw, zData: zDataRaw } = parameters
|
|
69
|
+
const vDataIn = (vDataRaw == null || vDataRaw === "none") ? null : vDataRaw
|
|
70
|
+
const vData2In = (vData2Raw == null || vData2Raw === "none") ? null : vData2Raw
|
|
71
|
+
const fData = (fDataRaw == null || fDataRaw === "none") ? null : fDataRaw
|
|
72
|
+
const zData = (zDataRaw == null || zDataRaw === "none") ? null : zDataRaw
|
|
73
|
+
const vData = vDataIn
|
|
74
|
+
const vData2 = vData2In
|
|
75
|
+
|
|
76
|
+
const xQK = resolveQuantityKind(parameters.xData, d) ?? undefined
|
|
77
|
+
const yQK = resolveQuantityKind(parameters.yData, d) ?? undefined
|
|
78
|
+
const zQK = zData ? (resolveQuantityKind(zData, d) ?? undefined) : undefined
|
|
79
|
+
const vQK = vData ? resolveQuantityKind(vData, d) : null
|
|
80
|
+
const vQK2 = vData2 ? resolveQuantityKind(vData2, d) : null
|
|
81
81
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const domains = this._buildDomains(d, parameters.xData, parameters.yData, zData, vData, vData2, xQK, yQK, zQK, vQK, vQK2)
|
|
83
|
+
|
|
84
|
+
// Vertex count: read from data when xData is a plain column name so that
|
|
85
|
+
// Plot.render() can determine how many vertices to draw even when other
|
|
86
|
+
// attributes are computed expressions resolved at draw time.
|
|
87
|
+
const vertexCount = typeof parameters.xData === 'string'
|
|
88
|
+
? (d.getData(parameters.xData)?.length ?? null)
|
|
89
|
+
: null
|
|
85
90
|
|
|
86
91
|
return [{
|
|
87
92
|
attributes: {
|
|
88
|
-
x:
|
|
89
|
-
y:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
uniforms: {
|
|
95
|
-
alphaBlend: alphaBlend ? 1.0 : 0.0,
|
|
96
|
-
u_useSecondColor: useSecond,
|
|
97
|
-
...(vData ? {} : { colorscale: 0, color_range: [0, 1], color_scale_type: 0.0 }),
|
|
98
|
-
...(vData2 ? {} : { colorscale2: 0, color_range2: [0, 1], color_scale_type2: 0.0 })
|
|
93
|
+
x: parameters.xData,
|
|
94
|
+
y: parameters.yData,
|
|
95
|
+
...(zData !== null ? { z: zData } : {}),
|
|
96
|
+
color_data: vData !== null ? vData : new Float32Array(vertexCount ?? 0).fill(NaN),
|
|
97
|
+
color_data2: vData2 !== null ? vData2 : new Float32Array(vertexCount ?? 0).fill(NaN),
|
|
98
|
+
...(fData != null ? { filter_data: fData } : {}),
|
|
99
99
|
},
|
|
100
|
+
uniforms: { u_pointSize: () => parameters.pointSize ?? 4 },
|
|
100
101
|
domains,
|
|
101
|
-
|
|
102
|
-
blend: blendConfig,
|
|
102
|
+
vertexCount,
|
|
103
103
|
}]
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
createDrawCommand(regl, layer) {
|
|
107
|
-
const hasFilter = layer.filterAxes.length > 0
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
async createDrawCommand(regl, layer, plot) {
|
|
107
|
+
const hasFilter = Object.keys(layer.filterAxes).length > 0
|
|
108
|
+
const hasFirst = '' in layer.colorAxes
|
|
109
|
+
const hasSecond = '2' in layer.colorAxes
|
|
110
|
+
const hasZ = 'z' in layer.attributes
|
|
111
|
+
this.vert = makePointsVert(hasFilter, hasZ)
|
|
112
|
+
this.frag = makePointsFrag(hasFirst, hasSecond)
|
|
113
|
+
return await super.createDrawCommand(regl, layer, plot)
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
|