@genome-spy/core 0.43.2 → 0.44.0
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/dist/bundle/index.es.js +5621 -5346
- package/dist/bundle/index.js +156 -104
- package/dist/schema.json +412 -43
- package/dist/src/data/sources/lazy/axisTickSource.d.ts +1 -1
- package/dist/src/data/sources/lazy/axisTickSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/axisTickSource.js +2 -2
- package/dist/src/data/sources/lazy/bigBedSource.js +70 -28
- package/dist/src/data/sources/lazy/bigWigSource.d.ts +6 -0
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +3 -5
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.js +1 -1
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts +7 -12
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +33 -29
- package/dist/src/data/transforms/filterScoredLabels.js +1 -1
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +16 -6
- package/dist/src/genomeSpy.d.ts +1 -0
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +108 -6
- package/dist/src/gl/glslScaleGenerator.d.ts +23 -3
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/gl/glslScaleGenerator.js +137 -42
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +5 -7
- package/dist/src/marks/link.common.glsl.js +2 -0
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +19 -9
- package/dist/src/marks/link.vertex.glsl.js +1 -1
- package/dist/src/marks/mark.d.ts +19 -17
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +181 -120
- package/dist/src/marks/point.common.glsl.js +1 -1
- package/dist/src/marks/rect.common.glsl.js +2 -0
- package/dist/src/marks/rect.d.ts.map +1 -1
- package/dist/src/marks/rect.js +12 -12
- package/dist/src/marks/rect.vertex.glsl.js +1 -1
- package/dist/src/marks/rule.common.glsl.js +1 -1
- package/dist/src/marks/rule.js +2 -2
- package/dist/src/marks/text.common.glsl.js +1 -1
- package/dist/src/marks/text.js +2 -2
- package/dist/src/paramBroker.d.ts +19 -3
- package/dist/src/paramBroker.d.ts.map +1 -1
- package/dist/src/paramBroker.js +18 -2
- package/dist/src/spec/channel.d.ts +4 -3
- package/dist/src/spec/mark.d.ts +17 -25
- package/dist/src/spec/parameter.d.ts +123 -0
- package/dist/src/spec/root.d.ts +9 -0
- package/dist/src/spec/scale.d.ts +2 -1
- package/dist/src/spec/view.d.ts +1 -1
- package/dist/src/types/scaleResolutionApi.d.ts +7 -3
- package/dist/src/utils/expression.d.ts +2 -2
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/expression.js +3 -3
- package/dist/src/view/axisView.js +3 -3
- package/dist/src/view/scaleResolution.d.ts +8 -18
- package/dist/src/view/scaleResolution.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.js +220 -126
- package/dist/src/view/scaleResolution.test.js +7 -7
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +10 -3
- package/dist/src/view/view.js +2 -2
- package/package.json +2 -2
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
} from "../encoder/encoder.js";
|
|
19
19
|
import { asArray, peek } from "../utils/arrayUtils.js";
|
|
20
20
|
import { InternMap } from "internmap";
|
|
21
|
+
import { isExprRef } from "../marks/mark.js";
|
|
22
|
+
import scaleNull from "../utils/scaleNull.js";
|
|
21
23
|
|
|
22
24
|
export const ATTRIBUTE_PREFIX = "attr_";
|
|
23
25
|
export const DOMAIN_PREFIX = "uDomain_";
|
|
@@ -50,11 +52,12 @@ function splitScaleType(type) {
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
/**
|
|
55
|
+
* Generates GLSL code for a constant value.
|
|
53
56
|
*
|
|
54
57
|
* @param {Channel} channel
|
|
55
58
|
* @param {number | number[] | string | boolean} value
|
|
56
59
|
*/
|
|
57
|
-
export function
|
|
60
|
+
export function generateConstantValueGlsl(channel, value) {
|
|
58
61
|
/** @type {VectorizedValue} */
|
|
59
62
|
let vec;
|
|
60
63
|
if (isDiscreteChannel(channel)) {
|
|
@@ -81,8 +84,6 @@ export function generateValueGlsl(channel, value) {
|
|
|
81
84
|
vec = vectorize(value);
|
|
82
85
|
}
|
|
83
86
|
|
|
84
|
-
// These could also be passed as uniforms because GPU drivers often handle
|
|
85
|
-
// uniforms as constants and recompile the shader to eliminate dead code etc.
|
|
86
87
|
let glsl = `
|
|
87
88
|
#define ${channel}_DEFINED
|
|
88
89
|
${vec.type} ${SCALED_FUNCTION_PREFIX}${channel}() {
|
|
@@ -93,16 +94,52 @@ ${vec.type} ${SCALED_FUNCTION_PREFIX}${channel}() {
|
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
/**
|
|
97
|
+
* Generates GLSL code for a dynamic, parameter-driven values. These are mainly
|
|
98
|
+
* used as dynamic mark properties that map to encoding channels.
|
|
96
99
|
*
|
|
97
100
|
* @param {Channel} channel
|
|
98
|
-
|
|
101
|
+
*/
|
|
102
|
+
export function generateDynamicValueGlslAndUniform(channel) {
|
|
103
|
+
let dataType = "float";
|
|
104
|
+
/** @type {(x: any) => any} */
|
|
105
|
+
let adjuster = (x) => x;
|
|
106
|
+
|
|
107
|
+
if (isColorChannel(channel)) {
|
|
108
|
+
dataType = "vec3";
|
|
109
|
+
adjuster = (x) => cssColorToArray(x);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const uniformName = `u${capitalize(channel)}`;
|
|
113
|
+
|
|
114
|
+
const uniformGlsl = ` // Dynamic value\n uniform ${dataType} ${uniformName};`;
|
|
115
|
+
|
|
116
|
+
let scaleGlsl = `
|
|
117
|
+
#define ${channel}_DEFINED
|
|
118
|
+
${dataType} ${SCALED_FUNCTION_PREFIX}${channel}() {
|
|
119
|
+
// Dynamic value
|
|
120
|
+
return ${uniformName};
|
|
121
|
+
}`;
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
channel,
|
|
125
|
+
uniformName,
|
|
126
|
+
uniformGlsl,
|
|
127
|
+
scaleGlsl,
|
|
128
|
+
adjuster,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
*
|
|
134
|
+
* @param {Channel} channel
|
|
135
|
+
* @param {import("../view/scaleResolution.js").default} scaleResolution TODO: typing
|
|
99
136
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
100
137
|
* @param {Channel[]} [sharedQuantitativeChannels] Channels that share the same quantitative field
|
|
101
138
|
*/
|
|
102
139
|
// eslint-disable-next-line complexity
|
|
103
140
|
export function generateScaleGlsl(
|
|
104
141
|
channel,
|
|
105
|
-
|
|
142
|
+
scaleResolution,
|
|
106
143
|
channelDef,
|
|
107
144
|
sharedQuantitativeChannels = [channel]
|
|
108
145
|
) {
|
|
@@ -112,9 +149,11 @@ export function generateScaleGlsl(
|
|
|
112
149
|
);
|
|
113
150
|
}
|
|
114
151
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Typecast to any to make it easier to handle all the different scale variants
|
|
154
|
+
* @type {any}
|
|
155
|
+
*/
|
|
156
|
+
const scale = scaleResolution ? scaleResolution.scale : scaleNull();
|
|
118
157
|
|
|
119
158
|
const primary = getPrimaryChannel(channel);
|
|
120
159
|
const attributeName =
|
|
@@ -243,24 +282,35 @@ export function generateScaleGlsl(
|
|
|
243
282
|
);
|
|
244
283
|
}
|
|
245
284
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
285
|
+
const range = getRangeForGlsl(scale, channel);
|
|
286
|
+
|
|
287
|
+
/** @type {string} */
|
|
288
|
+
let rangeUniform;
|
|
289
|
+
|
|
290
|
+
if (range && channel == primary) {
|
|
291
|
+
const rangeProp = scale.props.range ?? [];
|
|
292
|
+
// Maybe the scale could be annotated with a "dynamicRange" property or something
|
|
293
|
+
if (isExprRef(rangeProp) || rangeProp.some(isExprRef)) {
|
|
294
|
+
// TODO: should check that we don't have an ordinal range here as it should be
|
|
295
|
+
// handled using a texture.
|
|
296
|
+
if (range.length < 1 || range.length > 4) {
|
|
297
|
+
// TODO: Use an array instead of (float|vec[234]). This is likely to be a rare case, however.
|
|
298
|
+
throw new Error(
|
|
299
|
+
`A range with ExprRefs must have 1-4 elements, not ${
|
|
300
|
+
range.length
|
|
301
|
+
}! Range: ${JSON.stringify(range)}`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
rangeUniform = ` uniform ${getFloatVectorType(
|
|
305
|
+
range.length
|
|
306
|
+
)} ${rangeName};`;
|
|
307
|
+
} else if (range.length && range.every(isNumber)) {
|
|
308
|
+
const vectorizedRange = vectorizeRange(range);
|
|
309
|
+
|
|
310
|
+
glsl.push(
|
|
311
|
+
`const ${vectorizedRange.type} ${rangeName} = ${vectorizedRange};`
|
|
312
|
+
);
|
|
313
|
+
}
|
|
264
314
|
}
|
|
265
315
|
|
|
266
316
|
const returnType = isColorChannel(channel) ? "vec3" : "float";
|
|
@@ -290,9 +340,9 @@ export function generateScaleGlsl(
|
|
|
290
340
|
interpolate = `getDiscreteColor(${textureUniformName}, int(transformed)).r`;
|
|
291
341
|
}
|
|
292
342
|
|
|
293
|
-
const attributeGlsl = isDatumDef(channelDef)
|
|
294
|
-
? `uniform highp ${attributeType} ${attributeName};`
|
|
295
|
-
: `in highp ${attributeType} ${attributeName}
|
|
343
|
+
const [attributeGlsl, markUniformGlsl] = isDatumDef(channelDef)
|
|
344
|
+
? [undefined, ` uniform highp ${attributeType} ${attributeName};`]
|
|
345
|
+
: [`in highp ${attributeType} ${attributeName};`, undefined];
|
|
296
346
|
|
|
297
347
|
/** @type {string[]} Channel's scale function*/
|
|
298
348
|
const scaleBody = [];
|
|
@@ -374,14 +424,20 @@ ${returnType} ${SCALED_FUNCTION_PREFIX}${channel}() {
|
|
|
374
424
|
? domainLength
|
|
375
425
|
: 2;
|
|
376
426
|
domainUniform = hp
|
|
377
|
-
? `highp vec3 ${domainUniformName};`
|
|
378
|
-
: `mediump float ${domainUniformName}[${length}];`;
|
|
427
|
+
? ` highp vec3 ${domainUniformName};`
|
|
428
|
+
: ` mediump float ${domainUniformName}[${length}];`;
|
|
379
429
|
}
|
|
380
430
|
|
|
381
431
|
return {
|
|
432
|
+
attributeName,
|
|
382
433
|
attributeGlsl,
|
|
434
|
+
// Ends up in the Mark uniform block
|
|
435
|
+
markUniformGlsl,
|
|
383
436
|
glsl: concatenated,
|
|
437
|
+
domainUniformName,
|
|
384
438
|
domainUniform,
|
|
439
|
+
rangeName,
|
|
440
|
+
rangeUniform,
|
|
385
441
|
};
|
|
386
442
|
}
|
|
387
443
|
|
|
@@ -426,26 +482,43 @@ function vectorize(value) {
|
|
|
426
482
|
throw new Error("Invalid number of components: " + numComponents);
|
|
427
483
|
}
|
|
428
484
|
|
|
429
|
-
|
|
430
|
-
|
|
485
|
+
const type = getFloatVectorType(numComponents);
|
|
486
|
+
const str = `${type}(${value.map(toDecimal).join(", ")})`;
|
|
431
487
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
488
|
+
return Object.assign(str, { type, numComponents });
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* @param {number} numComponents
|
|
493
|
+
*/
|
|
494
|
+
function getFloatVectorType(numComponents) {
|
|
495
|
+
switch (numComponents) {
|
|
496
|
+
case 1:
|
|
497
|
+
return "float";
|
|
498
|
+
case 2:
|
|
499
|
+
return "vec2";
|
|
500
|
+
case 3:
|
|
501
|
+
return "vec3";
|
|
502
|
+
case 4:
|
|
503
|
+
return "vec4";
|
|
504
|
+
default:
|
|
505
|
+
throw new Error("Invalid number of components: " + numComponents);
|
|
438
506
|
}
|
|
507
|
+
}
|
|
439
508
|
|
|
440
|
-
|
|
509
|
+
/**
|
|
510
|
+
* @param {string} color
|
|
511
|
+
*/
|
|
512
|
+
function cssColorToArray(color) {
|
|
513
|
+
const rgb = d3color(color).rgb();
|
|
514
|
+
return [rgb.r, rgb.g, rgb.b].map((x) => x / 255);
|
|
441
515
|
}
|
|
442
516
|
|
|
443
517
|
/**
|
|
444
518
|
* @param {string} color
|
|
445
519
|
*/
|
|
446
520
|
function vectorizeCssColor(color) {
|
|
447
|
-
|
|
448
|
-
return vectorize([rgb.r, rgb.g, rgb.b].map((x) => x / 255));
|
|
521
|
+
return vectorize(cssColorToArray(color));
|
|
449
522
|
}
|
|
450
523
|
|
|
451
524
|
/**
|
|
@@ -591,3 +664,25 @@ export function dedupeEncodingFields(encoders) {
|
|
|
591
664
|
export function makeAttributeName(channel) {
|
|
592
665
|
return asArray(channel).join("_");
|
|
593
666
|
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* @param {string} str
|
|
670
|
+
*/
|
|
671
|
+
function capitalize(str) {
|
|
672
|
+
return str[0].toUpperCase() + str.slice(1);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* N.B. Interpolating scales require unit range
|
|
677
|
+
* TODO: Reverse
|
|
678
|
+
* @param {any} scale
|
|
679
|
+
* @param {Channel} channel
|
|
680
|
+
* @returns {number[]}
|
|
681
|
+
*/
|
|
682
|
+
export const getRangeForGlsl = (scale, channel) =>
|
|
683
|
+
isInterpolating(scale.type) ||
|
|
684
|
+
(isContinuous(scale.type) && isColorChannel(channel))
|
|
685
|
+
? [0, 1]
|
|
686
|
+
: scale.range
|
|
687
|
+
? scale.range()
|
|
688
|
+
: undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"AA4ZA;;;;GAIG;AACH,kCAJW,sBAAsB,gBACtB,WAAW,kBACX,WAAW;;;;;;EA8CrB;AAED;;;;;GAKG;AACH,0CALW,qBAAqB,WACrB,KAAK,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,OAC7C,MAAM,EAAE,GAAG,eAAe,YAC1B,YAAY,gBAYtB;AAjcD;IACI;;;;;;;OAOG;IACH,uBANW,WAAW,eACX,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,eAGrC,MAAM,EAmFhB;IAhFG,wBAA2B;IAC3B;;;MAKO;IAEP,uCAAuC;IACvC,cADW,IAAI,MAAM,EAAE,WAAW,CAAC,CACN;IAE7B,kFAAkF;IAClF,eADW,QAAQ,OAAO,4BAA4B,EAAE,OAAO,EAAE,YAAY,CAAC,CAC5C;IAuClC,0BAAoB;IACpB,2BAAY;IAGZ,oDAAoD;IACpD,2BADW,OAAO,SAAS,EAAE,iBAAiB,EAAE,CAQ/C;IACD,sDAGC;IAOD,+CAA+C;IAC/C,aADW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CACZ;IAOnC,uBAIC;IAHG;;;MAAmC;IAKvC,mBAEC;IADG,YAAkC;IAGtC;;;;;OAKG;IACH,oBAHW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,eA2B3B;IAED,iBAcC;IAED,iBAEC;IAED;;;;OAIG;IACH,oCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;;MAQ3C;IAED;;OAEG;IACH;;;MAuBC;IAED;;;;OAIG;IACH,oBAHW,MAAM,KACN,MAAM,cAwBhB;IAED,iBAOC;IAED;;;;;;;;;OASG;IACH,+BAHW,OAAO,4BAA4B,EAAE,OAAO,WAC5C,OAAO,QA0GjB;CACJ"}
|
|
@@ -301,9 +301,9 @@ export default class WebGLHelper {
|
|
|
301
301
|
const channel = resolution.channel;
|
|
302
302
|
|
|
303
303
|
if (isColorChannel(channel)) {
|
|
304
|
-
const
|
|
304
|
+
const scale = resolution.scale;
|
|
305
|
+
const props = scale.props;
|
|
305
306
|
|
|
306
|
-
const scale = resolution.getScale();
|
|
307
307
|
const range = /** @type {any[]} */ (scale.range());
|
|
308
308
|
|
|
309
309
|
/** @type {WebGLTexture} */
|
|
@@ -336,7 +336,7 @@ export default class WebGLHelper {
|
|
|
336
336
|
// Interpolating
|
|
337
337
|
isInterpolating(scale.type) ||
|
|
338
338
|
// Or piecewise
|
|
339
|
-
(isContinuous(scale.type) && range.length >
|
|
339
|
+
(isContinuous(scale.type) && range.length > 1)
|
|
340
340
|
) {
|
|
341
341
|
texture = createInterpolatedColorTexture(
|
|
342
342
|
range,
|
|
@@ -355,7 +355,7 @@ export default class WebGLHelper {
|
|
|
355
355
|
|
|
356
356
|
this.rangeTextures.set(resolution, texture);
|
|
357
357
|
} else {
|
|
358
|
-
const scale = resolution.
|
|
358
|
+
const scale = resolution.scale;
|
|
359
359
|
|
|
360
360
|
if (scale.type === "ordinal" || isDiscretizing(scale.type)) {
|
|
361
361
|
/** @type {function(any):number} Handle "shape" etc */
|
|
@@ -363,9 +363,7 @@ export default class WebGLHelper {
|
|
|
363
363
|
? getDiscreteRangeMapper(channel)
|
|
364
364
|
: (x) => x;
|
|
365
365
|
|
|
366
|
-
const range = /** @type {any[]} */ (
|
|
367
|
-
resolution.getScale().range()
|
|
368
|
-
);
|
|
366
|
+
const range = /** @type {any[]} */ (scale.range());
|
|
369
367
|
|
|
370
368
|
this.rangeTextures.set(
|
|
371
369
|
resolution,
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const shader = "layout(std140)uniform Mark{uniform float uArcHeightFactor;uniform float uMinArcHeight;uniform float uMinPickingSize;uniform int uShape;uniform int uOrient;uniform bool uClampApex;uniform float uMaxChordLength;uniform vec2 uArcFadingDistance;\n#pragma markUniforms\n};";
|
|
2
|
+
export default shader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/marks/link.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/marks/link.js"],"names":[],"mappings":"AAYA;IA+BQ;;;;;OAKG;IACH,yBAEC;IA4GD;;;;;;MAKC;CAoFR;iBAlPgB,WAAW"}
|
package/dist/src/marks/link.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { setBuffersAndAttributes } from "twgl.js";
|
|
2
2
|
import VERTEX_SHADER from "./link.vertex.glsl.js";
|
|
3
3
|
import FRAGMENT_SHADER from "./link.fragment.glsl.js";
|
|
4
|
+
import COMMON_SHADER from "./link.common.glsl.js";
|
|
4
5
|
import { LinkVertexBuilder } from "../gl/dataToVertices.js";
|
|
5
6
|
|
|
6
7
|
import Mark from "./mark.js";
|
|
@@ -98,7 +99,9 @@ export default class LinkMark extends Mark {
|
|
|
98
99
|
async initializeGraphics() {
|
|
99
100
|
await super.initializeGraphics();
|
|
100
101
|
|
|
101
|
-
this.createAndLinkShaders(VERTEX_SHADER, FRAGMENT_SHADER
|
|
102
|
+
this.createAndLinkShaders(VERTEX_SHADER, FRAGMENT_SHADER, [
|
|
103
|
+
COMMON_SHADER,
|
|
104
|
+
]);
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
finalizeGraphicsInitialization() {
|
|
@@ -107,22 +110,29 @@ export default class LinkMark extends Mark {
|
|
|
107
110
|
|
|
108
111
|
const props = this.properties;
|
|
109
112
|
|
|
110
|
-
this.
|
|
113
|
+
this.registerMarkUniformValue(
|
|
111
114
|
"uArcFadingDistance",
|
|
112
115
|
props.arcFadingDistance,
|
|
113
116
|
(x) => x || /** @type {[number, number]} */ ([0, 0])
|
|
114
117
|
);
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
this.registerMarkUniformValue(
|
|
119
|
+
"uArcHeightFactor",
|
|
120
|
+
props.arcHeightFactor
|
|
121
|
+
);
|
|
122
|
+
this.registerMarkUniformValue("uMinArcHeight", props.minArcHeight);
|
|
123
|
+
this.registerMarkUniformValue("uMinPickingSize", props.minPickingSize);
|
|
124
|
+
this.registerMarkUniformValue("uShape", props.linkShape, (linkShape) =>
|
|
119
125
|
LINK_SHAPES.indexOf(linkShape)
|
|
120
126
|
);
|
|
121
|
-
this.
|
|
127
|
+
this.registerMarkUniformValue("uOrient", props.orient, (orient) =>
|
|
122
128
|
ORIENTS.indexOf(orient)
|
|
123
129
|
);
|
|
124
|
-
this.
|
|
125
|
-
|
|
130
|
+
this.registerMarkUniformValue(
|
|
131
|
+
"uClampApex",
|
|
132
|
+
props.clampApex,
|
|
133
|
+
(x) => !!x
|
|
134
|
+
);
|
|
135
|
+
this.registerMarkUniformValue("uMaxChordLength", props.maxChordLength);
|
|
126
136
|
}
|
|
127
137
|
|
|
128
138
|
updateGraphicsData() {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "
|
|
1
|
+
const shader = "in vec2 strip;out vec4 vColor;out float vSize;out float vNormalLengthInPixels;const int SHAPE_ARC=0;const int SHAPE_DOME=1;const int SHAPE_DIAGONAL=2;const int SHAPE_LINE=3;const int ORIENT_VERTICAL=0;const int ORIENT_HORIZONTAL=1;float distanceFromLine(vec2 pointOnLine1,vec2 pointOnLine2,vec2 point){vec2 a=point-pointOnLine1;vec2 b=pointOnLine2-pointOnLine1;vec2 proj=dot(a,b)/dot(b,b)*b;return length(a-proj);}bool isInsideViewport(vec2 point,float marginFactor){vec2 margin=uViewportSize*vec2(marginFactor);return point.x>=-margin.x&&point.x<=uViewportSize.x+margin.x&&point.y>=-margin.y&&point.y<=uViewportSize.y+margin.y;}void main(void){float pixelSize=1.0/uDevicePixelRatio;float opacity=getScaled_opacity()*uViewOpacity;vec2 p1,p2,p3,p4;vec2 a=applySampleFacet(vec2(getScaled_x(),getScaled_y()))*uViewportSize;vec2 b=applySampleFacet(vec2(getScaled_x2(),getScaled_y2()))*uViewportSize;if(uShape<=SHAPE_DOME){if(uShape==SHAPE_DOME){vec2 height=vec2(0.0);if(uOrient==ORIENT_VERTICAL){p1=vec2(min(a.x,b.x),b.y);p4=vec2(max(a.x,b.x),b.y);height=vec2(0.0,a.y-b.y);if(uClampApex){if(p4.x>0.0){p1.x=max(p1.x,-p4.x);}if(p1.x<uViewportSize.x){p4.x=min(p4.x,2.0*uViewportSize.x-p1.x);}}}else{p1=vec2(b.x,min(a.y,b.y));p4=vec2(b.x,max(a.y,b.y));height=vec2(a.x-b.x,0.0);if(uClampApex){if(p4.y>0.0){p1.y=max(p1.y,-p4.y);}if(p1.y<uViewportSize.y){p4.y=min(p4.y,2.0*uViewportSize.y-p1.y);}}}vec2 controlOffset=height/0.75;p2=p1+controlOffset;p3=p4+controlOffset;}if(uShape==SHAPE_ARC){p1=a;p4=b;vec2 chordVector=p4-p1;vec2 unitChordVector=normalize(chordVector);vec2 chordNormal=vec2(-unitChordVector.y,unitChordVector.x);float chordLength=length(chordVector);if(chordLength>uMaxChordLength){if(isInsideViewport(p1,2.0)){chordLength=uMaxChordLength;p4=p1+unitChordVector*uMaxChordLength;}else if(isInsideViewport(p4,2.0)){chordLength=uMaxChordLength;p1=p4-unitChordVector*uMaxChordLength;}}float height=max(chordLength/2.0*uArcHeightFactor,uMinArcHeight);vec2 controlOffset=chordNormal*height/0.75;p2=p1+controlOffset;p3=p4+controlOffset;}}else if(uShape==SHAPE_DIAGONAL){if(uOrient==ORIENT_VERTICAL){p1=a;p2=vec2(a.x,(a.y+b.y)/2.0);p3=vec2(b.x,(a.y+b.y)/2.0);p4=b;}else{p1=a;p2=vec2((a.x+b.x)/2.0,a.y);p3=vec2((a.x+b.x)/2.0,b.y);p4=b;}}else if(uShape==SHAPE_LINE){p1=a;p2=(a+b)/2.0;p3=p2;p4=b;}float t=smoothstep(0.0,1.0,strip.x);vec2 C1=p4-3.0*p3+3.0*p2-p1;vec2 C2=3.0*p3-6.0*p2+3.0*p1;vec2 C3=3.0*p2-3.0*p1;vec2 C4=p1;vec2 p;if(t==0.0){p=p1;}else if(t==1.0){p=p4;}else{p=C1*t*t*t+C2*t*t+C3*t+C4;}vec2 tangent=normalize(3.0*C1*t*t+2.0*C2*t+C3);vec2 normal=vec2(-tangent.y,tangent.x);float size=getScaled_size();if(size<pixelSize){opacity*=size/pixelSize;size=pixelSize;}float paddedSize=uPickingEnabled? max(size,uMinPickingSize): size+pixelSize;vNormalLengthInPixels=strip.y*paddedSize;if(uShape==SHAPE_ARC&&uArcFadingDistance[0]>0.0&&uArcFadingDistance[1]>0.0){float d=distanceFromLine(p1,p4,p);float distanceOpacity=smoothstep(uArcFadingDistance[1],uArcFadingDistance[0],d);opacity*=distanceOpacity;if(distanceOpacity<=0.0){vNormalLengthInPixels=0.0;}}p+=normal*vNormalLengthInPixels;gl_Position=pixelsToNdc(p);vec3 color=getScaled_color();vColor=vec4(color*opacity,opacity);vSize=paddedSize;setupPicking();}";
|
|
2
2
|
export default shader;
|
package/dist/src/marks/mark.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="external-typings/internmap.js" />
|
|
2
2
|
/**
|
|
3
3
|
* @param {any} x
|
|
4
|
-
* @returns {x is import("../spec/
|
|
4
|
+
* @returns {x is import("../spec/parameter.js").ExprRef}
|
|
5
5
|
*/
|
|
6
|
-
export function isExprRef(x: any): x is import("../spec/
|
|
6
|
+
export function isExprRef(x: any): x is import("../spec/parameter.js").ExprRef;
|
|
7
7
|
export const SAMPLE_FACET_UNIFORM: "SAMPLE_FACET_UNIFORM";
|
|
8
8
|
export const SAMPLE_FACET_TEXTURE: "SAMPLE_FACET_TEXTURE";
|
|
9
9
|
/**
|
|
@@ -20,13 +20,6 @@ export const SAMPLE_FACET_TEXTURE: "SAMPLE_FACET_TEXTURE";
|
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
export default class Mark {
|
|
23
|
-
/**
|
|
24
|
-
* @typedef {import("../spec/mark.js").MarkConfig} MarkConfig
|
|
25
|
-
* @typedef {import("../spec/channel.js").Channel} Channel
|
|
26
|
-
* @typedef {import("../spec/channel.js").Encoding} Encoding
|
|
27
|
-
* @typedef {import("../spec/channel.js").ValueDef} ValueDef
|
|
28
|
-
* @typedef {import("../spec/mark.js").ExprRef} ExprRef
|
|
29
|
-
*/
|
|
30
23
|
/**
|
|
31
24
|
* @param {import("../view/unitView.js").default} unitView
|
|
32
25
|
*/
|
|
@@ -60,18 +53,18 @@ export default class Mark {
|
|
|
60
53
|
protected markUniformsAltered: boolean;
|
|
61
54
|
/** @type {RangeMap<any>} keep track of facet locations within the vertex array */
|
|
62
55
|
rangeMap: RangeMap<any>;
|
|
63
|
-
/** @type {
|
|
64
|
-
defaultProperties: import("../spec/mark.js").
|
|
56
|
+
/** @type {MarkProps} */
|
|
57
|
+
defaultProperties: import("../spec/mark.js").MarkProps;
|
|
65
58
|
/**
|
|
66
59
|
* A properties object that contains the configured mark properties or
|
|
67
60
|
* default values as fallback.
|
|
68
61
|
*
|
|
69
62
|
* TODO: Proper and comprehensive typings for mark properties
|
|
70
63
|
*
|
|
71
|
-
* @type {Partial<
|
|
64
|
+
* @type {Partial<MarkProps>}
|
|
72
65
|
* @readonly
|
|
73
66
|
*/
|
|
74
|
-
readonly properties: Partial<import("../spec/mark.js").
|
|
67
|
+
readonly properties: Partial<import("../spec/mark.js").MarkProps>;
|
|
75
68
|
get opaque(): boolean;
|
|
76
69
|
/**
|
|
77
70
|
* Returns attribute info for WebGL attributes that match visual channels.
|
|
@@ -128,8 +121,6 @@ export default class Mark {
|
|
|
128
121
|
* @protected
|
|
129
122
|
*/
|
|
130
123
|
protected createAndLinkShaders(vertexShader: string, fragmentShader: string, extraHeaders?: string[]): void;
|
|
131
|
-
/** @type {string[]} */
|
|
132
|
-
domainUniforms: string[];
|
|
133
124
|
programStatus: {
|
|
134
125
|
program: WebGLProgram;
|
|
135
126
|
getProgramErrors: () => {
|
|
@@ -140,8 +131,19 @@ export default class Mark {
|
|
|
140
131
|
/**
|
|
141
132
|
* Check WebGL shader/program compilation/linking status and finalize
|
|
142
133
|
* initialization.
|
|
134
|
+
*
|
|
135
|
+
* This is done as a separate step after all shader compilations have been
|
|
136
|
+
* initiated. The idea is to allow for parallel background compilation.
|
|
143
137
|
*/
|
|
144
138
|
finalizeGraphicsInitialization(): void;
|
|
139
|
+
/**
|
|
140
|
+
* Sets a uniform in the Mark block. Requests a render from the animator.
|
|
141
|
+
*
|
|
142
|
+
* @protected
|
|
143
|
+
* @param {string} uniformName
|
|
144
|
+
* @returns {function(any):void}
|
|
145
|
+
*/
|
|
146
|
+
protected createMarkUniformSetter(uniformName: string): (arg0: any) => void;
|
|
145
147
|
/**
|
|
146
148
|
* Set a uniform based on a mark property. If the property is an expression,
|
|
147
149
|
* register a listener to update the uniform when the params referenced by the
|
|
@@ -153,8 +155,7 @@ export default class Mark {
|
|
|
153
155
|
* @param {T} propValue
|
|
154
156
|
* @param {(x: Exclude<T, ExprRef>) => any} adjuster
|
|
155
157
|
*/
|
|
156
|
-
protected
|
|
157
|
-
_setDatums(): void;
|
|
158
|
+
protected registerMarkUniformValue<T>(uniformName: string, propValue: T, adjuster?: (x: Exclude<T, import("../spec/parameter.js").ExprRef>) => any): void;
|
|
158
159
|
/**
|
|
159
160
|
* Delete WebGL buffers etc.
|
|
160
161
|
*/
|
|
@@ -233,6 +234,7 @@ export default class Mark {
|
|
|
233
234
|
* @returns {any}
|
|
234
235
|
*/
|
|
235
236
|
findDatumAt(facetId: string, x: import("../spec/channel.js").Scalar): any;
|
|
237
|
+
#private;
|
|
236
238
|
}
|
|
237
239
|
export type RenderingOptions = import("../types/rendering.js").RenderingOptions;
|
|
238
240
|
export type _MarkRenderingOptions = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
|