@genome-spy/core 0.43.3 → 0.45.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 +5231 -4324
- package/dist/bundle/index.js +197 -85
- package/dist/schema.json +723 -104
- package/dist/src/data/collector.d.ts.map +1 -1
- package/dist/src/data/collector.js +4 -2
- package/dist/src/data/flowOptimizer.test.js +12 -3
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +3 -1
- 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.d.ts +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.js +52 -20
- package/dist/src/data/sources/lazy/bigWigSource.d.ts +6 -1
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +33 -9
- 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 -3
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts +13 -14
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +70 -48
- package/dist/src/data/sources/sequenceSource.d.ts.map +1 -1
- package/dist/src/data/sources/sequenceSource.js +14 -5
- package/dist/src/data/sources/sequenceSource.test.js +23 -5
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +15 -2
- package/dist/src/data/transforms/aggregate.d.ts.map +1 -1
- package/dist/src/data/transforms/aggregate.js +5 -2
- package/dist/src/data/transforms/filterScoredLabels.js +1 -1
- package/dist/src/encoder/encoder.d.ts +2 -4
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +20 -10
- package/dist/src/encoder/encoder.test.js +3 -0
- package/dist/src/genomeSpy.d.ts +8 -5
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +121 -42
- 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/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- 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 +25 -20
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +234 -129
- package/dist/src/marks/point.common.glsl.js +1 -1
- package/dist/src/marks/point.d.ts +1 -4
- package/dist/src/marks/point.d.ts.map +1 -1
- package/dist/src/marks/point.js +31 -23
- package/dist/src/marks/point.vertex.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.d.ts.map +1 -1
- package/dist/src/marks/text.js +17 -9
- package/dist/src/spec/channel.d.ts +4 -3
- package/dist/src/spec/data.d.ts +11 -10
- package/dist/src/spec/mark.d.ts +28 -46
- package/dist/src/spec/parameter.d.ts +127 -0
- package/dist/src/spec/root.d.ts +1 -0
- package/dist/src/spec/scale.d.ts +2 -1
- package/dist/src/spec/title.d.ts +5 -4
- package/dist/src/spec/view.d.ts +20 -5
- package/dist/src/styles/genome-spy.css.d.ts +1 -1
- package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
- package/dist/src/styles/genome-spy.css.js +52 -5
- package/dist/src/styles/genome-spy.scss +63 -10
- package/dist/src/styles/update.sh +6 -0
- package/dist/src/tooltip/dataTooltipHandler.js +1 -1
- package/dist/src/tooltip/refseqGeneTooltipHandler.js +1 -1
- package/dist/src/tooltip/tooltipHandler.d.ts +1 -1
- package/dist/src/tooltip/tooltipHandler.d.ts.map +1 -1
- package/dist/src/tooltip/tooltipHandler.ts +1 -1
- package/dist/src/types/embedApi.d.ts +6 -0
- package/dist/src/types/scaleResolutionApi.d.ts +7 -3
- package/dist/src/types/viewContext.d.ts +2 -3
- package/dist/src/utils/debounce.d.ts +2 -2
- package/dist/src/utils/debounce.d.ts.map +1 -1
- package/dist/src/utils/debounce.js +5 -2
- 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/utils/formatObject.d.ts +2 -2
- package/dist/src/utils/formatObject.d.ts.map +1 -1
- package/dist/src/utils/formatObject.js +2 -2
- package/dist/src/utils/inputBinding.d.ts +5 -0
- package/dist/src/utils/inputBinding.d.ts.map +1 -0
- package/dist/src/utils/inputBinding.js +115 -0
- package/dist/src/utils/ui/tooltip.js +1 -1
- package/dist/src/view/axisView.js +3 -3
- package/dist/src/view/paramMediator.d.ts +108 -0
- package/dist/src/view/paramMediator.d.ts.map +1 -0
- package/dist/src/view/paramMediator.js +337 -0
- package/dist/src/view/paramMediator.test.js +211 -0
- 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 +225 -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.d.ts +4 -1
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +21 -7
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +45 -0
- package/dist/src/view/viewUtils.d.ts +5 -1
- package/dist/src/view/viewUtils.d.ts.map +1 -1
- package/dist/src/view/viewUtils.js +9 -4
- package/package.json +16 -17
- package/dist/src/paramBroker.d.ts +0 -30
- package/dist/src/paramBroker.d.ts.map +0 -1
- package/dist/src/paramBroker.js +0 -102
package/dist/src/spec/title.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { Align, Baseline, FontStyle, FontWeight } from "./font.js";
|
|
12
|
+
import { ExprRef } from "./parameter.js";
|
|
12
13
|
|
|
13
14
|
export type TitleOrient = "none" | "left" | "right" | "top" | "bottom";
|
|
14
15
|
export type TitleAnchor = null | "start" | "middle" | "end";
|
|
@@ -18,7 +19,7 @@ export interface Title {
|
|
|
18
19
|
/**
|
|
19
20
|
* The title text.
|
|
20
21
|
*/
|
|
21
|
-
text: string;
|
|
22
|
+
text: string | ExprRef;
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* A mark style property to apply to the title text mark. If not specified, a default style of `"group-title"` is applied.
|
|
@@ -54,7 +55,7 @@ export interface Title {
|
|
|
54
55
|
/**
|
|
55
56
|
* Angle in degrees of title and subtitle text.
|
|
56
57
|
*/
|
|
57
|
-
angle?: number;
|
|
58
|
+
angle?: number | ExprRef;
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* Vertical text baseline for title and subtitle text. One of `"alphabetic"` (default), `"top"`, `"middle"`, or `"bottom"`.
|
|
@@ -75,7 +76,7 @@ export interface Title {
|
|
|
75
76
|
/**
|
|
76
77
|
* Text color for title text.
|
|
77
78
|
*/
|
|
78
|
-
color?: string;
|
|
79
|
+
color?: string | ExprRef;
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
82
|
* Font name for title text.
|
|
@@ -87,7 +88,7 @@ export interface Title {
|
|
|
87
88
|
*
|
|
88
89
|
* @minimum 0
|
|
89
90
|
*/
|
|
90
|
-
fontSize?: number;
|
|
91
|
+
fontSize?: number | ExprRef;
|
|
91
92
|
|
|
92
93
|
/**
|
|
93
94
|
* Font style for title text.
|
package/dist/src/spec/view.d.ts
CHANGED
|
@@ -7,14 +7,15 @@ import {
|
|
|
7
7
|
PrimaryPositionalChannel,
|
|
8
8
|
} from "./channel.js";
|
|
9
9
|
import {
|
|
10
|
-
ExprRef,
|
|
11
10
|
FillAndStrokeProps,
|
|
12
11
|
MarkConfigAndType,
|
|
13
12
|
MarkType,
|
|
14
13
|
RectProps,
|
|
15
14
|
} from "./mark.js";
|
|
15
|
+
import { ExprRef } from "./parameter.js";
|
|
16
16
|
import { Title } from "./title.js";
|
|
17
17
|
import { SampleSpec } from "./sampleView.js";
|
|
18
|
+
import { VariableParameter } from "./parameter.js";
|
|
18
19
|
|
|
19
20
|
export interface SizeDef {
|
|
20
21
|
/** Size in pixels */
|
|
@@ -108,6 +109,11 @@ export interface ViewSpecBase extends ResolveSpec {
|
|
|
108
109
|
*/
|
|
109
110
|
padding?: PaddingConfig;
|
|
110
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Dynamic variables that parameterize a visualization.
|
|
114
|
+
*/
|
|
115
|
+
params?: VariableParameter[];
|
|
116
|
+
|
|
111
117
|
data?: Data;
|
|
112
118
|
transform?: TransformParams[];
|
|
113
119
|
encoding?: Encoding;
|
|
@@ -212,14 +218,23 @@ export type ViewSpec =
|
|
|
212
218
|
| ConcatSpec
|
|
213
219
|
| SampleSpec;
|
|
214
220
|
|
|
215
|
-
export interface
|
|
216
|
-
name?: string;
|
|
221
|
+
export interface ImportParams {
|
|
217
222
|
url?: string;
|
|
218
|
-
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Name for the imported view. Overrides the name defined in the imported spec.
|
|
226
|
+
*/
|
|
227
|
+
name?: string;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Dynamic variables that parameterize a visualization. Parameters defined here
|
|
231
|
+
* override the parameters defined in the imported spec.
|
|
232
|
+
*/
|
|
233
|
+
params?: VariableParameter[] | Record<string, any>;
|
|
219
234
|
}
|
|
220
235
|
|
|
221
236
|
export interface ImportSpec {
|
|
222
|
-
import:
|
|
237
|
+
import: ImportParams;
|
|
223
238
|
}
|
|
224
239
|
|
|
225
240
|
export interface ConcatBase extends ViewSpecBase {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export default css;
|
|
2
|
-
declare const css: ".genome-spy {\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n position: relative;\n}\n.genome-spy canvas {\n transform: scale(1, 1);\n opacity: 1;\n transition: transform 0.6s, opacity 0.6s;\n}\n.genome-spy .loading-message {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-message .message {\n color: #666;\n opacity: 0;\n transition: opacity 0.7s;\n}\n.genome-spy.loading canvas {\n transform: scale(0.95, 0.95);\n opacity: 0;\n}\n.genome-spy.loading .loading-message .message {\n opacity: 1;\n}\n.genome-spy.loading .ellipsis {\n animation: blinker 1s linear infinite;\n}\n@keyframes blinker {\n 50% {\n opacity: 0;\n }\n}\n.genome-spy .loading-indicators {\n position: absolute;\n inset: 0;\n user-select: none;\n pointer-events: none;\n}\n.genome-spy .loading-indicators div {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-indicators div > div {\n font-size: 11px;\n transition: opacity 0.2s;\n background: white;\n padding: 2px 5px;\n display: flex;\n border-radius: 3px;\n gap: 0.5em;\n opacity: 0;\n}\n.genome-spy .loading-indicators div > div.loading {\n opacity: 0.5;\n}\n.genome-spy .loading-indicators div > div > * {\n display: block;\n}\n.genome-spy .loading-indicators div > div img {\n width: 1.5em;\n height: 1.5em;\n}\n.genome-spy .tooltip {\n position: absolute;\n max-width: 450px;\n overflow: hidden;\n background: #f6f6f6;\n padding: 10px;\n font-size: 13px;\n box-shadow: 0px 3px 15px 0px rgba(0, 0, 0, 0.21);\n pointer-events: none;\n z-index: 100;\n}\n.genome-spy .tooltip > :last-child {\n margin-bottom: 0;\n}\n.genome-spy .tooltip > .title {\n padding-bottom: 5px;\n margin-bottom: 5px;\n border-bottom: 1px dashed #b6b6b6;\n}\n.genome-spy .tooltip .summary {\n font-size: 12px;\n}\n.genome-spy .tooltip table {\n border-collapse: collapse;\n}\n.genome-spy .tooltip table:first-child {\n margin-top: 0;\n}\n.genome-spy .tooltip table th,\n.genome-spy .tooltip table td {\n padding: 2px 0.4em;\n vertical-align: top;\n}\n.genome-spy .tooltip table th:first-child,\n.genome-spy .tooltip table td:first-child {\n padding-left: 0;\n}\n.genome-spy .tooltip table th {\n text-align: left;\n font-weight: bold;\n}\n.genome-spy .tooltip .color-legend {\n display: inline-block;\n width: 0.8em;\n height: 0.8em;\n margin-left: 0.4em;\n box-shadow: 0px 0px 3px 1px white;\n}\n.genome-spy .tooltip .attributes .hovered {\n background-color: #e0e0e0;\n}\n.genome-spy .tooltip .na {\n color: #aaa;\n font-style: italic;\n font-size: 80%;\n}\n.genome-spy .gene-track-tooltip .summary {\n font-size: 90%;\n}\n.genome-spy .message-box {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: 0;\n height: 100%;\n width: 100%;\n}\n.genome-spy .message-box > div {\n border: 1px solid red;\n padding: 10px;\n background: #fff0f0;\n}";
|
|
2
|
+
declare const css: "\n.genome-spy {\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n position: relative;\n display: flex;\n flex-direction: column;\n}\n.genome-spy .canvas-wrapper {\n position: relative;\n flex-grow: 1;\n overflow: hidden;\n}\n.genome-spy canvas {\n transform: scale(1, 1);\n opacity: 1;\n transition: transform 0.6s, opacity 0.6s;\n}\n.genome-spy .loading-message {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-message .message {\n color: #666;\n opacity: 0;\n transition: opacity 0.7s;\n}\n.genome-spy .loading > canvas {\n transform: scale(0.95, 0.95);\n opacity: 0;\n}\n.genome-spy .loading > .loading-message .message {\n opacity: 1;\n}\n.genome-spy .loading > .loading-message .message .ellipsis {\n animation: blinker 1s linear infinite;\n}\n@keyframes blinker {\n 50% {\n opacity: 0;\n }\n}\n.genome-spy .loading-indicators {\n position: absolute;\n inset: 0;\n user-select: none;\n pointer-events: none;\n}\n.genome-spy .loading-indicators div {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-indicators div > div {\n font-size: 11px;\n transition: opacity 0.2s;\n background: white;\n padding: 2px 5px;\n display: flex;\n border-radius: 3px;\n gap: 0.5em;\n opacity: 0;\n}\n.genome-spy .loading-indicators div > div.loading {\n opacity: 0.5;\n}\n.genome-spy .loading-indicators div > div > * {\n display: block;\n}\n.genome-spy .loading-indicators div > div img {\n width: 1.5em;\n height: 1.5em;\n}\n.genome-spy .tooltip {\n position: absolute;\n max-width: 450px;\n overflow: hidden;\n background: #f6f6f6;\n padding: 10px;\n font-size: 13px;\n box-shadow: 0px 3px 15px 0px rgba(0, 0, 0, 0.21);\n pointer-events: none;\n z-index: 100;\n}\n.genome-spy .tooltip > :last-child {\n margin-bottom: 0;\n}\n.genome-spy .tooltip > .title {\n padding-bottom: 5px;\n margin-bottom: 5px;\n border-bottom: 1px dashed #b6b6b6;\n}\n.genome-spy .tooltip .summary {\n font-size: 12px;\n}\n.genome-spy .tooltip table {\n border-collapse: collapse;\n}\n.genome-spy .tooltip table:first-child {\n margin-top: 0;\n}\n.genome-spy .tooltip table th,\n.genome-spy .tooltip table td {\n padding: 2px 0.4em;\n vertical-align: top;\n}\n.genome-spy .tooltip table th:first-child,\n.genome-spy .tooltip table td:first-child {\n padding-left: 0;\n}\n.genome-spy .tooltip table th {\n text-align: left;\n font-weight: bold;\n}\n.genome-spy .tooltip .color-legend {\n display: inline-block;\n width: 0.8em;\n height: 0.8em;\n margin-left: 0.4em;\n box-shadow: 0px 0px 3px 1px white;\n}\n.genome-spy .tooltip .attributes .hovered {\n background-color: #e0e0e0;\n}\n.genome-spy .tooltip .na {\n color: #aaa;\n font-style: italic;\n font-size: 80%;\n}\n.genome-spy .gene-track-tooltip .summary {\n font-size: 90%;\n}\n.genome-spy .message-box {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: 0;\n height: 100%;\n width: 100%;\n}\n.genome-spy .message-box > div {\n border: 1px solid red;\n padding: 10px;\n background: #fff0f0;\n}\n\n.gs-input-binding {\n display: grid;\n grid-template-columns: max-content max-content;\n column-gap: 1em;\n row-gap: 0.3em;\n justify-items: start;\n}\n.gs-input-binding > select,\n.gs-input-binding > input:not([type=checkbox]) {\n width: 100%;\n}\n.gs-input-binding input[type=range] + span {\n display: inline-block;\n margin-left: 0.3em;\n min-width: 2.2em;\n font-variant-numeric: tabular-nums;\n}\n.gs-input-binding input[type=range],\n.gs-input-binding input[type=radio] {\n vertical-align: text-bottom;\n}\n.gs-input-binding .radio-group {\n display: flex;\n align-items: center;\n}\n.gs-input-binding .description {\n max-width: 26em;\n grid-column: 1/-1;\n color: #777;\n font-size: 90%;\n margin-top: -0.5em;\n}\n\n.gs-input-bindings {\n flex-basis: content;\n font-size: 14px;\n padding: 10px;\n}\n";
|
|
3
3
|
//# sourceMappingURL=genome-spy.css.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,6iIA4LE"}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
const css =
|
|
1
|
+
const css = `
|
|
2
|
+
.genome-spy {
|
|
2
3
|
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
3
4
|
position: relative;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
}
|
|
8
|
+
.genome-spy .canvas-wrapper {
|
|
9
|
+
position: relative;
|
|
10
|
+
flex-grow: 1;
|
|
11
|
+
overflow: hidden;
|
|
4
12
|
}
|
|
5
13
|
.genome-spy canvas {
|
|
6
14
|
transform: scale(1, 1);
|
|
@@ -19,14 +27,14 @@ const css = `.genome-spy {
|
|
|
19
27
|
opacity: 0;
|
|
20
28
|
transition: opacity 0.7s;
|
|
21
29
|
}
|
|
22
|
-
.genome-spy.loading canvas {
|
|
30
|
+
.genome-spy .loading > canvas {
|
|
23
31
|
transform: scale(0.95, 0.95);
|
|
24
32
|
opacity: 0;
|
|
25
33
|
}
|
|
26
|
-
.genome-spy.loading .loading-message .message {
|
|
34
|
+
.genome-spy .loading > .loading-message .message {
|
|
27
35
|
opacity: 1;
|
|
28
36
|
}
|
|
29
|
-
.genome-spy.loading .ellipsis {
|
|
37
|
+
.genome-spy .loading > .loading-message .message .ellipsis {
|
|
30
38
|
animation: blinker 1s linear infinite;
|
|
31
39
|
}
|
|
32
40
|
@keyframes blinker {
|
|
@@ -138,6 +146,45 @@ const css = `.genome-spy {
|
|
|
138
146
|
border: 1px solid red;
|
|
139
147
|
padding: 10px;
|
|
140
148
|
background: #fff0f0;
|
|
141
|
-
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.gs-input-binding {
|
|
152
|
+
display: grid;
|
|
153
|
+
grid-template-columns: max-content max-content;
|
|
154
|
+
column-gap: 1em;
|
|
155
|
+
row-gap: 0.3em;
|
|
156
|
+
justify-items: start;
|
|
157
|
+
}
|
|
158
|
+
.gs-input-binding > select,
|
|
159
|
+
.gs-input-binding > input:not([type=checkbox]) {
|
|
160
|
+
width: 100%;
|
|
161
|
+
}
|
|
162
|
+
.gs-input-binding input[type=range] + span {
|
|
163
|
+
display: inline-block;
|
|
164
|
+
margin-left: 0.3em;
|
|
165
|
+
min-width: 2.2em;
|
|
166
|
+
font-variant-numeric: tabular-nums;
|
|
167
|
+
}
|
|
168
|
+
.gs-input-binding input[type=range],
|
|
169
|
+
.gs-input-binding input[type=radio] {
|
|
170
|
+
vertical-align: text-bottom;
|
|
171
|
+
}
|
|
172
|
+
.gs-input-binding .radio-group {
|
|
173
|
+
display: flex;
|
|
174
|
+
align-items: center;
|
|
175
|
+
}
|
|
176
|
+
.gs-input-binding .description {
|
|
177
|
+
max-width: 26em;
|
|
178
|
+
grid-column: 1/-1;
|
|
179
|
+
color: #777;
|
|
180
|
+
font-size: 90%;
|
|
181
|
+
margin-top: -0.5em;
|
|
182
|
+
}
|
|
142
183
|
|
|
184
|
+
.gs-input-bindings {
|
|
185
|
+
flex-basis: content;
|
|
186
|
+
font-size: 14px;
|
|
187
|
+
padding: 10px;
|
|
188
|
+
}
|
|
189
|
+
`;
|
|
143
190
|
export default css;
|
|
@@ -10,6 +10,15 @@ $font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
|
|
10
10
|
|
|
11
11
|
position: relative;
|
|
12
12
|
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
|
|
16
|
+
.canvas-wrapper {
|
|
17
|
+
position: relative;
|
|
18
|
+
flex-grow: 1;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
canvas {
|
|
14
23
|
transform: scale(1, 1);
|
|
15
24
|
opacity: 1;
|
|
@@ -31,23 +40,23 @@ $font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
|
|
35
|
-
canvas {
|
|
43
|
+
.loading {
|
|
44
|
+
> canvas {
|
|
36
45
|
transform: scale(0.95, 0.95);
|
|
37
46
|
opacity: 0;
|
|
38
47
|
}
|
|
39
48
|
|
|
40
|
-
.loading-message .message {
|
|
49
|
+
> .loading-message .message {
|
|
41
50
|
opacity: 1;
|
|
42
|
-
}
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
.ellipsis {
|
|
53
|
+
animation: blinker 1s linear infinite;
|
|
54
|
+
}
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
@keyframes blinker {
|
|
57
|
+
50% {
|
|
58
|
+
opacity: 0;
|
|
59
|
+
}
|
|
51
60
|
}
|
|
52
61
|
}
|
|
53
62
|
}
|
|
@@ -187,3 +196,47 @@ $font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
|
|
187
196
|
}
|
|
188
197
|
}
|
|
189
198
|
}
|
|
199
|
+
|
|
200
|
+
.gs-input-binding {
|
|
201
|
+
display: grid;
|
|
202
|
+
grid-template-columns: max-content max-content;
|
|
203
|
+
column-gap: 1em;
|
|
204
|
+
row-gap: 0.3em;
|
|
205
|
+
justify-items: start;
|
|
206
|
+
|
|
207
|
+
> select,
|
|
208
|
+
> input:not([type="checkbox"]) {
|
|
209
|
+
width: 100%;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
input[type="range"] + span {
|
|
213
|
+
display: inline-block;
|
|
214
|
+
margin-left: 0.3em;
|
|
215
|
+
min-width: 2.2em;
|
|
216
|
+
font-variant-numeric: tabular-nums;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
input[type="range"],
|
|
220
|
+
input[type="radio"] {
|
|
221
|
+
vertical-align: text-bottom;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.radio-group {
|
|
225
|
+
display: flex;
|
|
226
|
+
align-items: center;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.description {
|
|
230
|
+
max-width: 26em;
|
|
231
|
+
grid-column: 1 / -1;
|
|
232
|
+
color: #777;
|
|
233
|
+
font-size: 90%;
|
|
234
|
+
margin-top: -0.5em;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.gs-input-bindings {
|
|
239
|
+
flex-basis: content;
|
|
240
|
+
font-size: 14px;
|
|
241
|
+
padding: $basic-spacing;
|
|
242
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltipHandler.d.ts","sourceRoot":"","sources":["../../../src/tooltip/tooltipHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"tooltipHandler.d.ts","sourceRoot":"","sources":["../../../src/tooltip/tooltipHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AACrC,OAAO,IAAI,MAAM,kBAAkB,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,IAAI,EAAE,IAAI;AACV,sDAAsD;AACtD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAC3B,OAAO,CAAC,MAAM,GAAG,cAAc,GAAG,WAAW,CAAC,CAAC"}
|
|
@@ -27,6 +27,12 @@ export interface EmbedOptions {
|
|
|
27
27
|
* Custom tooltip handlers. Use `"default"` to override the default handler
|
|
28
28
|
*/
|
|
29
29
|
tooltipHandlers?: Record<string, TooltipHandler>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Where to put the input binding elements. The default is `"default"`, which means that
|
|
33
|
+
* the input binding elements are placed in the same container as the GenomeSpy instance.
|
|
34
|
+
*/
|
|
35
|
+
inputBindingContainer?: HTMLElement | "none" | "default";
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ComplexDomain, NumericDomain } from "../spec/scale.js";
|
|
2
2
|
import ScaleResolution from "../view/scaleResolution.js";
|
|
3
3
|
|
|
4
|
+
export type ScaleResolutionEventType = "domain" | "range";
|
|
4
5
|
export interface ScaleResolutionEvent {
|
|
5
|
-
type:
|
|
6
|
+
type: ScaleResolutionEventType;
|
|
6
7
|
|
|
7
8
|
scaleResolution: ScaleResolution;
|
|
8
9
|
}
|
|
@@ -13,10 +14,13 @@ export type ScaleResolutionListener = (event: ScaleResolutionEvent) => void;
|
|
|
13
14
|
* A public API for ScaleResolution
|
|
14
15
|
*/
|
|
15
16
|
export interface ScaleResolutionApi {
|
|
16
|
-
addEventListener(
|
|
17
|
+
addEventListener(
|
|
18
|
+
type: ScaleResolutionEventType,
|
|
19
|
+
listener: ScaleResolutionListener
|
|
20
|
+
): void;
|
|
17
21
|
|
|
18
22
|
removeEventListener(
|
|
19
|
-
type:
|
|
23
|
+
type: ScaleResolutionEventType,
|
|
20
24
|
listener: ScaleResolutionListener
|
|
21
25
|
): void;
|
|
22
26
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TemplateResult } from "lit
|
|
1
|
+
import { TemplateResult } from "lit";
|
|
2
2
|
import View, { BroadcastMessage } from "../view/view.js";
|
|
3
3
|
import DataFlow from "../data/dataFlow.js";
|
|
4
4
|
import AccessorFactory from "../encoder/accessor.js";
|
|
@@ -11,7 +11,7 @@ import { Datum } from "../data/flowNode.js";
|
|
|
11
11
|
import { ImportSpec, ViewSpec } from "../spec/view.js";
|
|
12
12
|
import ContainerView from "./containerView.js";
|
|
13
13
|
import { BroadcastEventType } from "../genomeSpy.js";
|
|
14
|
-
import
|
|
14
|
+
import ParamMediator from "../view/paramMediator.js";
|
|
15
15
|
|
|
16
16
|
export interface Hover {
|
|
17
17
|
mark: Mark;
|
|
@@ -29,7 +29,6 @@ export default interface ViewContext {
|
|
|
29
29
|
genomeStore?: GenomeStore;
|
|
30
30
|
fontManager: BmFontManager;
|
|
31
31
|
|
|
32
|
-
paramBroker: ParamBroker;
|
|
33
32
|
devicePixelRatio: number;
|
|
34
33
|
|
|
35
34
|
requestLayoutReflow: () => void;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @param {(...args:T) => R} func
|
|
3
|
-
* @param {number} wait
|
|
3
|
+
* @param {number | (() => number)} wait
|
|
4
4
|
* @template {any[]} T
|
|
5
5
|
* @template R
|
|
6
6
|
*/
|
|
7
|
-
export function debounce<T extends any[], R>(func: (...args: T) => R, wait: number, rejectOnDebounce?: boolean): (...args: T) => Promise<R>;
|
|
7
|
+
export function debounce<T extends any[], R>(func: (...args: T) => R, wait: number | (() => number), rejectOnDebounce?: boolean): (...args: T) => Promise<R>;
|
|
8
8
|
//# sourceMappingURL=debounce.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../../src/utils/debounce.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,4EAJW,MAAM,
|
|
1
|
+
{"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../../src/utils/debounce.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,4EAJW,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,0DAqCjC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @param {(...args:T) => R} func
|
|
3
|
-
* @param {number} wait
|
|
3
|
+
* @param {number | (() => number)} wait
|
|
4
4
|
* @template {any[]} T
|
|
5
5
|
* @template R
|
|
6
6
|
*/
|
|
@@ -29,7 +29,10 @@ export function debounce(func, wait, rejectOnDebounce = true) {
|
|
|
29
29
|
clearTimeout(timeout);
|
|
30
30
|
|
|
31
31
|
rejectPrevious = reject;
|
|
32
|
-
timeout = window.setTimeout(
|
|
32
|
+
timeout = window.setTimeout(
|
|
33
|
+
later,
|
|
34
|
+
typeof wait == "function" ? wait() : wait
|
|
35
|
+
);
|
|
33
36
|
});
|
|
34
37
|
};
|
|
35
38
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @prop { string[] } globals
|
|
5
5
|
* @prop { string } code
|
|
6
6
|
*
|
|
7
|
-
* @typedef { ((
|
|
7
|
+
* @typedef { ((datum?: object) => any) & ExpressionProps } ExpressionFunction
|
|
8
8
|
*
|
|
9
9
|
* @param {string} expr
|
|
10
10
|
* @returns {ExpressionFunction}
|
|
@@ -15,5 +15,5 @@ export type ExpressionProps = {
|
|
|
15
15
|
globals: string[];
|
|
16
16
|
code: string;
|
|
17
17
|
};
|
|
18
|
-
export type ExpressionFunction = ((
|
|
18
|
+
export type ExpressionFunction = ((datum?: object) => any) & ExpressionProps;
|
|
19
19
|
//# sourceMappingURL=expression.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/utils/expression.js"],"names":[],"mappings":"AAyDA;;;;;;;;;;GAUG;AACH,6CAHW,MAAM,sBACJ,kBAAkB,CAyB9B;;YAhCU,MAAM,EAAE;aACR,MAAM,EAAE;UACR,MAAM;;
|
|
1
|
+
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/utils/expression.js"],"names":[],"mappings":"AAyDA;;;;;;;;;;GAUG;AACH,6CAHW,MAAM,sBACJ,kBAAkB,CAyB9B;;YAhCU,MAAM,EAAE;aACR,MAAM,EAAE;UACR,MAAM;;2CAEO,MAAM,KAAK,GAAG"}
|
|
@@ -61,7 +61,7 @@ const cg = codegenExpression({
|
|
|
61
61
|
* @prop { string[] } globals
|
|
62
62
|
* @prop { string } code
|
|
63
63
|
*
|
|
64
|
-
* @typedef { ((
|
|
64
|
+
* @typedef { ((datum?: object) => any) & ExpressionProps } ExpressionFunction
|
|
65
65
|
*
|
|
66
66
|
* @param {string} expr
|
|
67
67
|
* @returns {ExpressionFunction}
|
|
@@ -79,8 +79,8 @@ export default function createFunction(expr, globalObject = {}) {
|
|
|
79
79
|
).bind(functionContext);
|
|
80
80
|
|
|
81
81
|
/** @type { ExpressionFunction } */
|
|
82
|
-
const exprFunction = /** @param {object}
|
|
83
|
-
fn(
|
|
82
|
+
const exprFunction = /** @param {object} datum */ (datum) =>
|
|
83
|
+
fn(datum, globalObject);
|
|
84
84
|
exprFunction.fields = generatedCode.fields;
|
|
85
85
|
exprFunction.globals = generatedCode.globals;
|
|
86
86
|
exprFunction.code = generatedCode.code;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
*
|
|
3
3
|
* @param {any} object Object to format
|
|
4
|
-
* @returns {string | import("lit
|
|
4
|
+
* @returns {string | import("lit").TemplateResult}
|
|
5
5
|
*/
|
|
6
|
-
export default function formatObject(object: any): string | import("lit
|
|
6
|
+
export default function formatObject(object: any): string | import("lit").TemplateResult;
|
|
7
7
|
//# sourceMappingURL=formatObject.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatObject.d.ts","sourceRoot":"","sources":["../../../src/utils/formatObject.js"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,6CAHW,GAAG,GACD,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"formatObject.d.ts","sourceRoot":"","sources":["../../../src/utils/formatObject.js"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,6CAHW,GAAG,GACD,MAAM,GAAG,OAAO,KAAK,EAAE,cAAc,CA0BjD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isNumber, isString, isBoolean, isArray } from "vega-util";
|
|
2
2
|
import { format as d3format } from "d3-format";
|
|
3
|
-
import { html, nothing } from "lit
|
|
3
|
+
import { html, nothing } from "lit";
|
|
4
4
|
|
|
5
5
|
const numberFormat = d3format(".4~r");
|
|
6
6
|
const exponentNumberFormat = d3format(".4~e");
|
|
@@ -8,7 +8,7 @@ const exponentNumberFormat = d3format(".4~e");
|
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
10
10
|
* @param {any} object Object to format
|
|
11
|
-
* @returns {string | import("lit
|
|
11
|
+
* @returns {string | import("lit").TemplateResult}
|
|
12
12
|
*/
|
|
13
13
|
export default function formatObject(object) {
|
|
14
14
|
if (object === null || object === undefined) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputBinding.d.ts","sourceRoot":"","sources":["../../../src/utils/inputBinding.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,sDAFW,OAAO,0BAA0B,EAAE,OAAO,8CA6GpD"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import { debounce } from "./debounce.js";
|
|
3
|
+
import { tickStep } from "d3-array";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {import("../view/paramMediator.js").default} mediator
|
|
7
|
+
*/
|
|
8
|
+
export default function createBindingInputs(mediator) {
|
|
9
|
+
const random = Math.floor(Math.random() * 0xffffff).toString(16);
|
|
10
|
+
|
|
11
|
+
/** @type {import("lit").TemplateResult[]} */
|
|
12
|
+
const inputs = [];
|
|
13
|
+
|
|
14
|
+
for (const param of mediator.paramConfigs.values()) {
|
|
15
|
+
const bind = param.bind;
|
|
16
|
+
if (!bind || !("input" in bind)) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const name = param.name;
|
|
21
|
+
const setter = mediator.getSetter(name);
|
|
22
|
+
const value = mediator.getValue(name);
|
|
23
|
+
const label = bind.name ?? name;
|
|
24
|
+
|
|
25
|
+
// TODO: Implement two-way data binding, e.g. when an external agent changes
|
|
26
|
+
// the parameter value, the UI components should be updated.
|
|
27
|
+
|
|
28
|
+
const debouncedSetter = bind.debounce
|
|
29
|
+
? debounce(setter, bind.debounce, false)
|
|
30
|
+
: setter;
|
|
31
|
+
|
|
32
|
+
const id = `${random}-param-${name}`;
|
|
33
|
+
|
|
34
|
+
if (bind.input == "range") {
|
|
35
|
+
// TODO: Show the value next to the slider
|
|
36
|
+
inputs.push(
|
|
37
|
+
html`<label for=${id}>${label}</label>
|
|
38
|
+
<div>
|
|
39
|
+
<input
|
|
40
|
+
id=${id}
|
|
41
|
+
type="range"
|
|
42
|
+
min=${bind.min ?? 0}
|
|
43
|
+
max=${bind.max ?? 100}
|
|
44
|
+
step=${bind.step ??
|
|
45
|
+
tickStep(bind.min, bind.max, 100)}
|
|
46
|
+
.value=${value}
|
|
47
|
+
@input=${(/** @type {any} */ e) => {
|
|
48
|
+
debouncedSetter(e.target.valueAsNumber);
|
|
49
|
+
e.target.nextElementSibling.textContent =
|
|
50
|
+
e.target.valueAsNumber;
|
|
51
|
+
}}
|
|
52
|
+
/><span>${value}</span>
|
|
53
|
+
</div>`
|
|
54
|
+
);
|
|
55
|
+
} else if (bind.input == "checkbox") {
|
|
56
|
+
inputs.push(
|
|
57
|
+
html`<label for=${id}>${label}</label>
|
|
58
|
+
<input
|
|
59
|
+
id=${id}
|
|
60
|
+
type="checkbox"
|
|
61
|
+
?checked=${value}
|
|
62
|
+
@input=${(/** @type {any} */ e) =>
|
|
63
|
+
debouncedSetter(e.target.checked)}
|
|
64
|
+
/>`
|
|
65
|
+
);
|
|
66
|
+
} else if (bind.input == "radio") {
|
|
67
|
+
inputs.push(
|
|
68
|
+
html`<span class="label">${label}</span>
|
|
69
|
+
<div class="radio-group">
|
|
70
|
+
${bind.options.map(
|
|
71
|
+
(option, i) => html`<label>
|
|
72
|
+
<input
|
|
73
|
+
type="radio"
|
|
74
|
+
name=${name}
|
|
75
|
+
value=${option}
|
|
76
|
+
.checked=${value == option}
|
|
77
|
+
@input=${(/** @type {any} */ e) =>
|
|
78
|
+
debouncedSetter(e.target.value)}
|
|
79
|
+
/>${bind.labels?.[i] ?? option}</label
|
|
80
|
+
>`
|
|
81
|
+
)}
|
|
82
|
+
</div>`
|
|
83
|
+
);
|
|
84
|
+
} else if (bind.input == "select") {
|
|
85
|
+
inputs.push(
|
|
86
|
+
html`<label for=${id}>${label}</label>
|
|
87
|
+
<select
|
|
88
|
+
id=${id}
|
|
89
|
+
@input=${(/** @type {any} */ e) =>
|
|
90
|
+
debouncedSetter(e.target.value)}
|
|
91
|
+
>
|
|
92
|
+
${bind.options.map(
|
|
93
|
+
(option, i) => html`<option
|
|
94
|
+
value=${option}
|
|
95
|
+
?selected=${value == option}
|
|
96
|
+
>
|
|
97
|
+
${bind.labels?.[i] ?? option}
|
|
98
|
+
</option>`
|
|
99
|
+
)}
|
|
100
|
+
</select> `
|
|
101
|
+
);
|
|
102
|
+
} else {
|
|
103
|
+
// TODO: Support other types: "text", "number", "color".
|
|
104
|
+
throw new Error("Unsupported input type: " + bind.input);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (bind.description) {
|
|
108
|
+
inputs.push(
|
|
109
|
+
html`<div class="description">${bind.description}</div>`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return inputs;
|
|
115
|
+
}
|