@vitessce/scatterplot-embedding 4.0.7 → 4.0.9
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/{deflate-aaOFaah9.js → deflate-CHWmGKzs.js} +1 -1
- package/dist/{index-QPcBcBv4.js → index-DoXbfOn2.js} +1551 -107
- package/dist/index.js +1 -1
- package/dist/{jpeg-0GPV7wHB.js → jpeg-DfpY4ESw.js} +1 -1
- package/dist/{lerc-b0eKtxKR.js → lerc-zU6xDjk2.js} +1 -1
- package/dist/{lzw-BdtUMX-Z.js → lzw-qjsUiTV8.js} +1 -1
- package/dist/{packbits-XKIpoMsP.js → packbits-DpcvKlj_.js} +1 -1
- package/dist/{raw-gRNpvpQg.js → raw-DWdrKuNt.js} +1 -1
- package/dist/{webimage-CbAzpg9y.js → webimage-DP9dgaA0.js} +1 -1
- package/dist-tsc/EmbeddingScatterplotSubscriber.d.ts +2 -4
- package/dist-tsc/EmbeddingScatterplotSubscriber.d.ts.map +1 -1
- package/dist-tsc/EmbeddingScatterplotSubscriber.js +29 -9
- package/dist-tsc/EmbeddingScatterplotSubscriber.js.map +1 -1
- package/package.json +8 -8
- package/src/EmbeddingScatterplotSubscriber.js +56 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import React__default, { useLayoutEffect, useEffect, cloneElement, createElement, forwardRef, useState, useRef, useMemo, useImperativeHandle, useContext, createContext, isValidElement, Children, PureComponent, useCallback, useDeferredValue } from "react";
|
|
3
|
-
import { usePlotOptionsStyles, OptionsContainer, CellColorEncodingOption, OptionSelect, useVitessceContainer, useComponentHover, useComponentViewInfo, useLoaders,
|
|
3
|
+
import { usePlotOptionsStyles, OptionsContainer, CellColorEncodingOption, OptionSelect, useVitessceContainer, useComponentHover, useComponentViewInfo, useLoaders, useViewMapping, useSetComponentHover, useSetComponentViewInfo, useAnnotationFrameCoordination, useCoordination, useInitialCoordination, useDeckCanvasSize, useAnnotationStoryData, useMultiObsLabels, useObsEmbeddingData, useObsSetsData, useFeatureSelection, useObsFeatureMatrixIndices, useFeatureLabelsData, useExpandedFeatureLabelsMap, useSampleSetsData, useSampleEdgesData, useReady, useUrls, useGetObsInfo, useUint8FeatureSelection, useExpressionValueGetter, TitleInfo, useCoordinationScopes } from "@vitessce/vit-s";
|
|
4
4
|
import { jsxs, jsx as jsx$1, Fragment } from "react/jsx-runtime";
|
|
5
5
|
import * as ReactDOM from "react-dom";
|
|
6
6
|
function _mergeNamespaces(n2, m2) {
|
|
@@ -2214,11 +2214,11 @@ function requireConcaveman() {
|
|
|
2214
2214
|
while (node2) {
|
|
2215
2215
|
for (var i2 = 0; i2 < node2.children.length; i2++) {
|
|
2216
2216
|
var child = node2.children[i2];
|
|
2217
|
-
var
|
|
2218
|
-
if (
|
|
2217
|
+
var dist2 = node2.leaf ? sqSegDist(child, b, c2) : sqSegBoxDist(b, c2, child);
|
|
2218
|
+
if (dist2 > maxDist) continue;
|
|
2219
2219
|
queue.push({
|
|
2220
2220
|
node: child,
|
|
2221
|
-
dist
|
|
2221
|
+
dist: dist2
|
|
2222
2222
|
});
|
|
2223
2223
|
}
|
|
2224
2224
|
while (queue.length && !queue.peek().node.children) {
|
|
@@ -7096,7 +7096,7 @@ const latestFileDefSchema = z.object({
|
|
|
7096
7096
|
options: fileOptionsSchema.optional(),
|
|
7097
7097
|
requestInit: requestInit.optional(),
|
|
7098
7098
|
// New: file def can have coordinationValues.
|
|
7099
|
-
coordinationValues: z.record(z.
|
|
7099
|
+
coordinationValues: z.record(z.any()).optional()
|
|
7100
7100
|
});
|
|
7101
7101
|
const datasetsSchema1_0_13 = z.array(z.object({
|
|
7102
7102
|
uid: z.string(),
|
|
@@ -7127,7 +7127,8 @@ const configSchema1_0_16 = configSchema1_0_13.extend({
|
|
|
7127
7127
|
h: z.number().int().optional(),
|
|
7128
7128
|
// Updates coordinationScopes and coordinationScopesBy
|
|
7129
7129
|
coordinationScopes: componentCoordinationScopes.optional(),
|
|
7130
|
-
coordinationScopesBy: componentCoordinationScopesBy.optional()
|
|
7130
|
+
coordinationScopesBy: componentCoordinationScopesBy.optional(),
|
|
7131
|
+
coordinationValues: z.record(z.any()).optional()
|
|
7131
7132
|
}))
|
|
7132
7133
|
});
|
|
7133
7134
|
const configSchema1_0_17 = configSchema1_0_16.extend({
|
|
@@ -9633,7 +9634,9 @@ const ViewType$1 = {
|
|
|
9633
9634
|
DUAL_SCATTERPLOT: "dualScatterplot",
|
|
9634
9635
|
TREEMAP: "treemap",
|
|
9635
9636
|
SAMPLE_SET_PAIR_MANAGER: "sampleSetPairManager",
|
|
9636
|
-
FEATURE_STATS_TABLE: "featureStatsTable"
|
|
9637
|
+
FEATURE_STATS_TABLE: "featureStatsTable",
|
|
9638
|
+
SINGLE_OBS_SET_SELECTOR: "singleObsSetSelector",
|
|
9639
|
+
ANNOTATION_CONTROLLER: "annotationController"
|
|
9637
9640
|
};
|
|
9638
9641
|
const DataType$2 = {
|
|
9639
9642
|
OBS_LABELS: "obsLabels",
|
|
@@ -9654,7 +9657,8 @@ const DataType$2 = {
|
|
|
9654
9657
|
COMPARISON_METADATA: "comparisonMetadata",
|
|
9655
9658
|
FEATURE_STATS: "featureStats",
|
|
9656
9659
|
FEATURE_SET_STATS: "featureSetStats",
|
|
9657
|
-
OBS_SET_STATS: "obsSetStats"
|
|
9660
|
+
OBS_SET_STATS: "obsSetStats",
|
|
9661
|
+
ANNOTATION_STORY: "annotationStory"
|
|
9658
9662
|
};
|
|
9659
9663
|
const FileType$1 = {
|
|
9660
9664
|
// Joint file types
|
|
@@ -9676,6 +9680,7 @@ const FileType$1 = {
|
|
|
9676
9680
|
OBS_SETS_CSV: "obsSets.csv",
|
|
9677
9681
|
OBS_SETS_JSON: "obsSets.json",
|
|
9678
9682
|
SAMPLE_SETS_CSV: "sampleSets.csv",
|
|
9683
|
+
ANNOTATION_STORY_JSON: "annotationStory.json",
|
|
9679
9684
|
// OME-Zarr
|
|
9680
9685
|
IMAGE_OME_ZARR: "image.ome-zarr",
|
|
9681
9686
|
OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
|
|
@@ -9960,7 +9965,15 @@ const CoordinationType$1 = {
|
|
|
9960
9965
|
FEATURE_POINT_FOLD_CHANGE_THRESHOLD: "featurePointFoldChangeThreshold",
|
|
9961
9966
|
FEATURE_LABEL_FOLD_CHANGE_THRESHOLD: "featureLabelFoldChangeThreshold",
|
|
9962
9967
|
// Treemap
|
|
9963
|
-
HIERARCHY_LEVELS: "hierarchyLevels"
|
|
9968
|
+
HIERARCHY_LEVELS: "hierarchyLevels",
|
|
9969
|
+
// Annotation frames
|
|
9970
|
+
ANNOTATION_STORY: "annotationStory",
|
|
9971
|
+
ANNOTATION_FRAME_INDEX: "annotationFrameIndex",
|
|
9972
|
+
ANNOTATION_SHAPES: "annotationShapes",
|
|
9973
|
+
ANNOTATION_OVERLAY_VISIBLE: "annotationOverlayVisible",
|
|
9974
|
+
ANNOTATION_TRANSITION_DURATION: "annotationTransitionDuration",
|
|
9975
|
+
ANNOTATION_SEMANTIC_ZOOM: "annotationSemanticZoom",
|
|
9976
|
+
ANNOTATION_EDITABLE: "annotationEditable"
|
|
9964
9977
|
};
|
|
9965
9978
|
const ViewHelpMapping = {
|
|
9966
9979
|
SCATTERPLOT: "The scatterplot displays two-dimensional (pre-computed) dimensionality reduction results (such as from t-SNE or UMAP). Each point on the scatterplot represents an observation (e.g., cell)."
|
|
@@ -9979,6 +9992,7 @@ const ViewHelpMapping = {
|
|
|
9979
9992
|
[FileType$1.OBS_SEGMENTATIONS_JSON]: DataType$2.OBS_SEGMENTATIONS,
|
|
9980
9993
|
[FileType$1.OBS_SETS_CSV]: DataType$2.OBS_SETS,
|
|
9981
9994
|
[FileType$1.OBS_SETS_JSON]: DataType$2.OBS_SETS,
|
|
9995
|
+
[FileType$1.ANNOTATION_STORY_JSON]: DataType$2.ANNOTATION_STORY,
|
|
9982
9996
|
[FileType$1.IMAGE_OME_ZARR]: DataType$2.IMAGE,
|
|
9983
9997
|
[FileType$1.OBS_SEGMENTATIONS_OME_ZARR]: DataType$2.OBS_SEGMENTATIONS,
|
|
9984
9998
|
[FileType$1.OBS_FEATURE_MATRIX_ANNDATA_ZARR]: DataType$2.OBS_FEATURE_MATRIX,
|
|
@@ -10101,7 +10115,8 @@ const ViewHelpMapping = {
|
|
|
10101
10115
|
[DataType$2.OBS_SET_STATS]: [
|
|
10102
10116
|
CoordinationType$1.OBS_TYPE
|
|
10103
10117
|
// TODO: should sampleType, obsSetSelection, and/or sampleSetSelection be used here?
|
|
10104
|
-
]
|
|
10118
|
+
],
|
|
10119
|
+
[DataType$2.ANNOTATION_STORY]: []
|
|
10105
10120
|
});
|
|
10106
10121
|
({
|
|
10107
10122
|
// For AnnData:
|
|
@@ -10234,7 +10249,9 @@ const ViewHelpMapping = {
|
|
|
10234
10249
|
CoordinationType$1.SPATIAL_TARGET_Z,
|
|
10235
10250
|
CoordinationType$1.SPATIAL_AXIS_FIXED,
|
|
10236
10251
|
CoordinationType$1.SPATIAL_ORBIT_AXIS,
|
|
10237
|
-
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY
|
|
10252
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
10253
|
+
// Annotation shapes are specific to a view's coordinate system.
|
|
10254
|
+
CoordinationType$1.ANNOTATION_SHAPES
|
|
10238
10255
|
];
|
|
10239
10256
|
const COMPONENT_COORDINATION_TYPES = {
|
|
10240
10257
|
[ViewType$1.NEUROGLANCER]: [
|
|
@@ -10326,7 +10343,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10326
10343
|
CoordinationType$1.EMBEDDING_CONTOURS_FILLED,
|
|
10327
10344
|
CoordinationType$1.EMBEDDING_CONTOUR_PERCENTILES,
|
|
10328
10345
|
CoordinationType$1.CONTOUR_COLOR_ENCODING,
|
|
10329
|
-
CoordinationType$1.CONTOUR_COLOR
|
|
10346
|
+
CoordinationType$1.CONTOUR_COLOR,
|
|
10347
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10348
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10349
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10350
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10351
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10352
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10353
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10330
10354
|
],
|
|
10331
10355
|
[ViewType$1.DUAL_SCATTERPLOT]: [
|
|
10332
10356
|
CoordinationType$1.DATASET,
|
|
@@ -10442,7 +10466,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10442
10466
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
10443
10467
|
CoordinationType$1.MOLECULE_HIGHLIGHT,
|
|
10444
10468
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
10445
|
-
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
10469
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
|
|
10470
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10471
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10472
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10473
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10474
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10475
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10476
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10446
10477
|
],
|
|
10447
10478
|
[ViewType$1.SPATIAL_BETA]: [
|
|
10448
10479
|
CoordinationType$1.META_COORDINATION_SCOPES,
|
|
@@ -10520,7 +10551,27 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10520
10551
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
10521
10552
|
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
10522
10553
|
CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER,
|
|
10523
|
-
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
10554
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
|
|
10555
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10556
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10557
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10558
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10559
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10560
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10561
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10562
|
+
],
|
|
10563
|
+
[ViewType$1.ANNOTATION_CONTROLLER]: [
|
|
10564
|
+
CoordinationType$1.DATASET,
|
|
10565
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10566
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10567
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10568
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10569
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10570
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10571
|
+
// Note: the annotation controller also needs to read the coordination state
|
|
10572
|
+
// of all other views/coordination types via the full config.
|
|
10573
|
+
// Note: we get/set the CoordinationType.ANNOTATION_SHAPES from the full config,
|
|
10574
|
+
// as this info is view-specific rather than global to the story.
|
|
10524
10575
|
],
|
|
10525
10576
|
[ViewType$1.HEATMAP]: [
|
|
10526
10577
|
CoordinationType$1.DATASET,
|
|
@@ -10830,6 +10881,11 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10830
10881
|
CoordinationType$1.FEATURE_POINT_FOLD_CHANGE_THRESHOLD,
|
|
10831
10882
|
CoordinationType$1.FEATURE_LABEL_FOLD_CHANGE_THRESHOLD
|
|
10832
10883
|
],
|
|
10884
|
+
[ViewType$1.SINGLE_OBS_SET_SELECTOR]: [
|
|
10885
|
+
CoordinationType$1.OBS_TYPE,
|
|
10886
|
+
CoordinationType$1.OBS_SET_COLOR,
|
|
10887
|
+
CoordinationType$1.OBS_SET_SELECTION
|
|
10888
|
+
],
|
|
10833
10889
|
[ViewType$1.OBS_SET_COMPOSITION_BAR_PLOT]: [
|
|
10834
10890
|
CoordinationType$1.DATASET,
|
|
10835
10891
|
CoordinationType$1.OBS_TYPE,
|
|
@@ -11533,6 +11589,124 @@ z.object({
|
|
|
11533
11589
|
radius: z.number(),
|
|
11534
11590
|
opacity: z.number()
|
|
11535
11591
|
});
|
|
11592
|
+
const shapeBaseObj = z.object({
|
|
11593
|
+
uid: z.string(),
|
|
11594
|
+
text: z.string().optional(),
|
|
11595
|
+
strokeColor: z.array(z.number()).length(3).optional(),
|
|
11596
|
+
strokeWidth: z.number().optional(),
|
|
11597
|
+
// SVG-style dash pattern, e.g. "10 5" or "10 20 30 10". "none" or omitted = solid.
|
|
11598
|
+
strokeDashArray: z.string().optional(),
|
|
11599
|
+
visible: z.boolean().optional()
|
|
11600
|
+
// TODO: define unit modes for x and y axes
|
|
11601
|
+
// ("pixels" vs "normalized" vs "physical" etc.)
|
|
11602
|
+
// TODO: a coordinate system identifier (e.g., "DeckGL" for now,
|
|
11603
|
+
// but a coordinate system from OME-NGFF/SpatialData eventually?)
|
|
11604
|
+
});
|
|
11605
|
+
const rectangleShapeObj = shapeBaseObj.extend({
|
|
11606
|
+
type: z.literal("rectangle"),
|
|
11607
|
+
// OME-XML field names verbatim (upper-left origin)
|
|
11608
|
+
x: z.number(),
|
|
11609
|
+
y: z.number(),
|
|
11610
|
+
width: z.number(),
|
|
11611
|
+
height: z.number(),
|
|
11612
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11613
|
+
fillOpacity: z.number().optional()
|
|
11614
|
+
});
|
|
11615
|
+
const lineShapeObj = shapeBaseObj.extend({
|
|
11616
|
+
type: z.literal("line"),
|
|
11617
|
+
// OME-XML field names verbatim
|
|
11618
|
+
x1: z.number(),
|
|
11619
|
+
y1: z.number(),
|
|
11620
|
+
x2: z.number(),
|
|
11621
|
+
y2: z.number(),
|
|
11622
|
+
markerStart: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11623
|
+
markerEnd: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11624
|
+
textPosition: z.enum(["start", "middle", "end"]).optional(),
|
|
11625
|
+
textBufferPx: z.number().optional()
|
|
11626
|
+
});
|
|
11627
|
+
const ellipseShapeObj = shapeBaseObj.extend({
|
|
11628
|
+
type: z.literal("ellipse"),
|
|
11629
|
+
// OME-XML field names verbatim (centre point + radii)
|
|
11630
|
+
x1: z.number(),
|
|
11631
|
+
y1: z.number(),
|
|
11632
|
+
radiusX: z.number(),
|
|
11633
|
+
radiusY: z.number(),
|
|
11634
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11635
|
+
fillOpacity: z.number().optional()
|
|
11636
|
+
});
|
|
11637
|
+
const polygonShapeObj = shapeBaseObj.extend({
|
|
11638
|
+
type: z.literal("polygon"),
|
|
11639
|
+
// OME-XML: array of [x, y] coordinate pairs, closed automatically
|
|
11640
|
+
points: z.array(z.tuple([z.number(), z.number()])),
|
|
11641
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11642
|
+
fillOpacity: z.number().optional()
|
|
11643
|
+
});
|
|
11644
|
+
const polylineShapeObj = shapeBaseObj.extend({
|
|
11645
|
+
type: z.literal("polyline"),
|
|
11646
|
+
// OME-XML: array of [x, y] coordinate pairs, open (not closed)
|
|
11647
|
+
points: z.array(z.tuple([z.number(), z.number()])),
|
|
11648
|
+
markerStart: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11649
|
+
markerEnd: z.enum(["Arrow", "Tick"]).nullable().optional()
|
|
11650
|
+
});
|
|
11651
|
+
const annotationShapeObj = z.discriminatedUnion("type", [
|
|
11652
|
+
rectangleShapeObj,
|
|
11653
|
+
lineShapeObj,
|
|
11654
|
+
ellipseShapeObj,
|
|
11655
|
+
polygonShapeObj,
|
|
11656
|
+
polylineShapeObj
|
|
11657
|
+
]);
|
|
11658
|
+
z.array(annotationShapeObj);
|
|
11659
|
+
const annotationFrameObj = z.object({
|
|
11660
|
+
uid: z.string(),
|
|
11661
|
+
title: z.string().optional(),
|
|
11662
|
+
description: z.string().optional(),
|
|
11663
|
+
descriptionType: z.enum(["text", "markdown"]).optional(),
|
|
11664
|
+
// A frame can define per-view: coordinationValues
|
|
11665
|
+
// (if the view's state should not be coordinated with other views)
|
|
11666
|
+
// or per-view coordinationScopes/coordinationScopesBy
|
|
11667
|
+
// (if at this frame, the view should be coordinated with other views).
|
|
11668
|
+
// We can also define a frame-level coordination space,
|
|
11669
|
+
// which will be merged with the global coordination space.
|
|
11670
|
+
// TODO: datasets
|
|
11671
|
+
// TODO: coordinationSpace
|
|
11672
|
+
layout: z.array(
|
|
11673
|
+
// Note: for now, we will infer view objects which have a uid
|
|
11674
|
+
// that is present in the global layout, and do NOT have x/y/w/h defined,
|
|
11675
|
+
// to mean that in this frame, the layout and set of views is unchanged
|
|
11676
|
+
// from the global layout.
|
|
11677
|
+
// This will allow each frame to omit the full list of views from the layout,
|
|
11678
|
+
// and only specify the views whose coordination state is changing in this frame.
|
|
11679
|
+
// If a frame includes a view with a uid that is not present
|
|
11680
|
+
// in the global layout, then that view will be added to the layout at this frame.
|
|
11681
|
+
// This frame should also define x/y/w/h for all views,
|
|
11682
|
+
// since it will otherwise be ambiguous how to layout the updated set of views
|
|
11683
|
+
// for this frame.
|
|
11684
|
+
z.object({
|
|
11685
|
+
// The view UID. If this view uid is not present in the global layout,
|
|
11686
|
+
// it will be added to the layout at this frame,
|
|
11687
|
+
// and will need to have its coordination values initialized to their defaults
|
|
11688
|
+
// for any that were not fully specified.
|
|
11689
|
+
uid: z.string(),
|
|
11690
|
+
coordinationValues: z.record(
|
|
11691
|
+
z.string(),
|
|
11692
|
+
// The coordination type name, e.g. "embeddingType"
|
|
11693
|
+
z.any()
|
|
11694
|
+
).optional()
|
|
11695
|
+
// TODO: support coordinationScopes/coordinationScopesBy for per-view coordination
|
|
11696
|
+
// at this frame.
|
|
11697
|
+
// TODO: view x/y/w/h once we support view layout changes per-frame.
|
|
11698
|
+
})
|
|
11699
|
+
).optional()
|
|
11700
|
+
});
|
|
11701
|
+
z.object({
|
|
11702
|
+
// TODO: schema version for the story schema?
|
|
11703
|
+
// Same as current Vitessce schema version?
|
|
11704
|
+
uid: z.string(),
|
|
11705
|
+
title: z.string().optional(),
|
|
11706
|
+
description: z.string().optional(),
|
|
11707
|
+
descriptionType: z.enum(["text", "markdown"]).optional(),
|
|
11708
|
+
frames: z.array(annotationFrameObj)
|
|
11709
|
+
});
|
|
11536
11710
|
const SETS_DATATYPE_OBS = "obs";
|
|
11537
11711
|
const HIERARCHICAL_SCHEMAS = {
|
|
11538
11712
|
latestVersion: "0.1.3"
|
|
@@ -24586,8 +24760,8 @@ class Vector extends MathArray {
|
|
|
24586
24760
|
distanceSquared(mathArray) {
|
|
24587
24761
|
let length2 = 0;
|
|
24588
24762
|
for (let i2 = 0; i2 < this.ELEMENTS; ++i2) {
|
|
24589
|
-
const
|
|
24590
|
-
length2 +=
|
|
24763
|
+
const dist2 = this[i2] - mathArray[i2];
|
|
24764
|
+
length2 += dist2 * dist2;
|
|
24591
24765
|
}
|
|
24592
24766
|
return checkNumber(length2);
|
|
24593
24767
|
}
|
|
@@ -24908,6 +25082,12 @@ function multiply$3(out, a2, b) {
|
|
|
24908
25082
|
out[2] = a2[2] * b[2];
|
|
24909
25083
|
return out;
|
|
24910
25084
|
}
|
|
25085
|
+
function distance$3(a2, b) {
|
|
25086
|
+
var x = b[0] - a2[0];
|
|
25087
|
+
var y = b[1] - a2[1];
|
|
25088
|
+
var z2 = b[2] - a2[2];
|
|
25089
|
+
return Math.hypot(x, y, z2);
|
|
25090
|
+
}
|
|
24911
25091
|
function squaredLength$2(a2) {
|
|
24912
25092
|
var x = a2[0];
|
|
24913
25093
|
var y = a2[1];
|
|
@@ -25031,6 +25211,7 @@ function angle$2(a2, b) {
|
|
|
25031
25211
|
}
|
|
25032
25212
|
var sub = subtract;
|
|
25033
25213
|
var mul = multiply$3;
|
|
25214
|
+
var dist = distance$3;
|
|
25034
25215
|
var len = length$5;
|
|
25035
25216
|
var sqrLen = squaredLength$2;
|
|
25036
25217
|
(function() {
|
|
@@ -39501,7 +39682,7 @@ function noop$2() {
|
|
|
39501
39682
|
const getCursor$1 = ({
|
|
39502
39683
|
isDragging
|
|
39503
39684
|
}) => isDragging ? "grabbing" : "grab";
|
|
39504
|
-
const defaultProps$
|
|
39685
|
+
const defaultProps$P = {
|
|
39505
39686
|
id: "",
|
|
39506
39687
|
width: "100%",
|
|
39507
39688
|
height: "100%",
|
|
@@ -39632,7 +39813,7 @@ class Deck {
|
|
|
39632
39813
|
this._lastPointerDownInfo = pickedInfo.result[0] || pickedInfo.emptyInfo;
|
|
39633
39814
|
});
|
|
39634
39815
|
this.props = {
|
|
39635
|
-
...defaultProps$
|
|
39816
|
+
...defaultProps$P,
|
|
39636
39817
|
...props
|
|
39637
39818
|
};
|
|
39638
39819
|
props = this.props;
|
|
@@ -40134,7 +40315,7 @@ class Deck {
|
|
|
40134
40315
|
metrics.gpuMemory = memoryStats.get("GPU Memory").count;
|
|
40135
40316
|
}
|
|
40136
40317
|
}
|
|
40137
|
-
_defineProperty(Deck, "defaultProps", defaultProps$
|
|
40318
|
+
_defineProperty(Deck, "defaultProps", defaultProps$P);
|
|
40138
40319
|
_defineProperty(Deck, "VERSION", deckGlobal.VERSION);
|
|
40139
40320
|
class ShaderAttribute {
|
|
40140
40321
|
constructor(dataColumn, opts) {
|
|
@@ -42889,7 +43070,7 @@ const areViewportsEqual = memoize$3(({
|
|
|
42889
43070
|
return oldViewport.equals(viewport);
|
|
42890
43071
|
});
|
|
42891
43072
|
let pickingColorCache = new Uint8ClampedArray(0);
|
|
42892
|
-
const defaultProps$
|
|
43073
|
+
const defaultProps$O = {
|
|
42893
43074
|
data: {
|
|
42894
43075
|
type: "data",
|
|
42895
43076
|
value: EMPTY_ARRAY$1,
|
|
@@ -43764,7 +43945,7 @@ class Layer extends Component {
|
|
|
43764
43945
|
this.setNeedsUpdate();
|
|
43765
43946
|
}
|
|
43766
43947
|
}
|
|
43767
|
-
_defineProperty(Layer, "defaultProps", defaultProps$
|
|
43948
|
+
_defineProperty(Layer, "defaultProps", defaultProps$O);
|
|
43768
43949
|
_defineProperty(Layer, "layerName", "Layer");
|
|
43769
43950
|
const TRACE_RENDER_LAYERS = "compositeLayer.renderLayers";
|
|
43770
43951
|
class CompositeLayer extends Layer {
|
|
@@ -44800,6 +44981,124 @@ const esm$5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
44800
44981
|
project32,
|
|
44801
44982
|
shadow
|
|
44802
44983
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
44984
|
+
const dashShaders = {
|
|
44985
|
+
inject: {
|
|
44986
|
+
"vs:#decl": "\nattribute vec2 instanceDashArrays;\nattribute float instanceDashOffsets;\nvarying vec2 vDashArray;\nvarying float vDashOffset;\n",
|
|
44987
|
+
"vs:#main-end": "\nvDashArray = instanceDashArrays;\nvDashOffset = instanceDashOffsets / width.x;\n",
|
|
44988
|
+
"fs:#decl": "\nuniform float dashAlignMode;\nuniform float capType;\nuniform bool dashGapPickable;\nvarying vec2 vDashArray;\nvarying float vDashOffset;\n\nfloat round(float x) {\n return floor(x + 0.5);\n}\n",
|
|
44989
|
+
"fs:#main-start": "\n float solidLength = vDashArray.x;\n float gapLength = vDashArray.y;\n float unitLength = solidLength + gapLength;\n\n float offset;\n\n if (unitLength > 0.0) {\n if (dashAlignMode == 0.0) {\n offset = vDashOffset;\n } else {\n unitLength = vPathLength / round(vPathLength / unitLength);\n offset = solidLength / 2.0;\n }\n\n float unitOffset = mod(clamp(vPathPosition.y, 0.0, vPathLength) + offset, unitLength);\n\n if (gapLength > 0.0 && unitOffset > solidLength) {\n if (capType <= 0.5) {\n if (!(dashGapPickable && picking_uActive)) {\n discard;\n }\n } else {\n // caps are rounded, test the distance to solid ends\n float distToEnd = length(vec2(\n min(unitOffset - solidLength, unitLength - unitOffset),\n vPathPosition.x\n ));\n if (distToEnd > 1.0) {\n if (!(dashGapPickable && picking_uActive)) {\n discard;\n }\n }\n }\n }\n }\n"
|
|
44990
|
+
}
|
|
44991
|
+
};
|
|
44992
|
+
const offsetShaders = {
|
|
44993
|
+
inject: {
|
|
44994
|
+
"vs:#decl": "\nattribute float instanceOffsets;\n",
|
|
44995
|
+
"vs:DECKGL_FILTER_SIZE": "\n float offsetWidth = abs(instanceOffsets * 2.0) + 1.0;\n size *= offsetWidth;\n",
|
|
44996
|
+
"vCornerOffset = offsetVec;": "\n float offsetWidth = abs(instanceOffsets * 2.0) + 1.0;\n vec2 offsetCenter = -instanceOffsets * (isCap ? perp : miterVec * miterSize) * 2.0;\n vCornerOffset = vCornerOffset * offsetWidth - offsetCenter;\n",
|
|
44997
|
+
"fs:#main-start": "\n float isInside;\n isInside = step(-1.0, vPathPosition.x) * step(vPathPosition.x, 1.0);\n if (isInside == 0.0) {\n discard;\n }\n"
|
|
44998
|
+
}
|
|
44999
|
+
};
|
|
45000
|
+
const defaultProps$N = {
|
|
45001
|
+
getDashArray: {
|
|
45002
|
+
type: "accessor",
|
|
45003
|
+
value: [0, 0]
|
|
45004
|
+
},
|
|
45005
|
+
getOffset: {
|
|
45006
|
+
type: "accessor",
|
|
45007
|
+
value: 0
|
|
45008
|
+
},
|
|
45009
|
+
dashJustified: false,
|
|
45010
|
+
dashGapPickable: false
|
|
45011
|
+
};
|
|
45012
|
+
class PathStyleExtension extends LayerExtension {
|
|
45013
|
+
constructor({
|
|
45014
|
+
dash = false,
|
|
45015
|
+
offset: offset2 = false,
|
|
45016
|
+
highPrecisionDash = false
|
|
45017
|
+
} = {}) {
|
|
45018
|
+
super({
|
|
45019
|
+
dash: dash || highPrecisionDash,
|
|
45020
|
+
offset: offset2,
|
|
45021
|
+
highPrecisionDash
|
|
45022
|
+
});
|
|
45023
|
+
}
|
|
45024
|
+
isEnabled(layer) {
|
|
45025
|
+
return "pathTesselator" in layer.state;
|
|
45026
|
+
}
|
|
45027
|
+
getShaders(extension) {
|
|
45028
|
+
if (!extension.isEnabled(this)) {
|
|
45029
|
+
return null;
|
|
45030
|
+
}
|
|
45031
|
+
let result = {};
|
|
45032
|
+
if (extension.opts.dash) {
|
|
45033
|
+
result = mergeShaders(result, dashShaders);
|
|
45034
|
+
}
|
|
45035
|
+
if (extension.opts.offset) {
|
|
45036
|
+
result = mergeShaders(result, offsetShaders);
|
|
45037
|
+
}
|
|
45038
|
+
return result;
|
|
45039
|
+
}
|
|
45040
|
+
initializeState(context, extension) {
|
|
45041
|
+
const attributeManager = this.getAttributeManager();
|
|
45042
|
+
if (!attributeManager || !extension.isEnabled(this)) {
|
|
45043
|
+
return;
|
|
45044
|
+
}
|
|
45045
|
+
if (extension.opts.dash) {
|
|
45046
|
+
attributeManager.addInstanced({
|
|
45047
|
+
instanceDashArrays: {
|
|
45048
|
+
size: 2,
|
|
45049
|
+
accessor: "getDashArray"
|
|
45050
|
+
}
|
|
45051
|
+
});
|
|
45052
|
+
}
|
|
45053
|
+
if (extension.opts.highPrecisionDash) {
|
|
45054
|
+
attributeManager.addInstanced({
|
|
45055
|
+
instanceDashOffsets: {
|
|
45056
|
+
size: 1,
|
|
45057
|
+
accessor: "getPath",
|
|
45058
|
+
transform: extension.getDashOffsets.bind(this)
|
|
45059
|
+
}
|
|
45060
|
+
});
|
|
45061
|
+
}
|
|
45062
|
+
if (extension.opts.offset) {
|
|
45063
|
+
attributeManager.addInstanced({
|
|
45064
|
+
instanceOffsets: {
|
|
45065
|
+
size: 1,
|
|
45066
|
+
accessor: "getOffset"
|
|
45067
|
+
}
|
|
45068
|
+
});
|
|
45069
|
+
}
|
|
45070
|
+
}
|
|
45071
|
+
updateState(params, extension) {
|
|
45072
|
+
if (!extension.isEnabled(this)) {
|
|
45073
|
+
return;
|
|
45074
|
+
}
|
|
45075
|
+
const uniforms = {};
|
|
45076
|
+
if (extension.opts.dash) {
|
|
45077
|
+
uniforms.dashAlignMode = this.props.dashJustified ? 1 : 0;
|
|
45078
|
+
uniforms.dashGapPickable = Boolean(this.props.dashGapPickable);
|
|
45079
|
+
}
|
|
45080
|
+
this.state.model.setUniforms(uniforms);
|
|
45081
|
+
}
|
|
45082
|
+
getDashOffsets(path) {
|
|
45083
|
+
const result = [0];
|
|
45084
|
+
const positionSize = this.props.positionFormat === "XY" ? 2 : 3;
|
|
45085
|
+
const isNested2 = Array.isArray(path[0]);
|
|
45086
|
+
const geometrySize = isNested2 ? path.length : path.length / positionSize;
|
|
45087
|
+
let p;
|
|
45088
|
+
let prevP;
|
|
45089
|
+
for (let i2 = 0; i2 < geometrySize - 1; i2++) {
|
|
45090
|
+
p = isNested2 ? path[i2] : path.slice(i2 * positionSize, i2 * positionSize + positionSize);
|
|
45091
|
+
p = this.projectPosition(p);
|
|
45092
|
+
if (i2 > 0) {
|
|
45093
|
+
result[i2] = result[i2 - 1] + dist(prevP, p);
|
|
45094
|
+
}
|
|
45095
|
+
prevP = p;
|
|
45096
|
+
}
|
|
45097
|
+
return result;
|
|
45098
|
+
}
|
|
45099
|
+
}
|
|
45100
|
+
_defineProperty(PathStyleExtension, "defaultProps", defaultProps$N);
|
|
45101
|
+
_defineProperty(PathStyleExtension, "extensionName", "PathStyleExtension");
|
|
44803
45102
|
const defaultProps$M = {
|
|
44804
45103
|
clipBounds: [0, 0, 1, 1]
|
|
44805
45104
|
};
|
|
@@ -100847,8 +101146,8 @@ function requireJs$b() {
|
|
|
100847
101146
|
var DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi12 / 2 + Math.PI / 4));
|
|
100848
101147
|
var q = Math.abs(DeltaPsi) > 1e-11 ? DeltaPhi / DeltaPsi : Math.cos(phi12);
|
|
100849
101148
|
var delta = Math.sqrt(DeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda);
|
|
100850
|
-
var
|
|
100851
|
-
return
|
|
101149
|
+
var dist2 = delta * R;
|
|
101150
|
+
return dist2;
|
|
100852
101151
|
}
|
|
100853
101152
|
js$a.default = rhumbDistance;
|
|
100854
101153
|
return js$a;
|
|
@@ -101161,7 +101460,7 @@ function requireUtils$2() {
|
|
|
101161
101460
|
var x;
|
|
101162
101461
|
var y;
|
|
101163
101462
|
var segmentIdx;
|
|
101164
|
-
var
|
|
101463
|
+
var dist2;
|
|
101165
101464
|
if (coords.length > 1 && pointCoords.length) {
|
|
101166
101465
|
var lineCoordinates;
|
|
101167
101466
|
var pointCoordinate;
|
|
@@ -101178,17 +101477,17 @@ function requireUtils$2() {
|
|
|
101178
101477
|
if (lineCoordinates[n2][0] !== lineCoordinates[n2 - 1][0]) {
|
|
101179
101478
|
var slope = (lineCoordinates[n2][1] - lineCoordinates[n2 - 1][1]) / (lineCoordinates[n2][0] - lineCoordinates[n2 - 1][0]);
|
|
101180
101479
|
var inverseSlope = lineCoordinates[n2][1] - slope * lineCoordinates[n2][0];
|
|
101181
|
-
|
|
101182
|
-
} else
|
|
101480
|
+
dist2 = Math.abs(slope * pointCoordinate[0] + inverseSlope - pointCoordinate[1]) / Math.sqrt(slope * slope + 1);
|
|
101481
|
+
} else dist2 = Math.abs(pointCoordinate[0] - lineCoordinates[n2][0]);
|
|
101183
101482
|
var rl2 = Math.pow(lineCoordinates[n2][1] - lineCoordinates[n2 - 1][1], 2) + Math.pow(lineCoordinates[n2][0] - lineCoordinates[n2 - 1][0], 2);
|
|
101184
101483
|
var ln2 = Math.pow(lineCoordinates[n2][1] - pointCoordinate[1], 2) + Math.pow(lineCoordinates[n2][0] - pointCoordinate[0], 2);
|
|
101185
101484
|
var lnm12 = Math.pow(lineCoordinates[n2 - 1][1] - pointCoordinate[1], 2) + Math.pow(lineCoordinates[n2 - 1][0] - pointCoordinate[0], 2);
|
|
101186
|
-
var
|
|
101187
|
-
var calcrl2 = ln2 -
|
|
101485
|
+
var dist22 = Math.pow(dist2, 2);
|
|
101486
|
+
var calcrl2 = ln2 - dist22 + lnm12 - dist22;
|
|
101188
101487
|
if (calcrl2 > rl2) {
|
|
101189
|
-
|
|
101488
|
+
dist2 = Math.sqrt(Math.min(ln2, lnm12));
|
|
101190
101489
|
}
|
|
101191
|
-
if (minDist === null || minDist === void 0 || minDist >
|
|
101490
|
+
if (minDist === null || minDist === void 0 || minDist > dist2) {
|
|
101192
101491
|
if (calcrl2 > rl2) {
|
|
101193
101492
|
if (lnm12 < ln2) {
|
|
101194
101493
|
to = 0;
|
|
@@ -101198,10 +101497,10 @@ function requireUtils$2() {
|
|
|
101198
101497
|
to = 1;
|
|
101199
101498
|
}
|
|
101200
101499
|
} else {
|
|
101201
|
-
to = Math.sqrt(lnm12 -
|
|
101202
|
-
from2 = Math.sqrt(ln2 -
|
|
101500
|
+
to = Math.sqrt(lnm12 - dist22) / Math.sqrt(rl2);
|
|
101501
|
+
from2 = Math.sqrt(ln2 - dist22) / Math.sqrt(rl2);
|
|
101203
101502
|
}
|
|
101204
|
-
minDist =
|
|
101503
|
+
minDist = dist2;
|
|
101205
101504
|
segmentIdx = n2;
|
|
101206
101505
|
}
|
|
101207
101506
|
}
|
|
@@ -117532,22 +117831,22 @@ function addDecoder(cases, importFn) {
|
|
|
117532
117831
|
}
|
|
117533
117832
|
cases.forEach((c2) => registry$1.set(c2, importFn));
|
|
117534
117833
|
}
|
|
117535
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
117536
|
-
addDecoder(5, () => import("./lzw-
|
|
117834
|
+
addDecoder([void 0, 1], () => import("./raw-DWdrKuNt.js").then((m2) => m2.default));
|
|
117835
|
+
addDecoder(5, () => import("./lzw-qjsUiTV8.js").then((m2) => m2.default));
|
|
117537
117836
|
addDecoder(6, () => {
|
|
117538
117837
|
throw new Error("old style JPEG compression is not supported.");
|
|
117539
117838
|
});
|
|
117540
|
-
addDecoder(7, () => import("./jpeg-
|
|
117541
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
117542
|
-
addDecoder(32773, () => import("./packbits-
|
|
117839
|
+
addDecoder(7, () => import("./jpeg-DfpY4ESw.js").then((m2) => m2.default));
|
|
117840
|
+
addDecoder([8, 32946], () => import("./deflate-CHWmGKzs.js").then((m2) => m2.default));
|
|
117841
|
+
addDecoder(32773, () => import("./packbits-DpcvKlj_.js").then((m2) => m2.default));
|
|
117543
117842
|
addDecoder(
|
|
117544
117843
|
34887,
|
|
117545
|
-
() => import("./lerc-
|
|
117844
|
+
() => import("./lerc-zU6xDjk2.js").then(async (m2) => {
|
|
117546
117845
|
await m2.zstd.init();
|
|
117547
117846
|
return m2;
|
|
117548
117847
|
}).then((m2) => m2.default)
|
|
117549
117848
|
);
|
|
117550
|
-
addDecoder(50001, () => import("./webimage-
|
|
117849
|
+
addDecoder(50001, () => import("./webimage-DP9dgaA0.js").then((m2) => m2.default));
|
|
117551
117850
|
function decodeRowAcc(row, stride) {
|
|
117552
117851
|
let length2 = row.length - stride;
|
|
117553
117852
|
let offset2 = 0;
|
|
@@ -117962,8 +118261,8 @@ function TreeDesc(dyn_tree, stat_desc) {
|
|
|
117962
118261
|
this.max_code = 0;
|
|
117963
118262
|
this.stat_desc = stat_desc;
|
|
117964
118263
|
}
|
|
117965
|
-
const d_code = (
|
|
117966
|
-
return
|
|
118264
|
+
const d_code = (dist2) => {
|
|
118265
|
+
return dist2 < 256 ? _dist_code[dist2] : _dist_code[256 + (dist2 >>> 7)];
|
|
117967
118266
|
};
|
|
117968
118267
|
const put_short = (s2, w2) => {
|
|
117969
118268
|
s2.pending_buf[s2.pending++] = w2 & 255;
|
|
@@ -118097,7 +118396,7 @@ const tr_static_init = () => {
|
|
|
118097
118396
|
let bits;
|
|
118098
118397
|
let length2;
|
|
118099
118398
|
let code;
|
|
118100
|
-
let
|
|
118399
|
+
let dist2;
|
|
118101
118400
|
const bl_count = new Array(MAX_BITS + 1);
|
|
118102
118401
|
length2 = 0;
|
|
118103
118402
|
for (code = 0; code < LENGTH_CODES - 1; code++) {
|
|
@@ -118107,18 +118406,18 @@ const tr_static_init = () => {
|
|
|
118107
118406
|
}
|
|
118108
118407
|
}
|
|
118109
118408
|
_length_code[length2 - 1] = code;
|
|
118110
|
-
|
|
118409
|
+
dist2 = 0;
|
|
118111
118410
|
for (code = 0; code < 16; code++) {
|
|
118112
|
-
base_dist[code] =
|
|
118411
|
+
base_dist[code] = dist2;
|
|
118113
118412
|
for (n2 = 0; n2 < 1 << extra_dbits[code]; n2++) {
|
|
118114
|
-
_dist_code[
|
|
118413
|
+
_dist_code[dist2++] = code;
|
|
118115
118414
|
}
|
|
118116
118415
|
}
|
|
118117
|
-
|
|
118416
|
+
dist2 >>= 7;
|
|
118118
118417
|
for (; code < D_CODES; code++) {
|
|
118119
|
-
base_dist[code] =
|
|
118418
|
+
base_dist[code] = dist2 << 7;
|
|
118120
118419
|
for (n2 = 0; n2 < 1 << extra_dbits[code] - 7; n2++) {
|
|
118121
|
-
_dist_code[256 +
|
|
118420
|
+
_dist_code[256 + dist2++] = code;
|
|
118122
118421
|
}
|
|
118123
118422
|
}
|
|
118124
118423
|
for (bits = 0; bits <= MAX_BITS; bits++) {
|
|
@@ -118209,17 +118508,17 @@ const pqdownheap = (s2, tree, k) => {
|
|
|
118209
118508
|
s2.heap[k] = v;
|
|
118210
118509
|
};
|
|
118211
118510
|
const compress_block = (s2, ltree, dtree) => {
|
|
118212
|
-
let
|
|
118511
|
+
let dist2;
|
|
118213
118512
|
let lc;
|
|
118214
118513
|
let lx = 0;
|
|
118215
118514
|
let code;
|
|
118216
118515
|
let extra;
|
|
118217
118516
|
if (s2.last_lit !== 0) {
|
|
118218
118517
|
do {
|
|
118219
|
-
|
|
118518
|
+
dist2 = s2.pending_buf[s2.d_buf + lx * 2] << 8 | s2.pending_buf[s2.d_buf + lx * 2 + 1];
|
|
118220
118519
|
lc = s2.pending_buf[s2.l_buf + lx];
|
|
118221
118520
|
lx++;
|
|
118222
|
-
if (
|
|
118521
|
+
if (dist2 === 0) {
|
|
118223
118522
|
send_code(s2, lc, ltree);
|
|
118224
118523
|
} else {
|
|
118225
118524
|
code = _length_code[lc];
|
|
@@ -118229,13 +118528,13 @@ const compress_block = (s2, ltree, dtree) => {
|
|
|
118229
118528
|
lc -= base_length[code];
|
|
118230
118529
|
send_bits(s2, lc, extra);
|
|
118231
118530
|
}
|
|
118232
|
-
|
|
118233
|
-
code = d_code(
|
|
118531
|
+
dist2--;
|
|
118532
|
+
code = d_code(dist2);
|
|
118234
118533
|
send_code(s2, code, dtree);
|
|
118235
118534
|
extra = extra_dbits[code];
|
|
118236
118535
|
if (extra !== 0) {
|
|
118237
|
-
|
|
118238
|
-
send_bits(s2,
|
|
118536
|
+
dist2 -= base_dist[code];
|
|
118537
|
+
send_bits(s2, dist2, extra);
|
|
118239
118538
|
}
|
|
118240
118539
|
}
|
|
118241
118540
|
} while (lx < s2.last_lit);
|
|
@@ -118506,18 +118805,18 @@ const _tr_flush_block = (s2, buf, stored_len, last) => {
|
|
|
118506
118805
|
bi_windup(s2);
|
|
118507
118806
|
}
|
|
118508
118807
|
};
|
|
118509
|
-
const _tr_tally = (s2,
|
|
118510
|
-
s2.pending_buf[s2.d_buf + s2.last_lit * 2] =
|
|
118511
|
-
s2.pending_buf[s2.d_buf + s2.last_lit * 2 + 1] =
|
|
118808
|
+
const _tr_tally = (s2, dist2, lc) => {
|
|
118809
|
+
s2.pending_buf[s2.d_buf + s2.last_lit * 2] = dist2 >>> 8 & 255;
|
|
118810
|
+
s2.pending_buf[s2.d_buf + s2.last_lit * 2 + 1] = dist2 & 255;
|
|
118512
118811
|
s2.pending_buf[s2.l_buf + s2.last_lit] = lc & 255;
|
|
118513
118812
|
s2.last_lit++;
|
|
118514
|
-
if (
|
|
118813
|
+
if (dist2 === 0) {
|
|
118515
118814
|
s2.dyn_ltree[lc * 2]++;
|
|
118516
118815
|
} else {
|
|
118517
118816
|
s2.matches++;
|
|
118518
|
-
|
|
118817
|
+
dist2--;
|
|
118519
118818
|
s2.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]++;
|
|
118520
|
-
s2.dyn_dtree[d_code(
|
|
118819
|
+
s2.dyn_dtree[d_code(dist2) * 2]++;
|
|
118521
118820
|
}
|
|
118522
118821
|
return s2.last_lit === s2.lit_bufsize - 1;
|
|
118523
118822
|
};
|
|
@@ -120022,7 +120321,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120022
120321
|
let here;
|
|
120023
120322
|
let op;
|
|
120024
120323
|
let len2;
|
|
120025
|
-
let
|
|
120324
|
+
let dist2;
|
|
120026
120325
|
let from2;
|
|
120027
120326
|
let from_source;
|
|
120028
120327
|
let input, output;
|
|
@@ -120088,7 +120387,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120088
120387
|
bits -= op;
|
|
120089
120388
|
op = here >>> 16 & 255;
|
|
120090
120389
|
if (op & 16) {
|
|
120091
|
-
|
|
120390
|
+
dist2 = here & 65535;
|
|
120092
120391
|
op &= 15;
|
|
120093
120392
|
if (bits < op) {
|
|
120094
120393
|
hold += input[_in++] << bits;
|
|
@@ -120098,8 +120397,8 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120098
120397
|
bits += 8;
|
|
120099
120398
|
}
|
|
120100
120399
|
}
|
|
120101
|
-
|
|
120102
|
-
if (
|
|
120400
|
+
dist2 += hold & (1 << op) - 1;
|
|
120401
|
+
if (dist2 > dmax) {
|
|
120103
120402
|
strm.msg = "invalid distance too far back";
|
|
120104
120403
|
state.mode = BAD;
|
|
120105
120404
|
break top;
|
|
@@ -120107,8 +120406,8 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120107
120406
|
hold >>>= op;
|
|
120108
120407
|
bits -= op;
|
|
120109
120408
|
op = _out - beg;
|
|
120110
|
-
if (
|
|
120111
|
-
op =
|
|
120409
|
+
if (dist2 > op) {
|
|
120410
|
+
op = dist2 - op;
|
|
120112
120411
|
if (op > whave) {
|
|
120113
120412
|
if (state.sane) {
|
|
120114
120413
|
strm.msg = "invalid distance too far back";
|
|
@@ -120125,7 +120424,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120125
120424
|
do {
|
|
120126
120425
|
output[_out++] = s_window[from2++];
|
|
120127
120426
|
} while (--op);
|
|
120128
|
-
from2 = _out -
|
|
120427
|
+
from2 = _out - dist2;
|
|
120129
120428
|
from_source = output;
|
|
120130
120429
|
}
|
|
120131
120430
|
} else if (wnext < op) {
|
|
@@ -120143,7 +120442,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120143
120442
|
do {
|
|
120144
120443
|
output[_out++] = s_window[from2++];
|
|
120145
120444
|
} while (--op);
|
|
120146
|
-
from2 = _out -
|
|
120445
|
+
from2 = _out - dist2;
|
|
120147
120446
|
from_source = output;
|
|
120148
120447
|
}
|
|
120149
120448
|
}
|
|
@@ -120154,7 +120453,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120154
120453
|
do {
|
|
120155
120454
|
output[_out++] = s_window[from2++];
|
|
120156
120455
|
} while (--op);
|
|
120157
|
-
from2 = _out -
|
|
120456
|
+
from2 = _out - dist2;
|
|
120158
120457
|
from_source = output;
|
|
120159
120458
|
}
|
|
120160
120459
|
}
|
|
@@ -120171,7 +120470,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
120171
120470
|
}
|
|
120172
120471
|
}
|
|
120173
120472
|
} else {
|
|
120174
|
-
from2 = _out -
|
|
120473
|
+
from2 = _out - dist2;
|
|
120175
120474
|
do {
|
|
120176
120475
|
output[_out++] = output[from2++];
|
|
120177
120476
|
output[_out++] = output[from2++];
|
|
@@ -120729,7 +121028,7 @@ const fixedtables = (state) => {
|
|
|
120729
121028
|
state.distbits = 5;
|
|
120730
121029
|
};
|
|
120731
121030
|
const updatewindow = (strm, src, end, copy2) => {
|
|
120732
|
-
let
|
|
121031
|
+
let dist2;
|
|
120733
121032
|
const state = strm.state;
|
|
120734
121033
|
if (state.window === null) {
|
|
120735
121034
|
state.wsize = 1 << state.wbits;
|
|
@@ -120742,23 +121041,23 @@ const updatewindow = (strm, src, end, copy2) => {
|
|
|
120742
121041
|
state.wnext = 0;
|
|
120743
121042
|
state.whave = state.wsize;
|
|
120744
121043
|
} else {
|
|
120745
|
-
|
|
120746
|
-
if (
|
|
120747
|
-
|
|
121044
|
+
dist2 = state.wsize - state.wnext;
|
|
121045
|
+
if (dist2 > copy2) {
|
|
121046
|
+
dist2 = copy2;
|
|
120748
121047
|
}
|
|
120749
|
-
state.window.set(src.subarray(end - copy2, end - copy2 +
|
|
120750
|
-
copy2 -=
|
|
121048
|
+
state.window.set(src.subarray(end - copy2, end - copy2 + dist2), state.wnext);
|
|
121049
|
+
copy2 -= dist2;
|
|
120751
121050
|
if (copy2) {
|
|
120752
121051
|
state.window.set(src.subarray(end - copy2, end), 0);
|
|
120753
121052
|
state.wnext = copy2;
|
|
120754
121053
|
state.whave = state.wsize;
|
|
120755
121054
|
} else {
|
|
120756
|
-
state.wnext +=
|
|
121055
|
+
state.wnext += dist2;
|
|
120757
121056
|
if (state.wnext === state.wsize) {
|
|
120758
121057
|
state.wnext = 0;
|
|
120759
121058
|
}
|
|
120760
121059
|
if (state.whave < state.wsize) {
|
|
120761
|
-
state.whave +=
|
|
121060
|
+
state.whave += dist2;
|
|
120762
121061
|
}
|
|
120763
121062
|
}
|
|
120764
121063
|
}
|
|
@@ -124637,14 +124936,14 @@ vec4 colormap(float intensity) {
|
|
|
124637
124936
|
}
|
|
124638
124937
|
};
|
|
124639
124938
|
}
|
|
124640
|
-
const defaultProps$4$
|
|
124939
|
+
const defaultProps$4$2 = {
|
|
124641
124940
|
colormap: { type: "string", value: "viridis", compare: true },
|
|
124642
124941
|
opacity: { type: "number", value: 1, compare: true },
|
|
124643
124942
|
useTransparentColor: { type: "boolean", value: false, compare: true }
|
|
124644
124943
|
};
|
|
124645
124944
|
const AdditiveColormapExtension = class extends LayerExtension {
|
|
124646
124945
|
getShaders() {
|
|
124647
|
-
const name2 = this?.props?.colormap || defaultProps$4$
|
|
124946
|
+
const name2 = this?.props?.colormap || defaultProps$4$2.colormap.value;
|
|
124648
124947
|
const apply_cmap = cmaps[name2];
|
|
124649
124948
|
if (!apply_cmap) {
|
|
124650
124949
|
throw Error(`No colormap named ${name2} found in registry`);
|
|
@@ -124663,8 +124962,8 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
124663
124962
|
}
|
|
124664
124963
|
draw() {
|
|
124665
124964
|
const {
|
|
124666
|
-
useTransparentColor = defaultProps$4$
|
|
124667
|
-
opacity = defaultProps$4$
|
|
124965
|
+
useTransparentColor = defaultProps$4$2.useTransparentColor.value,
|
|
124966
|
+
opacity = defaultProps$4$2.opacity.value
|
|
124668
124967
|
} = this.props;
|
|
124669
124968
|
const uniforms = {
|
|
124670
124969
|
opacity,
|
|
@@ -124674,7 +124973,7 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
124674
124973
|
}
|
|
124675
124974
|
};
|
|
124676
124975
|
AdditiveColormapExtension.extensionName = "AdditiveColormapExtension";
|
|
124677
|
-
AdditiveColormapExtension.defaultProps = defaultProps$4$
|
|
124976
|
+
AdditiveColormapExtension.defaultProps = defaultProps$4$2;
|
|
124678
124977
|
const fs$1$2 = `uniform vec3 transparentColor;
|
|
124679
124978
|
uniform bool useTransparentColor;
|
|
124680
124979
|
uniform float opacity;
|
|
@@ -125967,7 +126266,7 @@ const ImageLayer = class extends CompositeLayer {
|
|
|
125967
126266
|
};
|
|
125968
126267
|
ImageLayer.layerName = "ImageLayer";
|
|
125969
126268
|
ImageLayer.defaultProps = defaultProps$5;
|
|
125970
|
-
const defaultProps$4 = {
|
|
126269
|
+
const defaultProps$4$1 = {
|
|
125971
126270
|
pickable: { type: "boolean", value: true, compare: true },
|
|
125972
126271
|
onHover: { type: "function", value: null, compare: false },
|
|
125973
126272
|
contrastLimits: { type: "array", value: [], compare: true },
|
|
@@ -126079,7 +126378,7 @@ const MultiscaleImageLayer = class extends CompositeLayer {
|
|
|
126079
126378
|
}
|
|
126080
126379
|
};
|
|
126081
126380
|
MultiscaleImageLayer.layerName = "MultiscaleImageLayer";
|
|
126082
|
-
MultiscaleImageLayer.defaultProps = defaultProps$4;
|
|
126381
|
+
MultiscaleImageLayer.defaultProps = defaultProps$4$1;
|
|
126083
126382
|
const defaultProps$3$1 = {
|
|
126084
126383
|
pickable: { type: "boolean", value: true, compare: true },
|
|
126085
126384
|
loader: {
|
|
@@ -127155,7 +127454,7 @@ function padWithDefault$1(arr, defaultValue2, padWidth) {
|
|
|
127155
127454
|
}
|
|
127156
127455
|
return newArr;
|
|
127157
127456
|
}
|
|
127158
|
-
const defaultProps$
|
|
127457
|
+
const defaultProps$4 = {
|
|
127159
127458
|
hoveredCell: { type: "number", value: null, compare: true },
|
|
127160
127459
|
// We do not want to deep-compare cellColorData,
|
|
127161
127460
|
// as it is potentially a TypedArray with millions of elements.
|
|
@@ -127272,7 +127571,7 @@ let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
|
|
|
127272
127571
|
}
|
|
127273
127572
|
};
|
|
127274
127573
|
BitmaskLayer$1.layerName = "BitmaskLayer";
|
|
127275
|
-
BitmaskLayer$1.defaultProps = defaultProps$
|
|
127574
|
+
BitmaskLayer$1.defaultProps = defaultProps$4;
|
|
127276
127575
|
const vs = `
|
|
127277
127576
|
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
127278
127577
|
|
|
@@ -127614,7 +127913,7 @@ function isEqualShallow(prevArr, nextArr) {
|
|
|
127614
127913
|
}
|
|
127615
127914
|
return prevArr === nextArr;
|
|
127616
127915
|
}
|
|
127617
|
-
const defaultProps$
|
|
127916
|
+
const defaultProps$3 = {
|
|
127618
127917
|
channelStrokeWidths: { type: "array", value: null, compare: true },
|
|
127619
127918
|
channelsFilled: { type: "array", value: null, compare: true },
|
|
127620
127919
|
channelOpacities: { type: "array", value: null, compare: true },
|
|
@@ -127878,7 +128177,7 @@ class BitmaskLayer2 extends XRLayer {
|
|
|
127878
128177
|
}
|
|
127879
128178
|
}
|
|
127880
128179
|
BitmaskLayer2.layerName = "BitmaskLayer";
|
|
127881
|
-
BitmaskLayer2.defaultProps = defaultProps$
|
|
128180
|
+
BitmaskLayer2.defaultProps = defaultProps$3;
|
|
127882
128181
|
var isNumeric$1 = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, mathceil = Math.ceil, mathfloor = Math.floor, bignumberError = "[BigNumber Error] ", tooManyDigits = bignumberError + "Number primitive has more than 15 significant digits: ", BASE = 1e14, LOG_BASE = 14, MAX_SAFE_INTEGER = 9007199254740991, POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], SQRT_BASE = 1e7, MAX = 1e9;
|
|
127883
128182
|
function clone(configObject) {
|
|
127884
128183
|
var div, convertBase, parseNumeric, P = BigNumber2.prototype = { constructor: BigNumber2, toString: null, valueOf: null }, ONE = new BigNumber2(1), DECIMAL_PLACES = 20, ROUNDING_MODE = 4, TO_EXP_NEG = -7, TO_EXP_POS = 21, MIN_EXP = -1e7, MAX_EXP = 1e7, CRYPTO = false, MODULO_MODE = 1, POW_PRECISION = 0, FORMAT = {
|
|
@@ -130821,7 +131120,7 @@ function ringArea(coords) {
|
|
|
130821
131120
|
return total * FACTOR;
|
|
130822
131121
|
}
|
|
130823
131122
|
const DEFAULT_THRESHOLD = 1;
|
|
130824
|
-
const defaultProps$
|
|
131123
|
+
const defaultProps$2 = {
|
|
130825
131124
|
// for text
|
|
130826
131125
|
obsSetPath: { type: "object" },
|
|
130827
131126
|
sampleSetPath: { type: "object" },
|
|
@@ -130916,9 +131215,9 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
130916
131215
|
const circlePoint = point(circleCoord);
|
|
130917
131216
|
polygonVertices.forEach((polyCoord) => {
|
|
130918
131217
|
const polyPoint = point(polyCoord);
|
|
130919
|
-
const
|
|
130920
|
-
if (
|
|
130921
|
-
minDist =
|
|
131218
|
+
const dist2 = distance$1(circlePoint, polyPoint);
|
|
131219
|
+
if (dist2 < minDist) {
|
|
131220
|
+
minDist = dist2;
|
|
130922
131221
|
minCirclePoint = circleCoord;
|
|
130923
131222
|
minCirclePointI = circlePointI;
|
|
130924
131223
|
minPolygonPoint = polyCoord;
|
|
@@ -130995,7 +131294,1077 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
130995
131294
|
}
|
|
130996
131295
|
}
|
|
130997
131296
|
ContourLayerWithText.layerName = "ContourLayerWithText";
|
|
130998
|
-
ContourLayerWithText.defaultProps = defaultProps$
|
|
131297
|
+
ContourLayerWithText.defaultProps = defaultProps$2;
|
|
131298
|
+
const ARROW_SCREEN_PX = 14;
|
|
131299
|
+
const LABEL_FONT_FAMILY$1 = '"Roboto", "Helvetica", "Arial", sans-serif';
|
|
131300
|
+
const LABEL_FONT_WEIGHT = "bold";
|
|
131301
|
+
const LABEL_FONT_SIZE = 14;
|
|
131302
|
+
const RATIO_CLUSTER = 0.1;
|
|
131303
|
+
const RATIO_DOT = 0.3;
|
|
131304
|
+
const RATIO_GEO_FADE = 0.55;
|
|
131305
|
+
const RATIO_TIPS = 0.7;
|
|
131306
|
+
const RATIO_LABEL = 0.55;
|
|
131307
|
+
const RATIO_LABEL_FULL = 0.75;
|
|
131308
|
+
function textBgColor(strokeColor) {
|
|
131309
|
+
const [r2, g2, b] = strokeColor;
|
|
131310
|
+
const lum = (0.299 * r2 + 0.587 * g2 + 0.114 * b) / 255;
|
|
131311
|
+
return lum > 0.45 ? [20, 20, 20, 210] : [245, 245, 245, 210];
|
|
131312
|
+
}
|
|
131313
|
+
function parseDashArray(strokeDashArray) {
|
|
131314
|
+
if (!strokeDashArray || strokeDashArray === "none")
|
|
131315
|
+
return null;
|
|
131316
|
+
const nums = strokeDashArray.trim().split(/\s+/).map(Number).filter((n2) => !Number.isNaN(n2) && n2 >= 0);
|
|
131317
|
+
return nums.length >= 2 ? [nums[0], nums[1]] : null;
|
|
131318
|
+
}
|
|
131319
|
+
function computeEllipsePolygon(cx, cy, rx, ry, numSegments = 64) {
|
|
131320
|
+
const pts = [];
|
|
131321
|
+
for (let i2 = 0; i2 < numSegments; i2++) {
|
|
131322
|
+
const angle2 = 2 * Math.PI * i2 / numSegments;
|
|
131323
|
+
pts.push([cx + rx * Math.cos(angle2), cy + ry * Math.sin(angle2)]);
|
|
131324
|
+
}
|
|
131325
|
+
return pts;
|
|
131326
|
+
}
|
|
131327
|
+
function createPreviewLayer(inProgress, hoverCoord, strokeColor = [255, 255, 0]) {
|
|
131328
|
+
if (!inProgress || inProgress.vertices.length === 0)
|
|
131329
|
+
return null;
|
|
131330
|
+
const { type, vertices } = inProgress;
|
|
131331
|
+
const base = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN };
|
|
131332
|
+
const previewColor = [...strokeColor, 160];
|
|
131333
|
+
const cursor2 = hoverCoord ?? vertices[vertices.length - 1];
|
|
131334
|
+
if (type === "rectangle" && vertices.length === 1) {
|
|
131335
|
+
const [ax, ay] = vertices[0];
|
|
131336
|
+
const [bx, by] = cursor2;
|
|
131337
|
+
const path = [[ax, ay], [bx, ay], [bx, by], [ax, by], [ax, ay]];
|
|
131338
|
+
return new PathLayer({
|
|
131339
|
+
...base,
|
|
131340
|
+
id: "annotation-preview-rectangle",
|
|
131341
|
+
data: [{ path }],
|
|
131342
|
+
getPath: (d) => d.path,
|
|
131343
|
+
getColor: previewColor,
|
|
131344
|
+
getWidth: 1,
|
|
131345
|
+
widthUnits: "pixels",
|
|
131346
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131347
|
+
getDashArray: [8, 4]
|
|
131348
|
+
});
|
|
131349
|
+
}
|
|
131350
|
+
if (type === "line" && vertices.length === 1) {
|
|
131351
|
+
const path = [vertices[0], cursor2];
|
|
131352
|
+
return new PathLayer({
|
|
131353
|
+
...base,
|
|
131354
|
+
id: "annotation-preview-line",
|
|
131355
|
+
data: [{ path }],
|
|
131356
|
+
getPath: (d) => d.path,
|
|
131357
|
+
getColor: previewColor,
|
|
131358
|
+
getWidth: 1,
|
|
131359
|
+
widthUnits: "pixels",
|
|
131360
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131361
|
+
getDashArray: [8, 4]
|
|
131362
|
+
});
|
|
131363
|
+
}
|
|
131364
|
+
if (type === "ellipse" && vertices.length === 1) {
|
|
131365
|
+
const [cx, cy] = vertices[0];
|
|
131366
|
+
const [ex, ey] = cursor2;
|
|
131367
|
+
const rx = Math.abs(ex - cx);
|
|
131368
|
+
const ry = Math.abs(ey - cy);
|
|
131369
|
+
if (rx < 1 && ry < 1)
|
|
131370
|
+
return null;
|
|
131371
|
+
const pts = computeEllipsePolygon(cx, cy, Math.max(rx, 1), Math.max(ry, 1));
|
|
131372
|
+
const path = [...pts, pts[0]];
|
|
131373
|
+
return new PathLayer({
|
|
131374
|
+
...base,
|
|
131375
|
+
id: "annotation-preview-ellipse",
|
|
131376
|
+
data: [{ path }],
|
|
131377
|
+
getPath: (d) => d.path,
|
|
131378
|
+
getColor: previewColor,
|
|
131379
|
+
getWidth: 1,
|
|
131380
|
+
widthUnits: "pixels",
|
|
131381
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131382
|
+
getDashArray: [8, 4]
|
|
131383
|
+
});
|
|
131384
|
+
}
|
|
131385
|
+
if ((type === "polygon" || type === "polyline") && vertices.length >= 1) {
|
|
131386
|
+
const path = [...vertices, cursor2];
|
|
131387
|
+
if (type === "polygon" && vertices.length >= 2)
|
|
131388
|
+
path.push(vertices[0]);
|
|
131389
|
+
return new PathLayer({
|
|
131390
|
+
...base,
|
|
131391
|
+
id: `annotation-preview-${type}`,
|
|
131392
|
+
data: [{ path }],
|
|
131393
|
+
getPath: (d) => d.path,
|
|
131394
|
+
getColor: previewColor,
|
|
131395
|
+
getWidth: 1,
|
|
131396
|
+
widthUnits: "pixels",
|
|
131397
|
+
jointRounded: true,
|
|
131398
|
+
capRounded: true,
|
|
131399
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131400
|
+
getDashArray: [8, 4]
|
|
131401
|
+
});
|
|
131402
|
+
}
|
|
131403
|
+
return null;
|
|
131404
|
+
}
|
|
131405
|
+
function computeTickCap(tipX, tipY, dirX, dirY, dataSize) {
|
|
131406
|
+
const len2 = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
131407
|
+
if (len2 === 0)
|
|
131408
|
+
return null;
|
|
131409
|
+
const ux = dirX / len2;
|
|
131410
|
+
const uy = dirY / len2;
|
|
131411
|
+
const px = -uy;
|
|
131412
|
+
const py = ux;
|
|
131413
|
+
const half = dataSize * 0.55;
|
|
131414
|
+
return [
|
|
131415
|
+
[tipX + px * half, tipY + py * half],
|
|
131416
|
+
[tipX - px * half, tipY - py * half]
|
|
131417
|
+
];
|
|
131418
|
+
}
|
|
131419
|
+
function computeArrowhead(tipX, tipY, dirX, dirY, dataSize) {
|
|
131420
|
+
const len2 = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
131421
|
+
if (len2 === 0)
|
|
131422
|
+
return null;
|
|
131423
|
+
const ux = dirX / len2;
|
|
131424
|
+
const uy = dirY / len2;
|
|
131425
|
+
const px = -uy;
|
|
131426
|
+
const py = ux;
|
|
131427
|
+
const halfBase = dataSize * 0.4;
|
|
131428
|
+
const bx = tipX - ux * dataSize;
|
|
131429
|
+
const by = tipY - uy * dataSize;
|
|
131430
|
+
return [
|
|
131431
|
+
[tipX, tipY],
|
|
131432
|
+
[bx + px * halfBase, by + py * halfBase],
|
|
131433
|
+
[bx - px * halfBase, by - py * halfBase]
|
|
131434
|
+
];
|
|
131435
|
+
}
|
|
131436
|
+
function fmtCommas(n2) {
|
|
131437
|
+
return Math.round(n2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
131438
|
+
}
|
|
131439
|
+
function getMeasurementLabel(shape2, physicalPixelSize, viewType = ViewType$1.SPATIAL) {
|
|
131440
|
+
const pps = physicalPixelSize;
|
|
131441
|
+
const px = pps?.x ?? 1;
|
|
131442
|
+
const py = pps?.y ?? 1;
|
|
131443
|
+
const unit2 = pps ? pps.unit ?? "" : null;
|
|
131444
|
+
const hasPhys = !!pps;
|
|
131445
|
+
const isEmbedding = viewType === ViewType$1.SCATTERPLOT;
|
|
131446
|
+
const fmtDist = (d) => {
|
|
131447
|
+
if (hasPhys)
|
|
131448
|
+
return `${d.toFixed(2)} ${unit2}`;
|
|
131449
|
+
if (isEmbedding)
|
|
131450
|
+
return d.toFixed(2);
|
|
131451
|
+
return `${fmtCommas(d)} px`;
|
|
131452
|
+
};
|
|
131453
|
+
const fmtArea = (a2) => {
|
|
131454
|
+
if (hasPhys)
|
|
131455
|
+
return `${a2.toFixed(2)} ${unit2}²`;
|
|
131456
|
+
if (isEmbedding)
|
|
131457
|
+
return a2.toFixed(2);
|
|
131458
|
+
return `${fmtCommas(a2)} px²`;
|
|
131459
|
+
};
|
|
131460
|
+
if (shape2.type === "line") {
|
|
131461
|
+
const dx = (shape2.x2 ?? 0) - (shape2.x1 ?? 0);
|
|
131462
|
+
const dy = (shape2.y2 ?? 0) - (shape2.y1 ?? 0);
|
|
131463
|
+
const dist2 = hasPhys ? Math.sqrt((dx * px) ** 2 + (dy * py) ** 2) : Math.sqrt(dx * dx + dy * dy);
|
|
131464
|
+
return fmtDist(dist2);
|
|
131465
|
+
}
|
|
131466
|
+
if (shape2.type === "rectangle") {
|
|
131467
|
+
return fmtArea(hasPhys ? Math.abs(shape2.width ?? 0) * px * Math.abs(shape2.height ?? 0) * py : Math.abs((shape2.width ?? 0) * (shape2.height ?? 0)));
|
|
131468
|
+
}
|
|
131469
|
+
if (shape2.type === "ellipse") {
|
|
131470
|
+
const rx = Math.abs(shape2.radiusX ?? 0);
|
|
131471
|
+
const ry = Math.abs(shape2.radiusY ?? 0);
|
|
131472
|
+
return fmtArea(hasPhys ? Math.PI * rx * px * ry * py : Math.PI * rx * ry);
|
|
131473
|
+
}
|
|
131474
|
+
if (shape2.type === "polygon" && shape2.points?.length >= 3) {
|
|
131475
|
+
const pts = shape2.points;
|
|
131476
|
+
let shoelace = 0;
|
|
131477
|
+
for (let i2 = 0; i2 < pts.length; i2++) {
|
|
131478
|
+
const [ax, ay] = pts[i2];
|
|
131479
|
+
const [bx, by] = pts[(i2 + 1) % pts.length];
|
|
131480
|
+
shoelace += (hasPhys ? ax * px : ax) * (hasPhys ? by * py : by) - (hasPhys ? bx * px : bx) * (hasPhys ? ay * py : ay);
|
|
131481
|
+
}
|
|
131482
|
+
return fmtArea(Math.abs(shoelace / 2));
|
|
131483
|
+
}
|
|
131484
|
+
if (shape2.type === "polyline" && shape2.points?.length >= 2) {
|
|
131485
|
+
let total = 0;
|
|
131486
|
+
for (let i2 = 0; i2 < shape2.points.length - 1; i2++) {
|
|
131487
|
+
const [ax, ay] = shape2.points[i2];
|
|
131488
|
+
const [bx, by] = shape2.points[i2 + 1];
|
|
131489
|
+
total += hasPhys ? Math.sqrt(((bx - ax) * px) ** 2 + ((by - ay) * py) ** 2) : Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
|
|
131490
|
+
}
|
|
131491
|
+
return fmtDist(total);
|
|
131492
|
+
}
|
|
131493
|
+
return null;
|
|
131494
|
+
}
|
|
131495
|
+
function pickBelowPerp(ux, uy) {
|
|
131496
|
+
const rp = [uy, -ux];
|
|
131497
|
+
const lp = [-uy, ux];
|
|
131498
|
+
return rp[1] > lp[1] || rp[1] === lp[1] && rp[0] > lp[0] ? rp : lp;
|
|
131499
|
+
}
|
|
131500
|
+
function readableAngle(deg) {
|
|
131501
|
+
let a2 = deg;
|
|
131502
|
+
if (a2 > 90)
|
|
131503
|
+
a2 -= 180;
|
|
131504
|
+
if (a2 < -90)
|
|
131505
|
+
a2 += 180;
|
|
131506
|
+
return a2;
|
|
131507
|
+
}
|
|
131508
|
+
function getShapeCentroid(shape2) {
|
|
131509
|
+
if (shape2.type === "rectangle") {
|
|
131510
|
+
return [(shape2.x ?? 0) + (shape2.width ?? 0) / 2, (shape2.y ?? 0) + (shape2.height ?? 0) / 2];
|
|
131511
|
+
}
|
|
131512
|
+
if (shape2.type === "line") {
|
|
131513
|
+
return [((shape2.x1 ?? 0) + (shape2.x2 ?? 0)) / 2, ((shape2.y1 ?? 0) + (shape2.y2 ?? 0)) / 2];
|
|
131514
|
+
}
|
|
131515
|
+
if (shape2.type === "ellipse") {
|
|
131516
|
+
return [shape2.x1 ?? 0, shape2.y1 ?? 0];
|
|
131517
|
+
}
|
|
131518
|
+
if ((shape2.type === "polygon" || shape2.type === "polyline") && shape2.points?.length >= 1) {
|
|
131519
|
+
const mx = shape2.points.reduce((s2, p) => s2 + p[0], 0) / shape2.points.length;
|
|
131520
|
+
const my = shape2.points.reduce((s2, p) => s2 + p[1], 0) / shape2.points.length;
|
|
131521
|
+
return [mx, my];
|
|
131522
|
+
}
|
|
131523
|
+
return [0, 0];
|
|
131524
|
+
}
|
|
131525
|
+
function computeClusters(shapeList, zoom, cellPx = 50) {
|
|
131526
|
+
const cellSize = cellPx / 2 ** Math.floor(zoom);
|
|
131527
|
+
const cells = /* @__PURE__ */ new Map();
|
|
131528
|
+
shapeList.forEach(({ shape: shape2 }) => {
|
|
131529
|
+
const [cx, cy] = getShapeCentroid(shape2);
|
|
131530
|
+
const key = `${Math.floor(cx / cellSize)},${Math.floor(cy / cellSize)}`;
|
|
131531
|
+
if (!cells.has(key)) {
|
|
131532
|
+
cells.set(key, { sumX: 0, sumY: 0, count: 0, color: shape2.strokeColor ?? [255, 255, 255] });
|
|
131533
|
+
}
|
|
131534
|
+
const c2 = cells.get(key);
|
|
131535
|
+
c2.sumX += cx;
|
|
131536
|
+
c2.sumY += cy;
|
|
131537
|
+
c2.count++;
|
|
131538
|
+
});
|
|
131539
|
+
return Array.from(cells.values()).map((c2) => ({
|
|
131540
|
+
position: [c2.sumX / c2.count, c2.sumY / c2.count, 0],
|
|
131541
|
+
count: c2.count,
|
|
131542
|
+
color: c2.color
|
|
131543
|
+
}));
|
|
131544
|
+
}
|
|
131545
|
+
function createAnnotationLayers(shapes = [], zoom = 0, selectedShapeUid = null, physicalPixelSize = null, authoredZoom = null, semanticZoom = true, viewType = ViewType$1.SPATIAL) {
|
|
131546
|
+
const selectionLayers = [];
|
|
131547
|
+
if (selectedShapeUid) {
|
|
131548
|
+
const sel = shapes.find((s2) => s2.uid === selectedShapeUid);
|
|
131549
|
+
if (sel) {
|
|
131550
|
+
const { uid: sUid, type: sType, strokeWidth: sStrokeWidth = 3 } = sel;
|
|
131551
|
+
const haloColor = [255, 220, 50, 70];
|
|
131552
|
+
const haloWidth = Math.max(sStrokeWidth + 8, 10);
|
|
131553
|
+
const base = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN };
|
|
131554
|
+
if (sType === "rectangle") {
|
|
131555
|
+
const { x, y, width: width2, height: height2 } = sel;
|
|
131556
|
+
selectionLayers.push(new PathLayer({
|
|
131557
|
+
...base,
|
|
131558
|
+
id: `annotation-select-${sUid}`,
|
|
131559
|
+
data: [{
|
|
131560
|
+
path: [
|
|
131561
|
+
[x, y],
|
|
131562
|
+
[x + width2, y],
|
|
131563
|
+
[x + width2, y + height2],
|
|
131564
|
+
[x, y + height2],
|
|
131565
|
+
[x, y]
|
|
131566
|
+
]
|
|
131567
|
+
}],
|
|
131568
|
+
getPath: (d) => d.path,
|
|
131569
|
+
getColor: haloColor,
|
|
131570
|
+
getWidth: haloWidth,
|
|
131571
|
+
widthUnits: "pixels",
|
|
131572
|
+
jointRounded: true,
|
|
131573
|
+
capRounded: true
|
|
131574
|
+
}));
|
|
131575
|
+
}
|
|
131576
|
+
if (sType === "line") {
|
|
131577
|
+
const { x1: x12, y1: y12, x2, y2 } = sel;
|
|
131578
|
+
selectionLayers.push(new PathLayer({
|
|
131579
|
+
...base,
|
|
131580
|
+
id: `annotation-select-${sUid}`,
|
|
131581
|
+
data: [{ path: [[x12, y12], [x2, y2]] }],
|
|
131582
|
+
getPath: (d) => d.path,
|
|
131583
|
+
getColor: haloColor,
|
|
131584
|
+
getWidth: haloWidth,
|
|
131585
|
+
widthUnits: "pixels",
|
|
131586
|
+
capRounded: true
|
|
131587
|
+
}));
|
|
131588
|
+
}
|
|
131589
|
+
if (sType === "ellipse") {
|
|
131590
|
+
const polygon2 = computeEllipsePolygon(sel.x1, sel.y1, sel.radiusX, sel.radiusY);
|
|
131591
|
+
selectionLayers.push(new PathLayer({
|
|
131592
|
+
...base,
|
|
131593
|
+
id: `annotation-select-${sUid}`,
|
|
131594
|
+
data: [{ path: [...polygon2, polygon2[0]] }],
|
|
131595
|
+
getPath: (d) => d.path,
|
|
131596
|
+
getColor: haloColor,
|
|
131597
|
+
getWidth: haloWidth,
|
|
131598
|
+
widthUnits: "pixels",
|
|
131599
|
+
jointRounded: true
|
|
131600
|
+
}));
|
|
131601
|
+
}
|
|
131602
|
+
if (sType === "polygon" && sel.points?.length >= 3) {
|
|
131603
|
+
selectionLayers.push(new PathLayer({
|
|
131604
|
+
...base,
|
|
131605
|
+
id: `annotation-select-${sUid}`,
|
|
131606
|
+
data: [{ path: [...sel.points, sel.points[0]] }],
|
|
131607
|
+
getPath: (d) => d.path,
|
|
131608
|
+
getColor: haloColor,
|
|
131609
|
+
getWidth: haloWidth,
|
|
131610
|
+
widthUnits: "pixels",
|
|
131611
|
+
jointRounded: true
|
|
131612
|
+
}));
|
|
131613
|
+
}
|
|
131614
|
+
if (sType === "polyline" && sel.points?.length >= 2) {
|
|
131615
|
+
selectionLayers.push(new PathLayer({
|
|
131616
|
+
...base,
|
|
131617
|
+
id: `annotation-select-${sUid}`,
|
|
131618
|
+
data: [{ path: sel.points }],
|
|
131619
|
+
getPath: (d) => d.path,
|
|
131620
|
+
getColor: haloColor,
|
|
131621
|
+
getWidth: haloWidth,
|
|
131622
|
+
widthUnits: "pixels",
|
|
131623
|
+
jointRounded: true,
|
|
131624
|
+
capRounded: true
|
|
131625
|
+
}));
|
|
131626
|
+
}
|
|
131627
|
+
}
|
|
131628
|
+
}
|
|
131629
|
+
const layers = [];
|
|
131630
|
+
const dotShapes = [];
|
|
131631
|
+
const clusterDotShapes = [];
|
|
131632
|
+
shapes.forEach((shape2, i2) => {
|
|
131633
|
+
const { uid: uid2, type, strokeColor = [255, 255, 255], strokeWidth = 3, strokeDashArray } = shape2;
|
|
131634
|
+
const isSelected = uid2 === selectedShapeUid;
|
|
131635
|
+
let shapeOpacity = 1;
|
|
131636
|
+
let tipsOpacity = 1;
|
|
131637
|
+
let labelOpacity = 0;
|
|
131638
|
+
if (isSelected || !semanticZoom || authoredZoom === null) {
|
|
131639
|
+
tipsOpacity = 1;
|
|
131640
|
+
labelOpacity = 1;
|
|
131641
|
+
} else {
|
|
131642
|
+
const zoomRatio = 2 ** (zoom - authoredZoom);
|
|
131643
|
+
if (zoomRatio < RATIO_CLUSTER) {
|
|
131644
|
+
clusterDotShapes.push({ shape: shape2 });
|
|
131645
|
+
return;
|
|
131646
|
+
}
|
|
131647
|
+
if (zoomRatio < RATIO_DOT) {
|
|
131648
|
+
dotShapes.push({ shape: shape2, alpha: 200 });
|
|
131649
|
+
return;
|
|
131650
|
+
}
|
|
131651
|
+
if (zoomRatio < RATIO_GEO_FADE) {
|
|
131652
|
+
const t = (zoomRatio - RATIO_DOT) / (RATIO_GEO_FADE - RATIO_DOT);
|
|
131653
|
+
shapeOpacity = t;
|
|
131654
|
+
dotShapes.push({ shape: shape2, alpha: Math.round((1 - t) * 200) });
|
|
131655
|
+
}
|
|
131656
|
+
tipsOpacity = zoomRatio >= RATIO_TIPS ? shapeOpacity : Math.max(0, (zoomRatio - RATIO_GEO_FADE) / (RATIO_TIPS - RATIO_GEO_FADE) * shapeOpacity);
|
|
131657
|
+
if (zoomRatio >= RATIO_LABEL_FULL) {
|
|
131658
|
+
labelOpacity = shapeOpacity;
|
|
131659
|
+
} else if (zoomRatio >= RATIO_LABEL) {
|
|
131660
|
+
labelOpacity = (zoomRatio - RATIO_LABEL) / (RATIO_LABEL_FULL - RATIO_LABEL) * shapeOpacity;
|
|
131661
|
+
}
|
|
131662
|
+
}
|
|
131663
|
+
const arrowDataSize = Math.max(ARROW_SCREEN_PX, strokeWidth * 4) / 2 ** zoom;
|
|
131664
|
+
const base = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: shapeOpacity };
|
|
131665
|
+
const tipsBase = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: tipsOpacity };
|
|
131666
|
+
const labelBase = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: labelOpacity };
|
|
131667
|
+
const labelBgProps = shape2.labelBackground ? {
|
|
131668
|
+
background: true,
|
|
131669
|
+
getBackgroundColor: textBgColor(strokeColor),
|
|
131670
|
+
backgroundPadding: [3, 1, 3, 2]
|
|
131671
|
+
} : {};
|
|
131672
|
+
const labelProps = { ...labelBgProps };
|
|
131673
|
+
const dashArray = parseDashArray(strokeDashArray);
|
|
131674
|
+
const dashExt = [new PathStyleExtension({ dash: true })];
|
|
131675
|
+
const getDash = dashArray ?? [0, 0];
|
|
131676
|
+
if (type === "rectangle") {
|
|
131677
|
+
const { x, y, width: width2, height: height2, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
131678
|
+
const filled = fillOpacity > 0;
|
|
131679
|
+
const rectPolygon = [[x, y], [x + width2, y], [x + width2, y + height2], [x, y + height2]];
|
|
131680
|
+
layers.push(new PolygonLayer({
|
|
131681
|
+
...base,
|
|
131682
|
+
id: `annotation-rect-${uid2}-${i2}`,
|
|
131683
|
+
data: [{ polygon: rectPolygon }],
|
|
131684
|
+
getPolygon: (d) => d.polygon,
|
|
131685
|
+
filled,
|
|
131686
|
+
stroked: true,
|
|
131687
|
+
getFillColor: filled ? [...fillColor, Math.round(fillOpacity * 255)] : [0, 0, 0, 0],
|
|
131688
|
+
getLineColor: strokeColor,
|
|
131689
|
+
getLineWidth: strokeWidth,
|
|
131690
|
+
lineWidthUnits: "pixels",
|
|
131691
|
+
...dashArray ? {
|
|
131692
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131693
|
+
getDashArray: dashArray
|
|
131694
|
+
} : {}
|
|
131695
|
+
}));
|
|
131696
|
+
if (shape2.text && labelOpacity > 0) {
|
|
131697
|
+
layers.push(new TextLayer({
|
|
131698
|
+
...labelBase,
|
|
131699
|
+
...labelProps,
|
|
131700
|
+
id: `annotation-rect-text-${uid2}-${i2}`,
|
|
131701
|
+
data: [{ position: [x, y], text: shape2.text }],
|
|
131702
|
+
getPosition: (d) => d.position,
|
|
131703
|
+
getText: (d) => d.text,
|
|
131704
|
+
getColor: strokeColor,
|
|
131705
|
+
getSize: LABEL_FONT_SIZE,
|
|
131706
|
+
sizeUnits: "pixels",
|
|
131707
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131708
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131709
|
+
getPixelOffset: [3, -7],
|
|
131710
|
+
getTextAnchor: "start",
|
|
131711
|
+
getAlignmentBaseline: "bottom"
|
|
131712
|
+
}));
|
|
131713
|
+
}
|
|
131714
|
+
}
|
|
131715
|
+
if (type === "line") {
|
|
131716
|
+
const { x1: x12, y1: y12, x2, y2, markerStart, markerEnd } = shape2;
|
|
131717
|
+
const dx = x2 - x12;
|
|
131718
|
+
const dy = y2 - y12;
|
|
131719
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131720
|
+
const ux = len2 > 0 ? dx / len2 : 0;
|
|
131721
|
+
const uy = len2 > 0 ? dy / len2 : 0;
|
|
131722
|
+
const srcX = markerStart === "Arrow" ? x12 + ux * arrowDataSize : x12;
|
|
131723
|
+
const srcY = markerStart === "Arrow" ? y12 + uy * arrowDataSize : y12;
|
|
131724
|
+
const tgtX = markerEnd === "Arrow" ? x2 - ux * arrowDataSize : x2;
|
|
131725
|
+
const tgtY = markerEnd === "Arrow" ? y2 - uy * arrowDataSize : y2;
|
|
131726
|
+
layers.push(new PathLayer({
|
|
131727
|
+
...base,
|
|
131728
|
+
id: `annotation-line-${uid2}-${i2}`,
|
|
131729
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131730
|
+
getDashArray: dashArray ?? [0, 0],
|
|
131731
|
+
data: [{ path: [[srcX, srcY], [tgtX, tgtY]] }],
|
|
131732
|
+
getPath: (d) => d.path,
|
|
131733
|
+
getColor: strokeColor,
|
|
131734
|
+
getWidth: strokeWidth,
|
|
131735
|
+
widthUnits: "pixels",
|
|
131736
|
+
capRounded: true
|
|
131737
|
+
}));
|
|
131738
|
+
if (markerEnd === "Arrow" && tipsOpacity > 0) {
|
|
131739
|
+
const head = computeArrowhead(x2, y2, x2 - x12, y2 - y12, arrowDataSize);
|
|
131740
|
+
if (head) {
|
|
131741
|
+
layers.push(new PolygonLayer({
|
|
131742
|
+
...tipsBase,
|
|
131743
|
+
id: `annotation-end-arrow-${uid2}-${i2}`,
|
|
131744
|
+
data: [{ polygon: head }],
|
|
131745
|
+
getPolygon: (d) => d.polygon,
|
|
131746
|
+
filled: true,
|
|
131747
|
+
stroked: false,
|
|
131748
|
+
getFillColor: strokeColor
|
|
131749
|
+
}));
|
|
131750
|
+
}
|
|
131751
|
+
}
|
|
131752
|
+
if (markerStart === "Arrow" && tipsOpacity > 0) {
|
|
131753
|
+
const head = computeArrowhead(x12, y12, x12 - x2, y12 - y2, arrowDataSize);
|
|
131754
|
+
if (head) {
|
|
131755
|
+
layers.push(new PolygonLayer({
|
|
131756
|
+
...tipsBase,
|
|
131757
|
+
id: `annotation-start-arrow-${uid2}-${i2}`,
|
|
131758
|
+
data: [{ polygon: head }],
|
|
131759
|
+
getPolygon: (d) => d.polygon,
|
|
131760
|
+
filled: true,
|
|
131761
|
+
stroked: false,
|
|
131762
|
+
getFillColor: strokeColor
|
|
131763
|
+
}));
|
|
131764
|
+
}
|
|
131765
|
+
}
|
|
131766
|
+
if (markerEnd === "Tick" && tipsOpacity > 0) {
|
|
131767
|
+
const tick = computeTickCap(x2, y2, x2 - x12, y2 - y12, arrowDataSize);
|
|
131768
|
+
if (tick) {
|
|
131769
|
+
layers.push(new PathLayer({
|
|
131770
|
+
...tipsBase,
|
|
131771
|
+
id: `annotation-end-tick-${uid2}-${i2}`,
|
|
131772
|
+
data: [{ path: tick }],
|
|
131773
|
+
getPath: (d) => d.path,
|
|
131774
|
+
getColor: strokeColor,
|
|
131775
|
+
getWidth: strokeWidth,
|
|
131776
|
+
widthUnits: "pixels",
|
|
131777
|
+
capRounded: true
|
|
131778
|
+
}));
|
|
131779
|
+
}
|
|
131780
|
+
}
|
|
131781
|
+
if (markerStart === "Tick" && tipsOpacity > 0) {
|
|
131782
|
+
const tick = computeTickCap(x12, y12, x12 - x2, y12 - y2, arrowDataSize);
|
|
131783
|
+
if (tick) {
|
|
131784
|
+
layers.push(new PathLayer({
|
|
131785
|
+
...tipsBase,
|
|
131786
|
+
id: `annotation-start-tick-${uid2}-${i2}`,
|
|
131787
|
+
data: [{ path: tick }],
|
|
131788
|
+
getPath: (d) => d.path,
|
|
131789
|
+
getColor: strokeColor,
|
|
131790
|
+
getWidth: strokeWidth,
|
|
131791
|
+
widthUnits: "pixels",
|
|
131792
|
+
capRounded: true
|
|
131793
|
+
}));
|
|
131794
|
+
}
|
|
131795
|
+
}
|
|
131796
|
+
if (shape2.text) {
|
|
131797
|
+
const pos = shape2.textPosition ?? "start";
|
|
131798
|
+
let textX;
|
|
131799
|
+
let textY;
|
|
131800
|
+
if (pos === "start") {
|
|
131801
|
+
textX = x12;
|
|
131802
|
+
textY = y12;
|
|
131803
|
+
} else if (pos === "end") {
|
|
131804
|
+
textX = x2;
|
|
131805
|
+
textY = y2;
|
|
131806
|
+
} else {
|
|
131807
|
+
textX = (x12 + x2) / 2;
|
|
131808
|
+
textY = (y12 + y2) / 2;
|
|
131809
|
+
}
|
|
131810
|
+
let pixelOffset = [0, 0];
|
|
131811
|
+
let textAnchor = "middle";
|
|
131812
|
+
let alignmentBaseline = "center";
|
|
131813
|
+
if (pos !== "middle") {
|
|
131814
|
+
const dxT = x2 - x12;
|
|
131815
|
+
const dyT = y2 - y12;
|
|
131816
|
+
const lenT = Math.sqrt(dxT * dxT + dyT * dyT);
|
|
131817
|
+
if (lenT > 0) {
|
|
131818
|
+
const uxT = dxT / lenT;
|
|
131819
|
+
const uyT = dyT / lenT;
|
|
131820
|
+
const sign2 = pos === "start" ? -1 : 1;
|
|
131821
|
+
const bufferPx = shape2.textBufferPx ?? 8;
|
|
131822
|
+
const offsetX = sign2 * uxT * bufferPx;
|
|
131823
|
+
const offsetY = sign2 * uyT * bufferPx;
|
|
131824
|
+
pixelOffset = [offsetX, offsetY];
|
|
131825
|
+
const absX = Math.abs(offsetX);
|
|
131826
|
+
const absY = Math.abs(offsetY);
|
|
131827
|
+
if (absX >= absY) {
|
|
131828
|
+
textAnchor = offsetX > 0 ? "start" : "end";
|
|
131829
|
+
}
|
|
131830
|
+
if (absY >= absX) {
|
|
131831
|
+
alignmentBaseline = offsetY > 0 ? "top" : "bottom";
|
|
131832
|
+
}
|
|
131833
|
+
}
|
|
131834
|
+
} else if (len2 > 0) {
|
|
131835
|
+
const belowPerp = pickBelowPerp(ux, uy);
|
|
131836
|
+
const bufferPx = shape2.textBufferPx ?? 14;
|
|
131837
|
+
pixelOffset = [-belowPerp[0] * bufferPx, -belowPerp[1] * bufferPx];
|
|
131838
|
+
textAnchor = "middle";
|
|
131839
|
+
alignmentBaseline = "center";
|
|
131840
|
+
}
|
|
131841
|
+
const middleAngle = pos === "middle" && len2 > 0 ? -readableAngle(Math.atan2(dy, dx) * 180 / Math.PI) : null;
|
|
131842
|
+
if (labelOpacity <= 0)
|
|
131843
|
+
return;
|
|
131844
|
+
layers.push(new TextLayer({
|
|
131845
|
+
...labelBase,
|
|
131846
|
+
...labelProps,
|
|
131847
|
+
id: `annotation-line-text-${uid2}-${i2}`,
|
|
131848
|
+
data: [{ position: [textX, textY], text: shape2.text }],
|
|
131849
|
+
getPosition: (d) => d.position,
|
|
131850
|
+
getText: (d) => d.text,
|
|
131851
|
+
getColor: strokeColor,
|
|
131852
|
+
getSize: LABEL_FONT_SIZE,
|
|
131853
|
+
sizeUnits: "pixels",
|
|
131854
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131855
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131856
|
+
getPixelOffset: pixelOffset,
|
|
131857
|
+
getTextAnchor: textAnchor,
|
|
131858
|
+
getAlignmentBaseline: alignmentBaseline,
|
|
131859
|
+
...middleAngle !== null && { getAngle: middleAngle }
|
|
131860
|
+
}));
|
|
131861
|
+
}
|
|
131862
|
+
}
|
|
131863
|
+
if (type === "ellipse") {
|
|
131864
|
+
const { x1: x12, y1: y12, radiusX, radiusY, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
131865
|
+
const polygon2 = computeEllipsePolygon(x12, y12, radiusX, radiusY);
|
|
131866
|
+
const filled = fillOpacity > 0;
|
|
131867
|
+
layers.push(new PolygonLayer({
|
|
131868
|
+
...base,
|
|
131869
|
+
id: `annotation-ellipse-${uid2}-${i2}`,
|
|
131870
|
+
data: [{ polygon: polygon2 }],
|
|
131871
|
+
getPolygon: (d) => d.polygon,
|
|
131872
|
+
filled,
|
|
131873
|
+
stroked: true,
|
|
131874
|
+
getFillColor: filled ? [...fillColor, Math.round(fillOpacity * 255)] : [0, 0, 0, 0],
|
|
131875
|
+
getLineColor: strokeColor,
|
|
131876
|
+
getLineWidth: strokeWidth,
|
|
131877
|
+
lineWidthUnits: "pixels",
|
|
131878
|
+
...dashArray ? {
|
|
131879
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131880
|
+
getDashArray: dashArray
|
|
131881
|
+
} : {}
|
|
131882
|
+
}));
|
|
131883
|
+
if (shape2.text && labelOpacity > 0) {
|
|
131884
|
+
layers.push(new TextLayer({
|
|
131885
|
+
...labelBase,
|
|
131886
|
+
...labelProps,
|
|
131887
|
+
id: `annotation-ellipse-text-${uid2}-${i2}`,
|
|
131888
|
+
data: [{ position: [x12, y12 - radiusY], text: shape2.text }],
|
|
131889
|
+
getPosition: (d) => d.position,
|
|
131890
|
+
getText: (d) => d.text,
|
|
131891
|
+
getColor: strokeColor,
|
|
131892
|
+
getSize: LABEL_FONT_SIZE,
|
|
131893
|
+
sizeUnits: "pixels",
|
|
131894
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131895
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131896
|
+
getPixelOffset: [0, -4],
|
|
131897
|
+
getTextAnchor: "middle",
|
|
131898
|
+
getAlignmentBaseline: "bottom"
|
|
131899
|
+
}));
|
|
131900
|
+
}
|
|
131901
|
+
}
|
|
131902
|
+
if (type === "polygon") {
|
|
131903
|
+
const { points, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
131904
|
+
if (!points || points.length < 3)
|
|
131905
|
+
return;
|
|
131906
|
+
const closedPath = [...points, points[0]];
|
|
131907
|
+
if (fillOpacity > 0) {
|
|
131908
|
+
layers.push(new PolygonLayer({
|
|
131909
|
+
...base,
|
|
131910
|
+
id: `annotation-polygon-fill-${uid2}-${i2}`,
|
|
131911
|
+
data: [{ polygon: points }],
|
|
131912
|
+
getPolygon: (d) => d.polygon,
|
|
131913
|
+
stroked: false,
|
|
131914
|
+
filled: true,
|
|
131915
|
+
getFillColor: [...fillColor, Math.round(fillOpacity * 255)]
|
|
131916
|
+
}));
|
|
131917
|
+
}
|
|
131918
|
+
layers.push(new PathLayer({
|
|
131919
|
+
...base,
|
|
131920
|
+
id: `annotation-polygon-${uid2}-${i2}`,
|
|
131921
|
+
extensions: dashExt,
|
|
131922
|
+
getDashArray: getDash,
|
|
131923
|
+
data: [{ path: closedPath }],
|
|
131924
|
+
getPath: (d) => d.path,
|
|
131925
|
+
getColor: strokeColor,
|
|
131926
|
+
getWidth: strokeWidth,
|
|
131927
|
+
widthUnits: "pixels",
|
|
131928
|
+
jointRounded: true
|
|
131929
|
+
}));
|
|
131930
|
+
if (shape2.text && labelOpacity > 0) {
|
|
131931
|
+
const minX = Math.min(...points.map((p) => p[0]));
|
|
131932
|
+
const maxX = Math.max(...points.map((p) => p[0]));
|
|
131933
|
+
const minY = Math.min(...points.map((p) => p[1]));
|
|
131934
|
+
const topCenterX = (minX + maxX) / 2;
|
|
131935
|
+
layers.push(new TextLayer({
|
|
131936
|
+
...labelBase,
|
|
131937
|
+
...labelProps,
|
|
131938
|
+
id: `annotation-polygon-text-${uid2}-${i2}`,
|
|
131939
|
+
data: [{ position: [topCenterX, minY], text: shape2.text }],
|
|
131940
|
+
getPosition: (d) => d.position,
|
|
131941
|
+
getText: (d) => d.text,
|
|
131942
|
+
getColor: strokeColor,
|
|
131943
|
+
getSize: LABEL_FONT_SIZE,
|
|
131944
|
+
sizeUnits: "pixels",
|
|
131945
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131946
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131947
|
+
getPixelOffset: [0, -4],
|
|
131948
|
+
getTextAnchor: "middle",
|
|
131949
|
+
getAlignmentBaseline: "bottom"
|
|
131950
|
+
}));
|
|
131951
|
+
}
|
|
131952
|
+
}
|
|
131953
|
+
if (type === "polyline") {
|
|
131954
|
+
const { points, markerStart, markerEnd } = shape2;
|
|
131955
|
+
if (!points || points.length < 2)
|
|
131956
|
+
return;
|
|
131957
|
+
let pathPoints = points;
|
|
131958
|
+
if (markerStart === "Arrow") {
|
|
131959
|
+
const [x02, y02] = points[0];
|
|
131960
|
+
const [x12, y12] = points[1];
|
|
131961
|
+
const dx = x02 - x12;
|
|
131962
|
+
const dy = y02 - y12;
|
|
131963
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131964
|
+
if (len2 > 0) {
|
|
131965
|
+
const ux = dx / len2;
|
|
131966
|
+
const uy = dy / len2;
|
|
131967
|
+
pathPoints = [[x02 - ux * arrowDataSize, y02 - uy * arrowDataSize], ...pathPoints.slice(1)];
|
|
131968
|
+
}
|
|
131969
|
+
}
|
|
131970
|
+
if (markerEnd === "Arrow") {
|
|
131971
|
+
const last = pathPoints[pathPoints.length - 1];
|
|
131972
|
+
const prev2 = pathPoints[pathPoints.length - 2];
|
|
131973
|
+
const dx = last[0] - prev2[0];
|
|
131974
|
+
const dy = last[1] - prev2[1];
|
|
131975
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131976
|
+
if (len2 > 0) {
|
|
131977
|
+
const ux = dx / len2;
|
|
131978
|
+
const uy = dy / len2;
|
|
131979
|
+
const shortened = [last[0] - ux * arrowDataSize, last[1] - uy * arrowDataSize];
|
|
131980
|
+
pathPoints = [...pathPoints.slice(0, -1), shortened];
|
|
131981
|
+
}
|
|
131982
|
+
}
|
|
131983
|
+
layers.push(new PathLayer({
|
|
131984
|
+
...base,
|
|
131985
|
+
id: `annotation-polyline-${uid2}-${i2}`,
|
|
131986
|
+
extensions: dashExt,
|
|
131987
|
+
getDashArray: getDash,
|
|
131988
|
+
data: [{ path: pathPoints }],
|
|
131989
|
+
getPath: (d) => d.path,
|
|
131990
|
+
getColor: strokeColor,
|
|
131991
|
+
getWidth: strokeWidth,
|
|
131992
|
+
widthUnits: "pixels",
|
|
131993
|
+
jointRounded: true,
|
|
131994
|
+
capRounded: true
|
|
131995
|
+
}));
|
|
131996
|
+
if (markerStart === "Arrow" && tipsOpacity > 0) {
|
|
131997
|
+
const [x02, y02] = points[0];
|
|
131998
|
+
const [x12, y12] = points[1];
|
|
131999
|
+
const head = computeArrowhead(x02, y02, x02 - x12, y02 - y12, arrowDataSize);
|
|
132000
|
+
if (head) {
|
|
132001
|
+
layers.push(new PolygonLayer({
|
|
132002
|
+
...tipsBase,
|
|
132003
|
+
id: `annotation-polyline-start-arrow-${uid2}-${i2}`,
|
|
132004
|
+
data: [{ polygon: head }],
|
|
132005
|
+
getPolygon: (d) => d.polygon,
|
|
132006
|
+
filled: true,
|
|
132007
|
+
stroked: false,
|
|
132008
|
+
getFillColor: strokeColor
|
|
132009
|
+
}));
|
|
132010
|
+
}
|
|
132011
|
+
}
|
|
132012
|
+
if (markerEnd === "Arrow" && tipsOpacity > 0) {
|
|
132013
|
+
const last = points[points.length - 1];
|
|
132014
|
+
const prev2 = points[points.length - 2];
|
|
132015
|
+
const dxArrow = last[0] - prev2[0];
|
|
132016
|
+
const dyArrow = last[1] - prev2[1];
|
|
132017
|
+
const head = computeArrowhead(last[0], last[1], dxArrow, dyArrow, arrowDataSize);
|
|
132018
|
+
if (head) {
|
|
132019
|
+
layers.push(new PolygonLayer({
|
|
132020
|
+
...tipsBase,
|
|
132021
|
+
id: `annotation-polyline-end-arrow-${uid2}-${i2}`,
|
|
132022
|
+
data: [{ polygon: head }],
|
|
132023
|
+
getPolygon: (d) => d.polygon,
|
|
132024
|
+
filled: true,
|
|
132025
|
+
stroked: false,
|
|
132026
|
+
getFillColor: strokeColor
|
|
132027
|
+
}));
|
|
132028
|
+
}
|
|
132029
|
+
}
|
|
132030
|
+
if (markerStart === "Tick" && tipsOpacity > 0) {
|
|
132031
|
+
const [x02, y02] = points[0];
|
|
132032
|
+
const [x12, y12] = points[1];
|
|
132033
|
+
const tick = computeTickCap(x02, y02, x02 - x12, y02 - y12, arrowDataSize);
|
|
132034
|
+
if (tick) {
|
|
132035
|
+
layers.push(new PathLayer({
|
|
132036
|
+
...tipsBase,
|
|
132037
|
+
id: `annotation-polyline-start-tick-${uid2}-${i2}`,
|
|
132038
|
+
data: [{ path: tick }],
|
|
132039
|
+
getPath: (d) => d.path,
|
|
132040
|
+
getColor: strokeColor,
|
|
132041
|
+
getWidth: strokeWidth,
|
|
132042
|
+
widthUnits: "pixels",
|
|
132043
|
+
capRounded: true
|
|
132044
|
+
}));
|
|
132045
|
+
}
|
|
132046
|
+
}
|
|
132047
|
+
if (markerEnd === "Tick" && tipsOpacity > 0) {
|
|
132048
|
+
const last = points[points.length - 1];
|
|
132049
|
+
const prev2 = points[points.length - 2];
|
|
132050
|
+
const dxTick = last[0] - prev2[0];
|
|
132051
|
+
const dyTick = last[1] - prev2[1];
|
|
132052
|
+
const tick = computeTickCap(last[0], last[1], dxTick, dyTick, arrowDataSize);
|
|
132053
|
+
if (tick) {
|
|
132054
|
+
layers.push(new PathLayer({
|
|
132055
|
+
...tipsBase,
|
|
132056
|
+
id: `annotation-polyline-end-tick-${uid2}-${i2}`,
|
|
132057
|
+
data: [{ path: tick }],
|
|
132058
|
+
getPath: (d) => d.path,
|
|
132059
|
+
getColor: strokeColor,
|
|
132060
|
+
getWidth: strokeWidth,
|
|
132061
|
+
widthUnits: "pixels",
|
|
132062
|
+
capRounded: true
|
|
132063
|
+
}));
|
|
132064
|
+
}
|
|
132065
|
+
}
|
|
132066
|
+
if (shape2.text) {
|
|
132067
|
+
const pos = shape2.textPosition ?? "start";
|
|
132068
|
+
const bufferPx = shape2.textBufferPx ?? 8;
|
|
132069
|
+
let textPt;
|
|
132070
|
+
let dirX;
|
|
132071
|
+
let dirY;
|
|
132072
|
+
if (pos === "end") {
|
|
132073
|
+
const last = points[points.length - 1];
|
|
132074
|
+
const prev2 = points[points.length - 2];
|
|
132075
|
+
textPt = last;
|
|
132076
|
+
dirX = last[0] - prev2[0];
|
|
132077
|
+
dirY = last[1] - prev2[1];
|
|
132078
|
+
} else if (pos === "middle") {
|
|
132079
|
+
const mx = points.reduce((s2, p) => s2 + p[0], 0) / points.length;
|
|
132080
|
+
const my = points.reduce((s2, p) => s2 + p[1], 0) / points.length;
|
|
132081
|
+
textPt = [mx, my];
|
|
132082
|
+
dirX = 0;
|
|
132083
|
+
dirY = 0;
|
|
132084
|
+
} else {
|
|
132085
|
+
[textPt] = points;
|
|
132086
|
+
dirX = points[0][0] - points[1][0];
|
|
132087
|
+
dirY = points[0][1] - points[1][1];
|
|
132088
|
+
}
|
|
132089
|
+
const [textX, textY] = textPt;
|
|
132090
|
+
const lenT = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
132091
|
+
let polylinePixelOffset = [0, 0];
|
|
132092
|
+
let polylineTextAnchor = "middle";
|
|
132093
|
+
let polylineAlignmentBaseline = pos === "middle" ? "center" : "bottom";
|
|
132094
|
+
if (lenT > 0) {
|
|
132095
|
+
const uxT = dirX / lenT;
|
|
132096
|
+
const uyT = dirY / lenT;
|
|
132097
|
+
const offX = uxT * bufferPx;
|
|
132098
|
+
const offY = uyT * bufferPx;
|
|
132099
|
+
polylinePixelOffset = [offX, offY];
|
|
132100
|
+
if (Math.abs(offX) >= Math.abs(offY)) {
|
|
132101
|
+
polylineTextAnchor = offX > 0 ? "start" : "end";
|
|
132102
|
+
}
|
|
132103
|
+
if (Math.abs(offY) >= Math.abs(offX)) {
|
|
132104
|
+
polylineAlignmentBaseline = offY > 0 ? "top" : "bottom";
|
|
132105
|
+
}
|
|
132106
|
+
}
|
|
132107
|
+
if (labelOpacity <= 0)
|
|
132108
|
+
return;
|
|
132109
|
+
layers.push(new TextLayer({
|
|
132110
|
+
...labelBase,
|
|
132111
|
+
...labelProps,
|
|
132112
|
+
id: `annotation-polyline-text-${uid2}-${i2}`,
|
|
132113
|
+
data: [{ position: [textX, textY], text: shape2.text }],
|
|
132114
|
+
getPosition: (d) => d.position,
|
|
132115
|
+
getText: (d) => d.text,
|
|
132116
|
+
getColor: strokeColor,
|
|
132117
|
+
getSize: LABEL_FONT_SIZE,
|
|
132118
|
+
sizeUnits: "pixels",
|
|
132119
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
132120
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
132121
|
+
getPixelOffset: polylinePixelOffset,
|
|
132122
|
+
getTextAnchor: polylineTextAnchor,
|
|
132123
|
+
getAlignmentBaseline: polylineAlignmentBaseline
|
|
132124
|
+
}));
|
|
132125
|
+
}
|
|
132126
|
+
}
|
|
132127
|
+
});
|
|
132128
|
+
if (dotShapes.length > 0) {
|
|
132129
|
+
layers.push(new ScatterplotLayer({
|
|
132130
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
132131
|
+
id: "annotation-dots",
|
|
132132
|
+
data: dotShapes.map(({ shape: s2, alpha: alpha2 }) => ({
|
|
132133
|
+
position: getShapeCentroid(s2),
|
|
132134
|
+
color: [...s2.strokeColor ?? [255, 255, 255], alpha2]
|
|
132135
|
+
})),
|
|
132136
|
+
getPosition: (d) => d.position,
|
|
132137
|
+
getFillColor: (d) => d.color,
|
|
132138
|
+
getRadius: 4,
|
|
132139
|
+
radiusUnits: "pixels",
|
|
132140
|
+
filled: true,
|
|
132141
|
+
stroked: false
|
|
132142
|
+
}));
|
|
132143
|
+
}
|
|
132144
|
+
if (clusterDotShapes.length > 0) {
|
|
132145
|
+
const clusters = computeClusters(clusterDotShapes, zoom);
|
|
132146
|
+
layers.push(new ScatterplotLayer({
|
|
132147
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
132148
|
+
id: "annotation-clusters",
|
|
132149
|
+
data: clusters,
|
|
132150
|
+
getPosition: (d) => d.position,
|
|
132151
|
+
getFillColor: (d) => [...d.color, 180],
|
|
132152
|
+
getRadius: (d) => Math.max(6, 4 + Math.sqrt(d.count) * 2),
|
|
132153
|
+
radiusUnits: "pixels",
|
|
132154
|
+
filled: true,
|
|
132155
|
+
stroked: true,
|
|
132156
|
+
getLineColor: (d) => [...d.color, 220],
|
|
132157
|
+
lineWidthMinPixels: 1.5
|
|
132158
|
+
}));
|
|
132159
|
+
const multiClusters = clusters.filter((c2) => c2.count > 1);
|
|
132160
|
+
if (multiClusters.length > 0) {
|
|
132161
|
+
layers.push(new TextLayer({
|
|
132162
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
132163
|
+
id: "annotation-cluster-counts",
|
|
132164
|
+
data: multiClusters,
|
|
132165
|
+
getPosition: (d) => d.position,
|
|
132166
|
+
getText: (d) => String(d.count),
|
|
132167
|
+
getColor: [255, 255, 255],
|
|
132168
|
+
getSize: 10,
|
|
132169
|
+
sizeUnits: "pixels",
|
|
132170
|
+
fontWeight: "bold",
|
|
132171
|
+
getTextAnchor: "middle",
|
|
132172
|
+
getAlignmentBaseline: "center"
|
|
132173
|
+
}));
|
|
132174
|
+
}
|
|
132175
|
+
}
|
|
132176
|
+
const measureLayers = [];
|
|
132177
|
+
shapes.forEach((shape2) => {
|
|
132178
|
+
if (!shape2.showMeasure)
|
|
132179
|
+
return;
|
|
132180
|
+
const mIsSelected = shape2.uid === selectedShapeUid;
|
|
132181
|
+
const label = getMeasurementLabel(shape2, physicalPixelSize, viewType);
|
|
132182
|
+
if (!label)
|
|
132183
|
+
return;
|
|
132184
|
+
const color2 = shape2.strokeColor ?? [255, 255, 255];
|
|
132185
|
+
let mShapeOpacity = 1;
|
|
132186
|
+
let mLabelFactor = 0;
|
|
132187
|
+
if (mIsSelected || !semanticZoom || authoredZoom === null) {
|
|
132188
|
+
mLabelFactor = 1;
|
|
132189
|
+
} else {
|
|
132190
|
+
const mZoomRatio = 2 ** (zoom - authoredZoom);
|
|
132191
|
+
if (mZoomRatio < RATIO_DOT)
|
|
132192
|
+
return;
|
|
132193
|
+
if (mZoomRatio < RATIO_GEO_FADE) {
|
|
132194
|
+
mShapeOpacity = (mZoomRatio - RATIO_DOT) / (RATIO_GEO_FADE - RATIO_DOT);
|
|
132195
|
+
}
|
|
132196
|
+
if (mZoomRatio >= RATIO_LABEL_FULL) {
|
|
132197
|
+
mLabelFactor = 1;
|
|
132198
|
+
} else if (mZoomRatio >= RATIO_LABEL) {
|
|
132199
|
+
mLabelFactor = (mZoomRatio - RATIO_LABEL) / (RATIO_LABEL_FULL - RATIO_LABEL);
|
|
132200
|
+
}
|
|
132201
|
+
}
|
|
132202
|
+
const measureOpacity = mShapeOpacity * mLabelFactor;
|
|
132203
|
+
if (measureOpacity <= 0)
|
|
132204
|
+
return;
|
|
132205
|
+
const base = {
|
|
132206
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
132207
|
+
opacity: measureOpacity,
|
|
132208
|
+
getText: (d) => d.text,
|
|
132209
|
+
getPosition: (d) => d.position,
|
|
132210
|
+
getColor: color2,
|
|
132211
|
+
getSize: 13,
|
|
132212
|
+
sizeUnits: "pixels",
|
|
132213
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
132214
|
+
fontWeight: "bold",
|
|
132215
|
+
// 'auto' builds the font atlas from the actual rendered characters (e.g. µ, ²)
|
|
132216
|
+
// instead of deck.gl's default ASCII-only atlas.
|
|
132217
|
+
characterSet: "auto",
|
|
132218
|
+
...shape2.measureBackground ? {
|
|
132219
|
+
background: true,
|
|
132220
|
+
getBackgroundColor: textBgColor(color2),
|
|
132221
|
+
backgroundPadding: [3, 1, 3, 2]
|
|
132222
|
+
} : {}
|
|
132223
|
+
};
|
|
132224
|
+
if (shape2.type === "line") {
|
|
132225
|
+
const mx = ((shape2.x1 ?? 0) + (shape2.x2 ?? 0)) / 2;
|
|
132226
|
+
const my = ((shape2.y1 ?? 0) + (shape2.y2 ?? 0)) / 2;
|
|
132227
|
+
const dx = (shape2.x2 ?? 0) - (shape2.x1 ?? 0);
|
|
132228
|
+
const dy = (shape2.y2 ?? 0) - (shape2.y1 ?? 0);
|
|
132229
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
132230
|
+
if (len2 === 0)
|
|
132231
|
+
return;
|
|
132232
|
+
const perp = pickBelowPerp(dx / len2, dy / len2);
|
|
132233
|
+
const angle2 = readableAngle(Math.atan2(dy, dx) * 180 / Math.PI);
|
|
132234
|
+
measureLayers.push(new TextLayer({
|
|
132235
|
+
...base,
|
|
132236
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
132237
|
+
data: [{ position: [mx, my], text: label }],
|
|
132238
|
+
getAngle: -angle2,
|
|
132239
|
+
getTextAnchor: "middle",
|
|
132240
|
+
getAlignmentBaseline: "center",
|
|
132241
|
+
getPixelOffset: [perp[0] * 16, perp[1] * 16]
|
|
132242
|
+
}));
|
|
132243
|
+
} else if (shape2.type === "polyline" && shape2.points?.length >= 2) {
|
|
132244
|
+
const pts = shape2.points;
|
|
132245
|
+
const mi = Math.floor((pts.length - 1) / 2);
|
|
132246
|
+
const [ax, ay] = pts[mi];
|
|
132247
|
+
const [bx, by] = pts[mi + 1];
|
|
132248
|
+
const dx = bx - ax;
|
|
132249
|
+
const dy = by - ay;
|
|
132250
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
132251
|
+
if (len2 === 0)
|
|
132252
|
+
return;
|
|
132253
|
+
const perp = pickBelowPerp(dx / len2, dy / len2);
|
|
132254
|
+
const angle2 = readableAngle(Math.atan2(dy, dx) * 180 / Math.PI);
|
|
132255
|
+
measureLayers.push(new TextLayer({
|
|
132256
|
+
...base,
|
|
132257
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
132258
|
+
data: [{ position: [(ax + bx) / 2, (ay + by) / 2], text: label }],
|
|
132259
|
+
getAngle: -angle2,
|
|
132260
|
+
getTextAnchor: "middle",
|
|
132261
|
+
getAlignmentBaseline: "center",
|
|
132262
|
+
getPixelOffset: [perp[0] * 16, perp[1] * 16]
|
|
132263
|
+
}));
|
|
132264
|
+
} else if (shape2.type === "rectangle") {
|
|
132265
|
+
const x02 = shape2.x ?? 0;
|
|
132266
|
+
const y02 = shape2.y ?? 0;
|
|
132267
|
+
const w2 = shape2.width ?? 0;
|
|
132268
|
+
const h = shape2.height ?? 0;
|
|
132269
|
+
const rx = x02 + (w2 >= 0 ? w2 : 0);
|
|
132270
|
+
const ry = y02 + (h >= 0 ? h : 0);
|
|
132271
|
+
measureLayers.push(new TextLayer({
|
|
132272
|
+
...base,
|
|
132273
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
132274
|
+
data: [{ position: [rx, ry], text: label }],
|
|
132275
|
+
getTextAnchor: "end",
|
|
132276
|
+
getAlignmentBaseline: "bottom",
|
|
132277
|
+
getPixelOffset: [-6, -6]
|
|
132278
|
+
}));
|
|
132279
|
+
} else if (shape2.type === "ellipse") {
|
|
132280
|
+
const cx = shape2.x1 ?? 0;
|
|
132281
|
+
const cy = shape2.y1 ?? 0;
|
|
132282
|
+
const ry = Math.abs(shape2.radiusY ?? 0);
|
|
132283
|
+
measureLayers.push(new TextLayer({
|
|
132284
|
+
...base,
|
|
132285
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
132286
|
+
data: [{ position: [cx, cy + ry], text: label }],
|
|
132287
|
+
getTextAnchor: "middle",
|
|
132288
|
+
getAlignmentBaseline: "top",
|
|
132289
|
+
getPixelOffset: [0, 8]
|
|
132290
|
+
}));
|
|
132291
|
+
} else if (shape2.type === "polygon" && shape2.points?.length >= 3) {
|
|
132292
|
+
const xs = shape2.points.map((p) => p[0]);
|
|
132293
|
+
const ys = shape2.points.map((p) => p[1]);
|
|
132294
|
+
const cx = (Math.min(...xs) + Math.max(...xs)) / 2;
|
|
132295
|
+
const maxY = Math.max(...ys);
|
|
132296
|
+
measureLayers.push(new TextLayer({
|
|
132297
|
+
...base,
|
|
132298
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
132299
|
+
data: [{ position: [cx, maxY], text: label }],
|
|
132300
|
+
getTextAnchor: "middle",
|
|
132301
|
+
getAlignmentBaseline: "top",
|
|
132302
|
+
getPixelOffset: [0, 8]
|
|
132303
|
+
}));
|
|
132304
|
+
}
|
|
132305
|
+
});
|
|
132306
|
+
return [...selectionLayers, ...layers, ...measureLayers];
|
|
132307
|
+
}
|
|
132308
|
+
const defaultProps$1 = {
|
|
132309
|
+
// Array of annotation shape objects (see annotationShapeObj in @vitessce/schemas).
|
|
132310
|
+
data: { type: "object", value: [], compare: true },
|
|
132311
|
+
// UID of the shape to highlight with a selection halo.
|
|
132312
|
+
selectedShapeUid: { type: "string", value: null },
|
|
132313
|
+
// { x, y, unit } used to format measurement labels in physical units.
|
|
132314
|
+
physicalPixelSize: { type: "object", value: null, compare: true },
|
|
132315
|
+
// The zoom level at which the shapes were authored (reference for semantic zoom).
|
|
132316
|
+
authoredZoom: { type: "number", value: null },
|
|
132317
|
+
// Whether to apply semantic zoom (level-of-detail) based on authoredZoom.
|
|
132318
|
+
semanticZoom: { type: "boolean", value: true },
|
|
132319
|
+
// The view type in which the layer is rendered (affects measurement label formatting).
|
|
132320
|
+
viewType: { type: "string", value: ViewType$1.SPATIAL },
|
|
132321
|
+
// In-progress shape being drawn, as { type, vertices }.
|
|
132322
|
+
inProgressShape: { type: "object", value: null, compare: true },
|
|
132323
|
+
// Current mouse position (in data coordinates) while drawing.
|
|
132324
|
+
hoverCoord: { type: "array", value: null, compare: true },
|
|
132325
|
+
// Stroke color [r, g, b] of the in-progress shape preview.
|
|
132326
|
+
previewStrokeColor: { type: "color", value: [255, 255, 0] }
|
|
132327
|
+
};
|
|
132328
|
+
class AnnotationLayer extends CompositeLayer {
|
|
132329
|
+
// The semantic zoom and arrowhead sizes depend on the current zoom level,
|
|
132330
|
+
// so the sublayers must also be re-rendered when the viewport changes.
|
|
132331
|
+
// eslint-disable-next-line class-methods-use-this
|
|
132332
|
+
shouldUpdateState({ changeFlags }) {
|
|
132333
|
+
return changeFlags.propsOrDataChanged || changeFlags.viewportChanged;
|
|
132334
|
+
}
|
|
132335
|
+
/**
|
|
132336
|
+
* Prefix the sublayer ID with this layer's ID (so that multiple
|
|
132337
|
+
* AnnotationLayers can co-exist), and combine this layer's
|
|
132338
|
+
* opacity with the per-shape opacity of the sublayer.
|
|
132339
|
+
* Note: we avoid getSubLayerProps here, since it would
|
|
132340
|
+
* overwrite the sublayer extensions (e.g., PathStyleExtension)
|
|
132341
|
+
* and opacity values.
|
|
132342
|
+
* @param {object} layer A DeckGL layer instance.
|
|
132343
|
+
* @returns {object} The cloned layer instance.
|
|
132344
|
+
*/
|
|
132345
|
+
wrapSubLayer(layer) {
|
|
132346
|
+
const { id, opacity, pickable, visible } = this.props;
|
|
132347
|
+
return layer.clone({
|
|
132348
|
+
id: `${id}-${layer.id}`,
|
|
132349
|
+
opacity: layer.props.opacity * opacity,
|
|
132350
|
+
pickable,
|
|
132351
|
+
visible
|
|
132352
|
+
});
|
|
132353
|
+
}
|
|
132354
|
+
renderLayers() {
|
|
132355
|
+
const { data, selectedShapeUid, physicalPixelSize, authoredZoom, semanticZoom, viewType, inProgressShape, hoverCoord, previewStrokeColor } = this.props;
|
|
132356
|
+
const zoom = this.context.viewport?.zoom ?? 0;
|
|
132357
|
+
const visibleShapes = (data ?? []).filter((shape2) => shape2.visible !== false);
|
|
132358
|
+
const annotationLayers = createAnnotationLayers(visibleShapes, zoom, selectedShapeUid, physicalPixelSize, authoredZoom, semanticZoom, viewType);
|
|
132359
|
+
const previewLayer = createPreviewLayer(inProgressShape, hoverCoord, previewStrokeColor.slice(0, 3));
|
|
132360
|
+
return [
|
|
132361
|
+
...annotationLayers,
|
|
132362
|
+
...previewLayer ? [previewLayer] : []
|
|
132363
|
+
].map((layer) => this.wrapSubLayer(layer));
|
|
132364
|
+
}
|
|
132365
|
+
}
|
|
132366
|
+
AnnotationLayer.layerName = "AnnotationLayer";
|
|
132367
|
+
AnnotationLayer.defaultProps = defaultProps$1;
|
|
130999
132368
|
function r$1(e3) {
|
|
131000
132369
|
var t, f2, n2 = "";
|
|
131001
132370
|
if ("string" == typeof e3 || "number" == typeof e3) n2 += e3;
|
|
@@ -145636,11 +147005,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
145636
147005
|
this.cellSetsLabelPrevZoom = null;
|
|
145637
147006
|
this.cellSetsLayers = [];
|
|
145638
147007
|
this.contourLayers = [];
|
|
147008
|
+
this.annotationLayer = null;
|
|
145639
147009
|
this.onUpdateCellsData();
|
|
145640
147010
|
this.onUpdateCellsLayer();
|
|
145641
147011
|
this.onUpdateCellSetsLayers();
|
|
145642
147012
|
this.onUpdateStratifiedData();
|
|
145643
147013
|
this.onUpdateContourLayers();
|
|
147014
|
+
this.onUpdateAnnotationLayer();
|
|
145644
147015
|
}
|
|
145645
147016
|
// Want to support multiple types of contour layers
|
|
145646
147017
|
// - One layer for all data points (no filtering)
|
|
@@ -145704,6 +147075,21 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
145704
147075
|
}));
|
|
145705
147076
|
return layers;
|
|
145706
147077
|
}
|
|
147078
|
+
createAnnotationLayer() {
|
|
147079
|
+
const { annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection } = this.props;
|
|
147080
|
+
return new AnnotationLayer({
|
|
147081
|
+
data: annotationShapes,
|
|
147082
|
+
visible: annotationOverlayVisible,
|
|
147083
|
+
semanticZoom: annotationSemanticZoom,
|
|
147084
|
+
selectedShapeUid: annotationShapeSelection,
|
|
147085
|
+
viewType: ViewType$1.SCATTERPLOT
|
|
147086
|
+
// TODO: is this needed?
|
|
147087
|
+
// TODO: these are view-level properties, rather than layer-level.
|
|
147088
|
+
// annotationTransitionDuration,
|
|
147089
|
+
// annotationEditable,
|
|
147090
|
+
// Other coordination types related to editing...
|
|
147091
|
+
});
|
|
147092
|
+
}
|
|
145707
147093
|
createCellsLayer() {
|
|
145708
147094
|
const {
|
|
145709
147095
|
obsEmbeddingIndex: obsIndex,
|
|
@@ -145837,12 +147223,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
145837
147223
|
], flipYTooltip, this.props.onSelectionBusy);
|
|
145838
147224
|
}
|
|
145839
147225
|
getLayers() {
|
|
145840
|
-
const { cellsLayer, cellSetsLayers, contourLayers } = this;
|
|
147226
|
+
const { cellsLayer, cellSetsLayers, contourLayers, annotationLayer } = this;
|
|
145841
147227
|
return [
|
|
145842
147228
|
cellsLayer,
|
|
145843
147229
|
...contourLayers,
|
|
145844
147230
|
...cellSetsLayers,
|
|
145845
|
-
this.createSelectionLayer()
|
|
147231
|
+
this.createSelectionLayer(),
|
|
147232
|
+
annotationLayer
|
|
145846
147233
|
];
|
|
145847
147234
|
}
|
|
145848
147235
|
/**
|
|
@@ -145879,6 +147266,14 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
145879
147266
|
this.cellsLayer = null;
|
|
145880
147267
|
}
|
|
145881
147268
|
}
|
|
147269
|
+
onUpdateAnnotationLayer() {
|
|
147270
|
+
const { annotationShapes } = this.props;
|
|
147271
|
+
if (annotationShapes) {
|
|
147272
|
+
this.annotationLayer = this.createAnnotationLayer();
|
|
147273
|
+
} else {
|
|
147274
|
+
this.annotationLayer = null;
|
|
147275
|
+
}
|
|
147276
|
+
}
|
|
145882
147277
|
onUpdateStratifiedData() {
|
|
145883
147278
|
const { stratifiedData } = this.props;
|
|
145884
147279
|
if (stratifiedData) {
|
|
@@ -145994,6 +147389,16 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
145994
147389
|
this.onUpdateCellSetsLayers(true);
|
|
145995
147390
|
forceUpdate = true;
|
|
145996
147391
|
}
|
|
147392
|
+
if ([
|
|
147393
|
+
"annotationShapes",
|
|
147394
|
+
"annotationOverlayVisible",
|
|
147395
|
+
"annotationSemanticZoom",
|
|
147396
|
+
"annotationTransitionDuration",
|
|
147397
|
+
"annotationEditable"
|
|
147398
|
+
].some(shallowDiff)) {
|
|
147399
|
+
this.onUpdateAnnotationLayer();
|
|
147400
|
+
forceUpdate = true;
|
|
147401
|
+
}
|
|
145997
147402
|
if (forceUpdate) {
|
|
145998
147403
|
this.forceUpdate();
|
|
145999
147404
|
}
|
|
@@ -148795,7 +150200,6 @@ const DEFAULT_FEATURE_AGGREGATION_STRATEGY = "first";
|
|
|
148795
150200
|
function EmbeddingScatterplotSubscriber(props) {
|
|
148796
150201
|
const {
|
|
148797
150202
|
uuid,
|
|
148798
|
-
coordinationScopes: coordinationScopesRaw,
|
|
148799
150203
|
closeButtonVisible,
|
|
148800
150204
|
downloadButtonVisible,
|
|
148801
150205
|
removeGridComponent,
|
|
@@ -148811,9 +150215,15 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
148811
150215
|
circleScaleFactor = 0.8
|
|
148812
150216
|
} = props;
|
|
148813
150217
|
const loaders = useLoaders();
|
|
148814
|
-
const
|
|
150218
|
+
const [
|
|
150219
|
+
// eslint-disable-next-line no-unused-vars
|
|
150220
|
+
coordinationScopes,
|
|
150221
|
+
_coordinationScopesBy,
|
|
150222
|
+
coordinationValues
|
|
150223
|
+
] = useViewMapping(uuid);
|
|
148815
150224
|
const setComponentHover = useSetComponentHover();
|
|
148816
150225
|
const setComponentViewInfo = useSetComponentViewInfo(uuid);
|
|
150226
|
+
useAnnotationFrameCoordination(uuid, coordinationScopes, coordinationValues);
|
|
148817
150227
|
const [{
|
|
148818
150228
|
dataset,
|
|
148819
150229
|
obsType,
|
|
@@ -148850,7 +150260,13 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
148850
150260
|
embeddingContourPercentiles: contourPercentiles,
|
|
148851
150261
|
contourColorEncoding,
|
|
148852
150262
|
contourColor,
|
|
148853
|
-
featureAggregationStrategy
|
|
150263
|
+
featureAggregationStrategy,
|
|
150264
|
+
annotationStory,
|
|
150265
|
+
annotationShapes,
|
|
150266
|
+
annotationOverlayVisible,
|
|
150267
|
+
annotationSemanticZoom,
|
|
150268
|
+
annotationTransitionDuration,
|
|
150269
|
+
annotationEditable
|
|
148854
150270
|
}, {
|
|
148855
150271
|
setEmbeddingZoom: setZoom,
|
|
148856
150272
|
setEmbeddingTargetX: setTargetX,
|
|
@@ -148877,21 +150293,41 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
148877
150293
|
setEmbeddingContoursFilled,
|
|
148878
150294
|
setEmbeddingContourPercentiles: setContourPercentiles,
|
|
148879
150295
|
setContourColorEncoding,
|
|
148880
|
-
setFeatureAggregationStrategy
|
|
148881
|
-
|
|
150296
|
+
setFeatureAggregationStrategy,
|
|
150297
|
+
setAnnotationStory
|
|
150298
|
+
}] = useCoordination(
|
|
150299
|
+
COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT],
|
|
150300
|
+
coordinationScopes,
|
|
150301
|
+
coordinationValues,
|
|
150302
|
+
uuid
|
|
150303
|
+
);
|
|
148882
150304
|
const {
|
|
148883
150305
|
embeddingZoom: initialZoom,
|
|
148884
150306
|
embeddingTargetX: initialTargetX,
|
|
148885
150307
|
embeddingTargetY: initialTargetY
|
|
148886
150308
|
} = useInitialCoordination(
|
|
148887
150309
|
COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT],
|
|
148888
|
-
coordinationScopes
|
|
150310
|
+
coordinationScopes,
|
|
150311
|
+
coordinationValues
|
|
148889
150312
|
);
|
|
148890
150313
|
const observationsLabel = observationsLabelOverride || obsType;
|
|
148891
150314
|
const sampleSetSelection = sampleSetSelectionFromProps || sampleSetSelectionFromCoordination;
|
|
148892
150315
|
const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY;
|
|
148893
150316
|
const [width2, height2, deckRef] = useDeckCanvasSize();
|
|
148894
150317
|
const title = titleOverride || `Scatterplot (${mapping})`;
|
|
150318
|
+
const [
|
|
150319
|
+
,
|
|
150320
|
+
annotationStoryStatus,
|
|
150321
|
+
annotationStoryUrls,
|
|
150322
|
+
annotationStoryError
|
|
150323
|
+
] = useAnnotationStoryData(
|
|
150324
|
+
loaders,
|
|
150325
|
+
dataset,
|
|
150326
|
+
false,
|
|
150327
|
+
{ setAnnotationStory },
|
|
150328
|
+
{ annotationStory },
|
|
150329
|
+
{}
|
|
150330
|
+
);
|
|
148895
150331
|
const [
|
|
148896
150332
|
// eslint-disable-next-line no-unused-vars
|
|
148897
150333
|
obsLabelsTypes,
|
|
@@ -148998,11 +150434,13 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
148998
150434
|
matrixIndicesError,
|
|
148999
150435
|
featureLabelsError,
|
|
149000
150436
|
sampleSetsError,
|
|
149001
|
-
sampleEdgesError
|
|
150437
|
+
sampleEdgesError,
|
|
150438
|
+
annotationStoryError
|
|
149002
150439
|
];
|
|
149003
150440
|
const isReady = useReady([
|
|
149004
150441
|
obsEmbeddingStatus,
|
|
149005
150442
|
obsSetsStatus,
|
|
150443
|
+
annotationStoryStatus,
|
|
149006
150444
|
featureSelectionStatus,
|
|
149007
150445
|
featureLabelsStatus,
|
|
149008
150446
|
expandedFeatureLabelsStatus,
|
|
@@ -149016,7 +150454,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
149016
150454
|
matrixIndicesUrls,
|
|
149017
150455
|
featureLabelsUrls,
|
|
149018
150456
|
sampleSetsUrl,
|
|
149019
|
-
sampleEdgesUrl
|
|
150457
|
+
sampleEdgesUrl,
|
|
150458
|
+
annotationStoryUrls
|
|
149020
150459
|
]);
|
|
149021
150460
|
const [dynamicCellRadius, setDynamicCellRadius] = useState(cellRadiusFixed);
|
|
149022
150461
|
const [isSelectionPending, setIsSelectionPending] = useState(false);
|
|
@@ -149392,7 +150831,12 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
149392
150831
|
embeddingPointsVisible,
|
|
149393
150832
|
embeddingContoursVisible,
|
|
149394
150833
|
circleInfo,
|
|
149395
|
-
featureSelection: geneSelection
|
|
150834
|
+
featureSelection: geneSelection,
|
|
150835
|
+
annotationShapes,
|
|
150836
|
+
annotationOverlayVisible,
|
|
150837
|
+
annotationSemanticZoom,
|
|
150838
|
+
annotationTransitionDuration,
|
|
150839
|
+
annotationEditable
|
|
149396
150840
|
}
|
|
149397
150841
|
),
|
|
149398
150842
|
tooltipsVisible && width2 && height2 ? /* @__PURE__ */ React__default.createElement(
|