@genome-spy/core 0.68.0 → 0.69.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 +12108 -10682
- package/dist/bundle/index.js +119 -119
- package/dist/schema.json +6224 -6319
- package/dist/src/data/dataFlow.d.ts.map +1 -1
- package/dist/src/data/dataFlow.js +10 -0
- package/dist/src/data/flowNode.d.ts +25 -10
- package/dist/src/data/flowNode.d.ts.map +1 -1
- package/dist/src/data/flowNode.js +66 -13
- package/dist/src/data/flowTestUtils.d.ts +2 -2
- package/dist/src/data/flowTestUtils.d.ts.map +1 -1
- package/dist/src/data/flowTestUtils.js +5 -4
- package/dist/src/data/sources/dataSource.js +2 -2
- package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.js +11 -10
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +11 -10
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +1 -1
- package/dist/src/data/sources/lazy/tabixSource.d.ts +0 -1
- package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/tabixSource.js +41 -11
- package/dist/src/data/sources/sequenceSource.d.ts.map +1 -1
- package/dist/src/data/sources/sequenceSource.js +5 -3
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +7 -3
- package/dist/src/data/transforms/filter.d.ts +4 -4
- package/dist/src/data/transforms/filter.d.ts.map +1 -1
- package/dist/src/data/transforms/filter.js +13 -7
- package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
- package/dist/src/data/transforms/filterScoredLabels.js +11 -6
- package/dist/src/data/transforms/filterScoredLabels.test.d.ts +2 -0
- package/dist/src/data/transforms/filterScoredLabels.test.d.ts.map +1 -0
- package/dist/src/data/transforms/formula.d.ts +4 -4
- package/dist/src/data/transforms/formula.d.ts.map +1 -1
- package/dist/src/data/transforms/formula.js +12 -6
- package/dist/src/data/transforms/measureText.d.ts +2 -2
- package/dist/src/data/transforms/measureText.d.ts.map +1 -1
- package/dist/src/data/transforms/measureText.js +16 -12
- package/dist/src/data/transforms/transform.d.ts +2 -2
- package/dist/src/data/transforms/transform.d.ts.map +1 -1
- package/dist/src/data/transforms/transform.js +3 -3
- package/dist/src/encoder/accessor.d.ts +8 -4
- package/dist/src/encoder/accessor.d.ts.map +1 -1
- package/dist/src/encoder/accessor.js +10 -10
- package/dist/src/encoder/encoder.js +5 -5
- package/dist/src/genome/genome.d.ts +8 -0
- package/dist/src/genome/genome.d.ts.map +1 -1
- package/dist/src/genome/genome.js +16 -1
- package/dist/src/genomeSpy/inputBindingManager.js +1 -1
- package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
- package/dist/src/genomeSpy/interactionController.js +7 -1
- package/dist/src/genomeSpy.js +1 -1
- package/dist/src/gl/glslScaleGenerator.js +1 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +22 -30
- package/dist/src/marks/point.d.ts.map +1 -1
- package/dist/src/marks/point.js +4 -6
- package/dist/src/paramRuntime/expressionCompiler.d.ts +7 -0
- package/dist/src/paramRuntime/expressionCompiler.d.ts.map +1 -0
- package/dist/src/paramRuntime/expressionCompiler.js +10 -0
- package/dist/src/paramRuntime/expressionRef.d.ts +20 -0
- package/dist/src/paramRuntime/expressionRef.d.ts.map +1 -0
- package/dist/src/paramRuntime/expressionRef.js +95 -0
- package/dist/src/paramRuntime/expressionRef.test.d.ts +2 -0
- package/dist/src/paramRuntime/expressionRef.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/graphRuntime.d.ts +176 -0
- package/dist/src/paramRuntime/graphRuntime.d.ts.map +1 -0
- package/dist/src/paramRuntime/graphRuntime.js +628 -0
- package/dist/src/paramRuntime/graphRuntime.test.d.ts +2 -0
- package/dist/src/paramRuntime/graphRuntime.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/index.d.ts +9 -0
- package/dist/src/paramRuntime/index.d.ts.map +1 -0
- package/dist/src/paramRuntime/index.js +8 -0
- package/dist/src/paramRuntime/lifecycleRegistry.d.ts +27 -0
- package/dist/src/paramRuntime/lifecycleRegistry.d.ts.map +1 -0
- package/dist/src/paramRuntime/lifecycleRegistry.js +54 -0
- package/dist/src/paramRuntime/paramRuntime.d.ts +165 -0
- package/dist/src/paramRuntime/paramRuntime.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramRuntime.js +222 -0
- package/dist/src/paramRuntime/paramRuntime.test.d.ts +2 -0
- package/dist/src/paramRuntime/paramRuntime.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramStore.d.ts +68 -0
- package/dist/src/paramRuntime/paramStore.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramStore.js +148 -0
- package/dist/src/paramRuntime/paramStore.test.d.ts +2 -0
- package/dist/src/paramRuntime/paramStore.test.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramUtils.d.ts +86 -0
- package/dist/src/paramRuntime/paramUtils.d.ts.map +1 -0
- package/dist/src/paramRuntime/paramUtils.js +272 -0
- package/dist/src/paramRuntime/selectionStore.d.ts +6 -0
- package/dist/src/paramRuntime/selectionStore.d.ts.map +1 -0
- package/dist/src/paramRuntime/selectionStore.js +13 -0
- package/dist/src/paramRuntime/types.d.ts +16 -0
- package/dist/src/paramRuntime/types.d.ts.map +1 -0
- package/dist/src/paramRuntime/types.js +25 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts +164 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -0
- package/dist/src/paramRuntime/viewParamRuntime.js +443 -0
- package/dist/src/scales/scaleInstanceManager.d.ts +6 -3
- package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
- package/dist/src/scales/scaleInstanceManager.js +17 -11
- package/dist/src/scales/scaleResolution.d.ts +1 -0
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +7 -1
- package/dist/src/selection/selection.js +1 -1
- package/dist/src/spec/coreSchemaRoot.d.ts +53 -0
- package/dist/src/spec/root.d.ts +1 -1
- package/dist/src/spec/view.d.ts +114 -33
- package/dist/src/tooltip/dataTooltipHandler.d.ts +1 -1
- package/dist/src/tooltip/dataTooltipHandler.js +23 -32
- package/dist/src/tooltip/dataTooltipHandler.test.d.ts +2 -0
- package/dist/src/tooltip/dataTooltipHandler.test.d.ts.map +1 -0
- package/dist/src/tooltip/flattenDatumRows.d.ts +13 -0
- package/dist/src/tooltip/flattenDatumRows.d.ts.map +1 -0
- package/dist/src/tooltip/flattenDatumRows.js +47 -0
- package/dist/src/tooltip/flattenDatumRows.test.d.ts +2 -0
- package/dist/src/tooltip/flattenDatumRows.test.d.ts.map +1 -0
- package/dist/src/tooltip/refseqGeneTooltipHandler.d.ts +1 -1
- package/dist/src/tooltip/refseqGeneTooltipHandler.js +7 -1
- package/dist/src/tooltip/tooltipContext.d.ts +13 -0
- package/dist/src/tooltip/tooltipContext.d.ts.map +1 -0
- package/dist/src/tooltip/tooltipContext.js +543 -0
- package/dist/src/tooltip/tooltipContext.test.d.ts +2 -0
- package/dist/src/tooltip/tooltipContext.test.d.ts.map +1 -0
- package/dist/src/tooltip/tooltipHandler.d.ts +40 -1
- package/dist/src/tooltip/tooltipHandler.d.ts.map +1 -1
- package/dist/src/tooltip/tooltipHandler.ts +62 -1
- package/dist/src/types/encoder.d.ts +1 -1
- package/dist/src/utils/inputBinding.d.ts +10 -2
- package/dist/src/utils/inputBinding.d.ts.map +1 -1
- package/dist/src/utils/inputBinding.js +12 -3
- package/dist/src/view/flowBuilder.d.ts.map +1 -1
- package/dist/src/view/flowBuilder.js +12 -3
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +8 -3
- package/dist/src/view/gridView/selectionRect.d.ts +6 -10
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
- package/dist/src/view/gridView/selectionRect.js +3 -20
- package/dist/src/view/layerView.d.ts.map +1 -1
- package/dist/src/view/layerView.js +4 -2
- package/dist/src/view/multiscale.d.ts +35 -0
- package/dist/src/view/multiscale.d.ts.map +1 -0
- package/dist/src/view/multiscale.js +233 -0
- package/dist/src/view/multiscale.test.d.ts +2 -0
- package/dist/src/view/multiscale.test.d.ts.map +1 -0
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +10 -4
- package/dist/src/view/view.d.ts +5 -4
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +205 -28
- package/dist/src/view/viewFactory.d.ts +0 -12
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +35 -24
- package/dist/src/view/viewParamRuntime.test.d.ts +2 -0
- package/dist/src/view/viewParamRuntime.test.d.ts.map +1 -0
- package/dist/src/view/viewSelectors.d.ts.map +1 -1
- package/dist/src/view/viewSelectors.js +8 -5
- package/package.json +3 -3
- package/dist/src/spec/sampleView.d.ts +0 -197
- package/dist/src/view/paramMediator.d.ts +0 -168
- package/dist/src/view/paramMediator.d.ts.map +0 -1
- package/dist/src/view/paramMediator.js +0 -545
- package/dist/src/view/paramMediator.test.d.ts +0 -2
- package/dist/src/view/paramMediator.test.d.ts.map +0 -1
package/dist/src/view/view.js
CHANGED
|
@@ -9,14 +9,15 @@ import {
|
|
|
9
9
|
initPropertyCache,
|
|
10
10
|
invalidatePrefix,
|
|
11
11
|
} from "../utils/propertyCacher.js";
|
|
12
|
-
import { isNumber, isString, span } from "vega-util";
|
|
12
|
+
import { isArray, isNumber, isString, span } from "vega-util";
|
|
13
13
|
import { scaleLog } from "d3-scale";
|
|
14
14
|
import { isFieldDef, getPrimaryChannel } from "../encoder/encoder.js";
|
|
15
15
|
import { concatUrl } from "../utils/url.js";
|
|
16
16
|
import { isDiscrete, bandSpace } from "vega-scale";
|
|
17
17
|
import { peek } from "../utils/arrayUtils.js";
|
|
18
18
|
import ViewError from "./viewError.js";
|
|
19
|
-
import
|
|
19
|
+
import ViewParamRuntime from "../paramRuntime/viewParamRuntime.js";
|
|
20
|
+
import { isExprRef } from "../paramRuntime/paramUtils.js";
|
|
20
21
|
import { InternMap } from "internmap";
|
|
21
22
|
import { endWithSlash } from "../utils/addBaseUrl.js";
|
|
22
23
|
|
|
@@ -160,15 +161,15 @@ export default class View {
|
|
|
160
161
|
*/
|
|
161
162
|
this.needsAxes = { x: false, y: false };
|
|
162
163
|
|
|
163
|
-
/** @type {
|
|
164
|
-
this.
|
|
165
|
-
() => this.dataParent?.
|
|
164
|
+
/** @type {ViewParamRuntime} */
|
|
165
|
+
this.paramRuntime = new ViewParamRuntime(
|
|
166
|
+
() => this.dataParent?.paramRuntime
|
|
166
167
|
);
|
|
167
168
|
|
|
168
169
|
if (spec.params) {
|
|
169
170
|
for (const param of spec.params) {
|
|
170
171
|
// TODO: If interval selection, validate `encodings` or provides defaults
|
|
171
|
-
this.
|
|
172
|
+
this.paramRuntime.registerParam(param);
|
|
172
173
|
}
|
|
173
174
|
}
|
|
174
175
|
|
|
@@ -178,9 +179,9 @@ export default class View {
|
|
|
178
179
|
// doesn't make much sense, but it's used in the App's SampleView
|
|
179
180
|
// to set the height to sample facets' height.
|
|
180
181
|
const allocateIfFree = (/** @type {string} */ name) =>
|
|
181
|
-
this.
|
|
182
|
+
this.paramRuntime.findRuntimeForParam(name)
|
|
182
183
|
? undefined
|
|
183
|
-
: this.
|
|
184
|
+
: this.paramRuntime.allocateSetter(name, 0);
|
|
184
185
|
this.#heightSetter = allocateIfFree("height");
|
|
185
186
|
this.#widthSetter = allocateIfFree("width");
|
|
186
187
|
}
|
|
@@ -510,6 +511,7 @@ export default class View {
|
|
|
510
511
|
*
|
|
511
512
|
* @param {string} type
|
|
512
513
|
* @param {function(BroadcastMessage):void} handler
|
|
514
|
+
* @returns {() => void}
|
|
513
515
|
*/
|
|
514
516
|
_addBroadcastHandler(type, handler) {
|
|
515
517
|
let handlers = this.#broadcastHandlers[type];
|
|
@@ -518,6 +520,18 @@ export default class View {
|
|
|
518
520
|
this.#broadcastHandlers[type] = handlers;
|
|
519
521
|
}
|
|
520
522
|
handlers.push(handler);
|
|
523
|
+
|
|
524
|
+
return () => {
|
|
525
|
+
const currentHandlers = this.#broadcastHandlers[type];
|
|
526
|
+
if (!currentHandlers) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const index = currentHandlers.indexOf(handler);
|
|
531
|
+
if (index >= 0) {
|
|
532
|
+
currentHandlers.splice(index, 1);
|
|
533
|
+
}
|
|
534
|
+
};
|
|
521
535
|
}
|
|
522
536
|
|
|
523
537
|
/**
|
|
@@ -642,6 +656,8 @@ export default class View {
|
|
|
642
656
|
this.context.dataFlow.removeDataSource(handle.dataSource);
|
|
643
657
|
}
|
|
644
658
|
|
|
659
|
+
this.paramRuntime.dispose();
|
|
660
|
+
|
|
645
661
|
this.context.dataFlow.loadingStatusRegistry.delete(this);
|
|
646
662
|
|
|
647
663
|
this.flowHandle = undefined;
|
|
@@ -875,7 +891,7 @@ export default class View {
|
|
|
875
891
|
return isString(title)
|
|
876
892
|
? title
|
|
877
893
|
: isExprRef(title.text)
|
|
878
|
-
? this.
|
|
894
|
+
? this.paramRuntime.evaluateAndGet(title.text.expr)
|
|
879
895
|
: title.text;
|
|
880
896
|
}
|
|
881
897
|
}
|
|
@@ -940,6 +956,16 @@ function isDynamicOpacity(opacity) {
|
|
|
940
956
|
}
|
|
941
957
|
|
|
942
958
|
/**
|
|
959
|
+
* Builds the effective opacity function for a view.
|
|
960
|
+
*
|
|
961
|
+
* The resulting function multiplies parent opacity with one of:
|
|
962
|
+
* 1. constant opacity (`number`)
|
|
963
|
+
* 2. zoom-driven dynamic opacity (`DynamicOpacity`) that maps the current
|
|
964
|
+
* units-per-pixel metric through a log interpolation
|
|
965
|
+
* 3. expression-driven opacity (`ExprRef`) that is evaluated reactively
|
|
966
|
+
*
|
|
967
|
+
* Dynamic opacity supports scale selection via `channel` (`x`, `y`, or
|
|
968
|
+
* `"auto"`), where `"auto"` averages available x/y metrics.
|
|
943
969
|
*
|
|
944
970
|
* @param {View} view
|
|
945
971
|
* @returns {function(number):number}
|
|
@@ -951,46 +977,197 @@ function createViewOpacityFunction(view) {
|
|
|
951
977
|
if (isNumber(opacityDef)) {
|
|
952
978
|
return (parentOpacity) => parentOpacity * opacityDef;
|
|
953
979
|
} else if (isDynamicOpacity(opacityDef)) {
|
|
954
|
-
/**
|
|
955
|
-
|
|
956
|
-
|
|
980
|
+
/**
|
|
981
|
+
* @param {import("../spec/channel.js").PrimaryPositionalChannel} channel
|
|
982
|
+
*/
|
|
983
|
+
const getScaleContext = (channel) => {
|
|
984
|
+
const scaleResolution = view.getScaleResolution(channel);
|
|
985
|
+
const scale = scaleResolution?.getScale();
|
|
957
986
|
// Only works on linear scales
|
|
958
987
|
if (["linear", "index", "locus"].includes(scale?.type)) {
|
|
959
|
-
return scale;
|
|
988
|
+
return { scale, scaleResolution };
|
|
960
989
|
}
|
|
961
990
|
};
|
|
962
991
|
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
992
|
+
const opacityValues = asFiniteNumberArray(
|
|
993
|
+
opacityDef.values,
|
|
994
|
+
"opacity.values",
|
|
995
|
+
view
|
|
996
|
+
);
|
|
966
997
|
|
|
967
|
-
if (!
|
|
998
|
+
if (!isArray(opacityDef.unitsPerPixel)) {
|
|
968
999
|
throw new ViewError(
|
|
969
|
-
"
|
|
1000
|
+
'"opacity.unitsPerPixel" must be an array.',
|
|
970
1001
|
view
|
|
971
1002
|
);
|
|
972
1003
|
}
|
|
973
1004
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
.range(opacityDef.values)
|
|
977
|
-
.clamp(true);
|
|
1005
|
+
/** @type {function(number): number} */
|
|
1006
|
+
let interpolate = () => 1;
|
|
978
1007
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
const unitsPerPixel = span(scale.domain()) / rangeSpan;
|
|
1008
|
+
/** @type {(() => number)[]} */
|
|
1009
|
+
let stopReaders = [];
|
|
982
1010
|
|
|
983
|
-
|
|
1011
|
+
const updateInterpolator = () => {
|
|
1012
|
+
const unitsPerPixel = asFiniteNumberArray(
|
|
1013
|
+
stopReaders.map((readStop) => readStop()),
|
|
1014
|
+
"opacity.unitsPerPixel",
|
|
1015
|
+
view
|
|
1016
|
+
);
|
|
1017
|
+
|
|
1018
|
+
validateDynamicOpacityStops(unitsPerPixel, opacityValues, view);
|
|
1019
|
+
|
|
1020
|
+
const scale = scaleLog()
|
|
1021
|
+
.domain(unitsPerPixel)
|
|
1022
|
+
.range(opacityValues)
|
|
1023
|
+
.clamp(true);
|
|
1024
|
+
|
|
1025
|
+
interpolate = (value) => scale(value);
|
|
1026
|
+
};
|
|
1027
|
+
|
|
1028
|
+
stopReaders = opacityDef.unitsPerPixel.map((stop) => {
|
|
1029
|
+
if (isExprRef(stop)) {
|
|
1030
|
+
const fn = view.paramRuntime.watchExpression(
|
|
1031
|
+
stop.expr,
|
|
1032
|
+
() => {
|
|
1033
|
+
updateInterpolator();
|
|
1034
|
+
view.context.animator.requestRender();
|
|
1035
|
+
}
|
|
1036
|
+
);
|
|
1037
|
+
return () => fn(null);
|
|
1038
|
+
} else {
|
|
1039
|
+
return () => stop;
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
updateInterpolator();
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* @param {{ scale: any, scaleResolution: import("../scales/scaleResolution.js").default }} scaleContext
|
|
1047
|
+
*/
|
|
1048
|
+
const getUnitsPerPixel = (scaleContext) => {
|
|
1049
|
+
const axisLength = scaleContext.scaleResolution.getAxisLength();
|
|
1050
|
+
const rangeSpan = axisLength || 1000;
|
|
1051
|
+
return span(scaleContext.scale.domain()) / rangeSpan;
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
/** @type {() => number} */
|
|
1055
|
+
let getMetric;
|
|
1056
|
+
|
|
1057
|
+
if (opacityDef.channel === "auto") {
|
|
1058
|
+
const xScale = getScaleContext("x");
|
|
1059
|
+
const yScale = getScaleContext("y");
|
|
1060
|
+
|
|
1061
|
+
if (xScale && yScale) {
|
|
1062
|
+
getMetric = () =>
|
|
1063
|
+
(getUnitsPerPixel(xScale) + getUnitsPerPixel(yScale)) /
|
|
1064
|
+
2;
|
|
1065
|
+
} else if (xScale) {
|
|
1066
|
+
getMetric = () => getUnitsPerPixel(xScale);
|
|
1067
|
+
} else if (yScale) {
|
|
1068
|
+
getMetric = () => getUnitsPerPixel(yScale);
|
|
1069
|
+
} else {
|
|
1070
|
+
throw new ViewError(
|
|
1071
|
+
"Cannot find a resolved quantitative x or y scale for dynamic opacity!",
|
|
1072
|
+
view
|
|
1073
|
+
);
|
|
1074
|
+
}
|
|
1075
|
+
} else {
|
|
1076
|
+
const scaleContext = opacityDef.channel
|
|
1077
|
+
? getScaleContext(opacityDef.channel)
|
|
1078
|
+
: (getScaleContext("x") ?? getScaleContext("y"));
|
|
1079
|
+
|
|
1080
|
+
if (!scaleContext) {
|
|
1081
|
+
throw new ViewError(
|
|
1082
|
+
"Cannot find a resolved quantitative scale for dynamic opacity!",
|
|
1083
|
+
view
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
getMetric = () => getUnitsPerPixel(scaleContext);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
return (parentOpacity) => {
|
|
1091
|
+
return interpolate(getMetric()) * parentOpacity;
|
|
984
1092
|
};
|
|
985
1093
|
} else if (isExprRef(opacityDef)) {
|
|
986
|
-
const fn = view.
|
|
987
|
-
|
|
1094
|
+
const fn = view.paramRuntime.watchExpression(opacityDef.expr, () =>
|
|
1095
|
+
view.context.animator.requestRender()
|
|
1096
|
+
);
|
|
988
1097
|
return (parentOpacity) => fn(null) * parentOpacity;
|
|
989
1098
|
}
|
|
990
1099
|
}
|
|
991
1100
|
return (parentOpacity) => parentOpacity;
|
|
992
1101
|
}
|
|
993
1102
|
|
|
1103
|
+
/**
|
|
1104
|
+
* @param {number[]} unitsPerPixel
|
|
1105
|
+
* @param {number[]} values
|
|
1106
|
+
* @param {View} view
|
|
1107
|
+
*/
|
|
1108
|
+
function validateDynamicOpacityStops(unitsPerPixel, values, view) {
|
|
1109
|
+
if (!unitsPerPixel.length) {
|
|
1110
|
+
throw new ViewError(
|
|
1111
|
+
'"opacity.unitsPerPixel" must contain at least one stop.',
|
|
1112
|
+
view
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
if (unitsPerPixel.length !== values.length) {
|
|
1117
|
+
throw new ViewError(
|
|
1118
|
+
'"opacity.unitsPerPixel" and "opacity.values" must have the same length.',
|
|
1119
|
+
view
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
unitsPerPixel.forEach((value, index) => {
|
|
1124
|
+
if (value <= 0) {
|
|
1125
|
+
throw new ViewError(
|
|
1126
|
+
"Invalid opacity.unitsPerPixel value at index " +
|
|
1127
|
+
index +
|
|
1128
|
+
". Stop values must be positive.",
|
|
1129
|
+
view
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
});
|
|
1133
|
+
|
|
1134
|
+
for (let i = 1; i < unitsPerPixel.length; i++) {
|
|
1135
|
+
if (unitsPerPixel[i - 1] <= unitsPerPixel[i]) {
|
|
1136
|
+
throw new ViewError(
|
|
1137
|
+
'"opacity.unitsPerPixel" must be strictly decreasing.',
|
|
1138
|
+
view
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* @param {unknown} value
|
|
1146
|
+
* @param {string} label
|
|
1147
|
+
* @param {View} view
|
|
1148
|
+
* @returns {number[]}
|
|
1149
|
+
*/
|
|
1150
|
+
function asFiniteNumberArray(value, label, view) {
|
|
1151
|
+
if (!isArray(value)) {
|
|
1152
|
+
throw new ViewError('"' + label + '" must evaluate to an array.', view);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
return value.map((item, index) => {
|
|
1156
|
+
if (!isNumber(item) || !Number.isFinite(item)) {
|
|
1157
|
+
throw new ViewError(
|
|
1158
|
+
"Invalid " +
|
|
1159
|
+
label +
|
|
1160
|
+
" value at index " +
|
|
1161
|
+
index +
|
|
1162
|
+
". Expected a finite number.",
|
|
1163
|
+
view
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
return item;
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
|
|
994
1171
|
/**
|
|
995
1172
|
*
|
|
996
1173
|
* @param {any} size
|
|
@@ -16,12 +16,6 @@ export function isLayerSpec(spec: import("../spec/view.js").ViewSpec): spec is i
|
|
|
16
16
|
* @returns {spec is LayerSpec}
|
|
17
17
|
*/
|
|
18
18
|
export function isFacetSpec(spec: import("../spec/view.js").ViewSpec): spec is import("../spec/view.js").LayerSpec;
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
* @param {ViewSpec} spec
|
|
22
|
-
* @returns {spec is import("../spec/view.js").AggregateSamplesSpec}
|
|
23
|
-
*/
|
|
24
|
-
export function isAggregateSamplesSpec(spec: import("../spec/view.js").ViewSpec): spec is import("../spec/view.js").AggregateSamplesSpec;
|
|
25
19
|
/**
|
|
26
20
|
*
|
|
27
21
|
* @param {object} spec
|
|
@@ -46,12 +40,6 @@ export function isHConcatSpec(spec: import("../spec/view.js").ViewSpec): spec is
|
|
|
46
40
|
* @returns {spec is ConcatSpec}
|
|
47
41
|
*/
|
|
48
42
|
export function isConcatSpec(spec: import("../spec/view.js").ViewSpec): spec is import("../spec/view.js").ConcatSpec;
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
51
|
-
* @param {ViewSpec} spec
|
|
52
|
-
* @returns {spec is SampleSpec}
|
|
53
|
-
*/
|
|
54
|
-
export function isSampleSpec(spec: import("../spec/view.js").ViewSpec): spec is import("../spec/sampleView.js").SampleSpec;
|
|
55
43
|
export const VIEW_ROOT_NAME: "viewRoot";
|
|
56
44
|
/**
|
|
57
45
|
* @typedef {object} ViewFactoryOptions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewFactory.d.ts","sourceRoot":"","sources":["../../../src/view/viewFactory.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"viewFactory.d.ts","sourceRoot":"","sources":["../../../src/view/viewFactory.js"],"names":[],"mappings":"AAwUA;;;;GAIG;AACH,sEAFa,IAAI,sCAAY,CAI5B;AAED;;;;GAIG;AACH,uEAFa,IAAI,uCAAa,CAI7B;AAED;;;;GAIG;AACH,uEAFa,IAAI,uCAAa,CAS7B;AAED;;;;GAIG;AACH,mCAHW,MAAM,GACJ,IAAI,IAAI,OAAO,iBAAiB,EAAE,UAAU,CAIxD;AAED;;;;GAIG;AACH,yEAFa,IAAI,yCAAe,CAI/B;AAED;;;;GAIG;AACH,yEAFa,IAAI,IAAI,WAAW,CAI/B;AAED;;;;GAIG;AACH,wEAFa,IAAI,wCAAc,CAI9B;AAxXD,6BAA8B,UAAU,CAAC;AAEzC;;;;GAIG;AAEH;;GAEG;AACH;IAiBI;;OAEG;IACH,sBAFW,kBAAkB,EAiD5B;IA9CG,2CAA2C;IAC3C,SADW,QAAQ,CAAC,kBAAkB,CAAC,CAKtC;IA2CL;;;OAGG;IACH,qEA/DiC,OAAO,yHAC2B,OAAO,oBAAoB,EAAE,OAAO,eAAe,OAAO,WAAW,EAAE,OAAO,gBAAgB,MAAM,KAAK,IAAI,QAgE/K;IAED;;;;;;OAMG;IACH,wHAJW,OAAO,oBAAoB,EAAE,OAAO,eACpC,OAAO,WAAW,EAAE,OAAO,gBAC3B,MAAM,QAyBhB;IAED;;;;OAIG;IACH,sDAFa,IAAI,sCAAY,CAU5B;IAED;;;;;;;;;;OAUG;IACH,yBAPW,qCAAW,OAAO,iBAAiB,EAAE,UAAU,qEAE/C,OAAO,oBAAoB,EAAE,OAAO,eACpC,OAAO,WAAW,EAAE,OAAO,gBAC3B,MAAM,cACN,CAAC,IAAI,oCAAU,KAAK,IAAI,iBAiGlC;;CACJ;;;;;kBA9Oa,OAAO;eACP,OAAO;;iBAtBJ,WAAW"}
|
|
@@ -8,12 +8,13 @@ import { isArray, isObject, isString } from "vega-util";
|
|
|
8
8
|
import { loadExternalViewSpec } from "./viewUtils.js";
|
|
9
9
|
import ContainerView from "./containerView.js";
|
|
10
10
|
import ViewError from "./viewError.js";
|
|
11
|
-
import { isSelectionParameter } from "
|
|
11
|
+
import { isSelectionParameter } from "../paramRuntime/paramUtils.js";
|
|
12
12
|
import { asSelectionConfig } from "../selection/selection.js";
|
|
13
13
|
import {
|
|
14
14
|
markViewAsNonAddressable,
|
|
15
15
|
registerImportInstance,
|
|
16
16
|
} from "./viewSelectors.js";
|
|
17
|
+
import { isMultiscaleSpec, normalizeMultiscaleSpec } from "./multiscale.js";
|
|
17
18
|
|
|
18
19
|
export const VIEW_ROOT_NAME = "viewRoot";
|
|
19
20
|
|
|
@@ -32,9 +33,9 @@ export class ViewFactory {
|
|
|
32
33
|
* @typedef {import("../spec/view.js").UnitSpec} UnitSpec
|
|
33
34
|
* @typedef {import("../spec/view.js").ViewSpec} ViewSpec
|
|
34
35
|
* @typedef {import("../spec/view.js").LayerSpec} LayerSpec
|
|
36
|
+
* @typedef {import("../spec/view.js").MultiscaleSpec} MultiscaleSpec
|
|
35
37
|
* @typedef {import("../spec/view.js").VConcatSpec} VConcatSpec
|
|
36
38
|
* @typedef {import("../spec/view.js").ConcatSpec} ConcatSpec
|
|
37
|
-
* @typedef {import("../spec/sampleView.js").SampleSpec} SampleSpec
|
|
38
39
|
*
|
|
39
40
|
* @typedef {(spec: ViewSpec) => boolean} SpecGuard
|
|
40
41
|
* @typedef {(spec: ViewSpec, context: ViewContext, layoutParent?: import("./containerView.js").default, dataParent?: import("./view.js").default, defaultName?: string) => View} Factory
|
|
@@ -69,17 +70,30 @@ export class ViewFactory {
|
|
|
69
70
|
);
|
|
70
71
|
|
|
71
72
|
this.addViewType(isLayerSpec, makeDefaultFactory(LayerView));
|
|
73
|
+
this.addViewType(
|
|
74
|
+
isMultiscaleSpec,
|
|
75
|
+
/** @type {Factory} */ (
|
|
76
|
+
(spec, context, layoutParent, dataParent, defaultName) =>
|
|
77
|
+
/** @type {View} */ (
|
|
78
|
+
new LayerView(
|
|
79
|
+
normalizeMultiscaleSpec(
|
|
80
|
+
/** @type {import("../spec/view.js").MultiscaleSpec} */ (
|
|
81
|
+
spec
|
|
82
|
+
)
|
|
83
|
+
),
|
|
84
|
+
context,
|
|
85
|
+
layoutParent,
|
|
86
|
+
dataParent,
|
|
87
|
+
defaultName
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
);
|
|
72
92
|
this.addViewType(isUnitSpec, makeDefaultFactory(UnitView));
|
|
73
93
|
this.addViewType(isVConcatSpec, makeDefaultFactory(ConcatView));
|
|
74
94
|
this.addViewType(isHConcatSpec, makeDefaultFactory(ConcatView));
|
|
75
95
|
this.addViewType(isConcatSpec, makeDefaultFactory(ConcatView));
|
|
76
96
|
//this.addViewType(isFacetSpec, makeDefaultFactory(FacetView));
|
|
77
|
-
|
|
78
|
-
this.addViewType(isSampleSpec, () => {
|
|
79
|
-
throw new Error(
|
|
80
|
-
"SampleView is not supported by the @genome-spy/core package. Use @genome-spy/app instead!"
|
|
81
|
-
);
|
|
82
|
-
});
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
/**
|
|
@@ -110,6 +124,12 @@ export class ViewFactory {
|
|
|
110
124
|
}
|
|
111
125
|
}
|
|
112
126
|
|
|
127
|
+
if (isSampleSpec(spec)) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
"SampleView is not supported by the @genome-spy/core package. Use @genome-spy/app instead!"
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
113
133
|
throw new Error(
|
|
114
134
|
"Invalid spec, cannot figure out the view type from the properties: " +
|
|
115
135
|
JSON.stringify([...Object.keys(spec)])
|
|
@@ -203,6 +223,7 @@ export class ViewFactory {
|
|
|
203
223
|
this.options.wrapRoot &&
|
|
204
224
|
(isUnitSpec(viewSpec) ||
|
|
205
225
|
isLayerSpec(viewSpec) ||
|
|
226
|
+
isMultiscaleSpec(viewSpec) ||
|
|
206
227
|
hasIntervalSelection(viewSpec)) &&
|
|
207
228
|
defaultName === VIEW_ROOT_NAME
|
|
208
229
|
) {
|
|
@@ -268,6 +289,10 @@ function applyParamsToImportedSpec(importedSpec, importSpec) {
|
|
|
268
289
|
importedSpec.name = importSpec.name;
|
|
269
290
|
}
|
|
270
291
|
|
|
292
|
+
if (importSpec.visible != null) {
|
|
293
|
+
importedSpec.visible = importSpec.visible;
|
|
294
|
+
}
|
|
295
|
+
|
|
271
296
|
const params = isArray(importSpec.params)
|
|
272
297
|
? importSpec.params
|
|
273
298
|
: isObject(importSpec.params)
|
|
@@ -333,19 +358,6 @@ export function isFacetSpec(spec) {
|
|
|
333
358
|
);
|
|
334
359
|
}
|
|
335
360
|
|
|
336
|
-
/**
|
|
337
|
-
*
|
|
338
|
-
* @param {ViewSpec} spec
|
|
339
|
-
* @returns {spec is import("../spec/view.js").AggregateSamplesSpec}
|
|
340
|
-
*/
|
|
341
|
-
export function isAggregateSamplesSpec(spec) {
|
|
342
|
-
return (
|
|
343
|
-
spec &&
|
|
344
|
-
(isUnitSpec(spec) || isLayerSpec(spec)) &&
|
|
345
|
-
"aggregateSamples" in spec
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
361
|
/**
|
|
350
362
|
*
|
|
351
363
|
* @param {object} spec
|
|
@@ -384,10 +396,9 @@ export function isConcatSpec(spec) {
|
|
|
384
396
|
|
|
385
397
|
/**
|
|
386
398
|
*
|
|
387
|
-
* @param {
|
|
388
|
-
* @returns {spec is SampleSpec}
|
|
399
|
+
* @param {object} spec
|
|
389
400
|
*/
|
|
390
|
-
|
|
401
|
+
function isSampleSpec(spec) {
|
|
391
402
|
return (
|
|
392
403
|
"samples" in spec &&
|
|
393
404
|
isObject(spec.samples) &&
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewParamRuntime.test.d.ts","sourceRoot":"","sources":["../../../src/view/viewParamRuntime.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewSelectors.d.ts","sourceRoot":"","sources":["../../../src/view/viewSelectors.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"viewSelectors.d.ts","sourceRoot":"","sources":["../../../src/view/viewSelectors.js"],"names":[],"mappings":"AAiCA;;;;;GAKG;AACH,6CAHW,OAAO,WAAW,EAAE,OAAO,aAC3B,MAAM,GAAG,IAAI,QAQvB;AAED;;;;;GAKG;AACH,yCAHW,OAAO,WAAW,EAAE,OAAO,GACzB,eAAe,GAAG,SAAS,CAIvC;AAED;;;;;GAKG;AACH,+CAHW,OAAO,WAAW,EAAE,OAAO,YAC3B,kBAAkB,QAM5B;AAED;;;;;GAKG;AACH,wCAHW,OAAO,WAAW,EAAE,OAAO,GACzB,MAAM,EAAE,CAgBpB;AAED;;;;;GAKG;AACH,sCAHW,OAAO,WAAW,EAAE,OAAO,GACzB,YAAY,CAYxB;AAED;;;;;;GAMG;AACH,uCAJW,OAAO,WAAW,EAAE,OAAO,aAC3B,MAAM,GACJ,aAAa,CAazB;AAED;;;;;GAKG;AACH,+CAHW,aAAa,GACX,MAAM,CAQlB;AAED;;;;;GAKG;AACH,0CAHW,OAAO,WAAW,EAAE,OAAO,GACzB,OAAO,WAAW,EAAE,OAAO,EAAE,CAWzC;AAED;;;;;GAKG;AACH,4CAHW,OAAO,WAAW,EAAE,OAAO,WAC3B,OAAO,WAAW,EAAE,OAAO,QAerC;AAED;;;;;;GAMG;AACH,0CAJW,OAAO,WAAW,EAAE,OAAO,YAC3B,YAAY,GACV,OAAO,WAAW,EAAE,OAAO,GAAG,SAAS,CAmCnD;AAED;;;;;;GAMG;AACH,2CAJW,OAAO,WAAW,EAAE,OAAO,YAC3B,aAAa,GACX,aAAa,GAAG,SAAS,CAuCrC;AAED;;;;;GAKG;AACH,8CAHW,OAAO,WAAW,EAAE,OAAO,WAC3B,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,QAyBjD;AAED;;;;;GAKG;AACH,4CAHW,OAAO,WAAW,EAAE,OAAO,GACzB,sBAAsB,EAAE,CAOpC;AAED;;;;;GAKG;AACH,kDAHW,OAAO,WAAW,EAAE,OAAO,GACzB,uBAAuB,EAAE,CAcrC;AArUD;;;;;;GAMG;AAEH;;;;;;;;;GASG;AAEH,wCAAyC,IAAI,CAAC;2BAVjC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;4BACjC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;qCAClC;IAAE,IAAI,EAAE,OAAO,WAAW,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,sBAAsB,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE;sCAC/G;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE;8BACpC;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE;kCACvB,SAAS,GAAG,gBAAgB;iCAC5B;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE;4BACzB;IAAE,IAAI,EAAE,OAAO,WAAW,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,sBAAsB,EAAE,SAAS,CAAA;CAAE"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { VISIT_SKIP, VISIT_STOP } from "./view.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
isSelectionParameter,
|
|
4
|
+
isVariableParameter,
|
|
5
|
+
} from "../paramRuntime/paramUtils.js";
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* Selectors identify views and parameters in a way that stays stable when the
|
|
@@ -237,7 +240,7 @@ export function resolveParamSelector(root, selector) {
|
|
|
237
240
|
const matches = [];
|
|
238
241
|
|
|
239
242
|
visitViewsInScope(scopeRoot, (view) => {
|
|
240
|
-
for (const [name, param] of view.
|
|
243
|
+
for (const [name, param] of view.paramRuntime.paramConfigs) {
|
|
241
244
|
if (name !== selector.param) {
|
|
242
245
|
continue;
|
|
243
246
|
}
|
|
@@ -281,7 +284,7 @@ export function visitBookmarkableParams(root, visitor) {
|
|
|
281
284
|
return;
|
|
282
285
|
}
|
|
283
286
|
|
|
284
|
-
for (const [name, param] of view.
|
|
287
|
+
for (const [name, param] of view.paramRuntime.paramConfigs) {
|
|
285
288
|
if (!isBookmarkableParam(param)) {
|
|
286
289
|
continue;
|
|
287
290
|
}
|
|
@@ -530,7 +533,7 @@ function validateParamNamesInScope(scopeRoot, scope, issues) {
|
|
|
530
533
|
const names = new Map();
|
|
531
534
|
|
|
532
535
|
visitViewsInScope(scopeRoot, (view) => {
|
|
533
|
-
for (const [name, param] of view.
|
|
536
|
+
for (const [name, param] of view.paramRuntime.paramConfigs) {
|
|
534
537
|
if (!isBookmarkableParam(param)) {
|
|
535
538
|
continue;
|
|
536
539
|
}
|
|
@@ -672,7 +675,7 @@ function hasAddressableFeatures(root) {
|
|
|
672
675
|
return VISIT_STOP;
|
|
673
676
|
}
|
|
674
677
|
|
|
675
|
-
for (const param of view.
|
|
678
|
+
for (const param of view.paramRuntime.paramConfigs.values()) {
|
|
676
679
|
if (isBookmarkableParam(param)) {
|
|
677
680
|
found = true;
|
|
678
681
|
return VISIT_STOP;
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"contributors": [],
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.69.0",
|
|
11
11
|
"jsdelivr": "dist/bundle/index.js",
|
|
12
12
|
"unpkg": "dist/bundle/index.js",
|
|
13
13
|
"browser": "dist/bundle/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"build": "rm -rf dist && mkdir -p dist && node scripts/build.mjs && vite build && npm run build:schema && npm run build:typings",
|
|
31
31
|
"prepublishOnly": "npm run build",
|
|
32
32
|
"test:tsc": "tsc -p tsconfig.json --noEmit",
|
|
33
|
-
"build:schema": "mkdir -p dist && ts-json-schema-generator --path 'src/spec/*.ts' --type
|
|
33
|
+
"build:schema": "mkdir -p dist && ts-json-schema-generator --path 'src/spec/*.ts' --type CoreRootSpec > dist/schema.json",
|
|
34
34
|
"build:typings": "tsc -p tsconfig.json --declaration --emitDeclarationOnly --declarationMap --outDir dist/src",
|
|
35
35
|
"prepack": "node scripts/prepack.mjs",
|
|
36
36
|
"postpack": "node scripts/postpack.mjs"
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/long": "^4.0.1"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "bfb9bd98ceb875f90a458b876208b15b6c12c9f3"
|
|
71
71
|
}
|