@vitessce/all 4.0.8 → 4.0.10
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/{GeometryAndMeshXR-Caba1QEa.js → GeometryAndMeshXR-BovcVfOy.js} +1 -1
- package/dist/{ReactNeuroglancer-Cm_ERWOf.js → ReactNeuroglancer-Ch1xO_u5.js} +1 -1
- package/dist/{XREnterButton-C7Q7e8rD.js → XREnterButton-Dz4r7Jjx.js} +1 -1
- package/dist/{XRSceneComponents-Dgayh6-j.js → XRSceneComponents-CGcz34cr.js} +1 -1
- package/dist/{XRWrapper-BrRGN2E4.js → XRWrapper-C1AfBFtW.js} +2 -2
- package/dist/{deflate-D1RcEgtg.js → deflate-BKJk_mLF.js} +1 -1
- package/dist/{higlass-BLYM2C4s.js → higlass-BzshVp46.js} +1 -1
- package/dist/{index-Bub8madF.js → index-CNXTPnLt.js} +1 -1
- package/dist/{index-B8xbImKw.js → index-CfweEgJW.js} +5 -5
- package/dist/{index-CzTdHRMx.js → index-EoA5CfO8.js} +1907 -150
- package/dist/index.js +8 -1
- package/dist/{jpeg-g9i0I1mK.js → jpeg-DXSq15HV.js} +1 -1
- package/dist/{lerc-B4lSBwWt.js → lerc-uTsWAc7Y.js} +1 -1
- package/dist/{lzw-63HBqTiG.js → lzw-CIpLYaya.js} +1 -1
- package/dist/{packbits-i970u6wg.js → packbits-Cf0TB9M_.js} +1 -1
- package/dist/{raw-akfNT_LS.js → raw-CR3kVxsB.js} +1 -1
- package/dist/{webimage-CA4EiJGO.js → webimage-Dp3HLfwF.js} +1 -1
- package/dist/{xrStore--BrpHLm6.js → xrStore-B2qW6VGJ.js} +1 -1
- package/dist-tsc/base-plugins.d.ts +268 -1
- package/dist-tsc/base-plugins.d.ts.map +1 -1
- package/dist-tsc/base-plugins.js +13 -2
- package/dist-tsc/base-plugins.js.map +1 -1
- package/dist-tsc/index.d.ts +1 -0
- package/dist-tsc/index.d.ts.map +1 -1
- package/dist-tsc/index.js +1 -0
- package/dist-tsc/index.js.map +1 -1
- package/dist-tsc/joint-file-types-legacy.d.ts +18 -18
- package/dist-tsc/joint-file-types-legacy.d.ts.map +1 -1
- package/package.json +34 -33
- package/src/base-plugins.ts +14 -0
- package/src/index.ts +7 -0
|
@@ -8,7 +8,7 @@ var __privateSet = (obj, member, value2, setter2) => (__accessCheck(obj, member,
|
|
|
8
8
|
var _inner;
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
import React__default, { useContext, forwardRef as forwardRef$1, useRef, useMemo as useMemo$1, createContext as createContext$1, createElement, isValidElement, cloneElement, Children, PureComponent, useEffect, useState, version as version$6, useLayoutEffect as useLayoutEffect$1, useImperativeHandle, Component as Component$1, useCallback, useDeferredValue, Suspense, useReducer } from "react";
|
|
11
|
-
import { useLoaders, useCoordinationScopes, useCoordination, useDescription, useImageData, useReady, TitleInfo, useVitessceContainer, useSetWarning, useObsSetsData, useUrls, usePlotOptionsStyles, OptionsContainer, CellColorEncodingOption, OptionSelect, useComponentHover, useComponentViewInfo, useSetComponentHover, useSetComponentViewInfo, useInitialCoordination, useDeckCanvasSize, useMultiObsLabels, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useFeatureLabelsData, useExpandedFeatureLabelsMap, useSampleSetsData, useSampleEdgesData, useGetObsInfo, useUint8FeatureSelection, useExpressionValueGetter, useAuxiliaryCoordination, useHasLoader, useObsLocationsData, useObsLabelsData, useObsSegmentationsData, useNeighborhoodsData, useMergeCoordination, useCoordinationScopesBy, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationScopesNonNull, useComplexCoordination, useComplexCoordinationSecondary, useGridItemSize, useMultiObsPoints, usePointMultiObsLabels, usePointMultiObsFeatureMatrixIndices, useMultiObsSpots, useSpotMultiObsSets, useSpotMultiFeatureLabels, useSpotMultiFeatureSelection, useSpotMultiObsFeatureMatrixIndices, useSegmentationMultiObsLocations, useMultiObsSegmentations, useSegmentationMultiObsSets, useSegmentationMultiFeatureSelection, useSegmentationMultiObsFeatureMatrixIndices, useMultiImages, useObsFeatureMatrixData, useUint8ObsFeatureMatrix, useGetObsMembership, PopperMenu, useComponentLayout, useClosestVitessceContainerSize, useWindowDimensions, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes, useViewConfigStoreApi, useViewConfig, useSetViewConfig, createLoaders, useWarning, useGenomicProfilesData, shallowDiff, shallowDiffByChannelWithKeys, shallowDiffByLayer, shallowDiffByChannelCoordinationWithKeys, shallowDiffByChannel, shallowDiffByLayerCoordinationWithKeys, useMemoCustomComparison, useSegmentationMultiObsColors, useMatchingLoader, useColumnNameMapping, useFeatureStatsData, useObsSetStatsData, useAsyncFunction, useFeatureSetStatsData, useMultiCoordinationScopes, useComparisonMetadata, logConfig, VitSContainer } from "@vitessce/vit-s";
|
|
11
|
+
import { useLoaders, useCoordinationScopes, useCoordination, useDescription, useImageData, useReady, TitleInfo, useVitessceContainer, useSetWarning, useObsSetsData, useUrls, usePlotOptionsStyles, OptionsContainer, CellColorEncodingOption, OptionSelect, useComponentHover, useComponentViewInfo, useViewMapping, useSetComponentHover, useSetComponentViewInfo, useAnnotationFrameCoordination, useInitialCoordination, useDeckCanvasSize, useAnnotationStoryData, useMultiObsLabels, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useFeatureLabelsData, useExpandedFeatureLabelsMap, useSampleSetsData, useSampleEdgesData, useGetObsInfo, useUint8FeatureSelection, useExpressionValueGetter, useAuxiliaryCoordination, useHasLoader, useObsLocationsData, useObsLabelsData, useObsSegmentationsData, useNeighborhoodsData, useMergeCoordination, useCoordinationScopesBy, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationScopesNonNull, useComplexCoordination, useComplexCoordinationSecondary, useGridItemSize, useMultiObsPoints, usePointMultiObsLabels, usePointMultiObsFeatureMatrixIndices, useMultiObsSpots, useSpotMultiObsSets, useSpotMultiFeatureLabels, useSpotMultiFeatureSelection, useSpotMultiObsFeatureMatrixIndices, useSegmentationMultiObsLocations, useMultiObsSegmentations, useSegmentationMultiObsSets, useSegmentationMultiFeatureSelection, useSegmentationMultiObsFeatureMatrixIndices, useMultiImages, useObsFeatureMatrixData, useUint8ObsFeatureMatrix, useGetObsMembership, PopperMenu, useComponentLayout, useClosestVitessceContainerSize, useWindowDimensions, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes, useViewConfigStoreApi, useViewConfig, useSetViewConfig, createLoaders, useWarning, useGenomicProfilesData, shallowDiff, shallowDiffByChannelWithKeys, shallowDiffByLayer, shallowDiffByChannelCoordinationWithKeys, shallowDiffByChannel, shallowDiffByLayerCoordinationWithKeys, useMemoCustomComparison, useSegmentationMultiObsColors, useMatchingLoader, useColumnNameMapping, useFeatureStatsData, useObsSetStatsData, useAsyncFunction, useFeatureSetStatsData, useMultiCoordinationScopes, useComparisonMetadata, logConfig, VitSContainer } from "@vitessce/vit-s";
|
|
12
12
|
import { jsx as jsx$1, jsxs, Fragment } from "react/jsx-runtime";
|
|
13
13
|
import * as ReactDOM from "react-dom";
|
|
14
14
|
import ReactDOM__default, { createPortal } from "react-dom";
|
|
@@ -4261,7 +4261,7 @@ const latestFileDefSchema = z.object({
|
|
|
4261
4261
|
options: fileOptionsSchema.optional(),
|
|
4262
4262
|
requestInit: requestInit.optional(),
|
|
4263
4263
|
// New: file def can have coordinationValues.
|
|
4264
|
-
coordinationValues: z.record(z.
|
|
4264
|
+
coordinationValues: z.record(z.any()).optional()
|
|
4265
4265
|
});
|
|
4266
4266
|
const datasetsSchema1_0_13 = z.array(z.object({
|
|
4267
4267
|
uid: z.string(),
|
|
@@ -4292,7 +4292,8 @@ const configSchema1_0_16 = configSchema1_0_13.extend({
|
|
|
4292
4292
|
h: z.number().int().optional(),
|
|
4293
4293
|
// Updates coordinationScopes and coordinationScopesBy
|
|
4294
4294
|
coordinationScopes: componentCoordinationScopes.optional(),
|
|
4295
|
-
coordinationScopesBy: componentCoordinationScopesBy.optional()
|
|
4295
|
+
coordinationScopesBy: componentCoordinationScopesBy.optional(),
|
|
4296
|
+
coordinationValues: z.record(z.any()).optional()
|
|
4296
4297
|
}))
|
|
4297
4298
|
});
|
|
4298
4299
|
const configSchema1_0_17 = configSchema1_0_16.extend({
|
|
@@ -9167,7 +9168,8 @@ const ViewType$1 = {
|
|
|
9167
9168
|
TREEMAP: "treemap",
|
|
9168
9169
|
SAMPLE_SET_PAIR_MANAGER: "sampleSetPairManager",
|
|
9169
9170
|
FEATURE_STATS_TABLE: "featureStatsTable",
|
|
9170
|
-
SINGLE_OBS_SET_SELECTOR: "singleObsSetSelector"
|
|
9171
|
+
SINGLE_OBS_SET_SELECTOR: "singleObsSetSelector",
|
|
9172
|
+
ANNOTATION_CONTROLLER: "annotationController"
|
|
9171
9173
|
};
|
|
9172
9174
|
const DataType$3 = {
|
|
9173
9175
|
OBS_LABELS: "obsLabels",
|
|
@@ -9188,7 +9190,8 @@ const DataType$3 = {
|
|
|
9188
9190
|
COMPARISON_METADATA: "comparisonMetadata",
|
|
9189
9191
|
FEATURE_STATS: "featureStats",
|
|
9190
9192
|
FEATURE_SET_STATS: "featureSetStats",
|
|
9191
|
-
OBS_SET_STATS: "obsSetStats"
|
|
9193
|
+
OBS_SET_STATS: "obsSetStats",
|
|
9194
|
+
ANNOTATION_STORY: "annotationStory"
|
|
9192
9195
|
};
|
|
9193
9196
|
const AsyncFunctionType = {
|
|
9194
9197
|
// String input (rather than Node input)
|
|
@@ -9220,6 +9223,7 @@ const FileType$1 = {
|
|
|
9220
9223
|
OBS_SETS_CSV: "obsSets.csv",
|
|
9221
9224
|
OBS_SETS_JSON: "obsSets.json",
|
|
9222
9225
|
SAMPLE_SETS_CSV: "sampleSets.csv",
|
|
9226
|
+
ANNOTATION_STORY_JSON: "annotationStory.json",
|
|
9223
9227
|
// OME-Zarr
|
|
9224
9228
|
IMAGE_OME_ZARR: "image.ome-zarr",
|
|
9225
9229
|
OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
|
|
@@ -9504,7 +9508,15 @@ const CoordinationType$1 = {
|
|
|
9504
9508
|
FEATURE_POINT_FOLD_CHANGE_THRESHOLD: "featurePointFoldChangeThreshold",
|
|
9505
9509
|
FEATURE_LABEL_FOLD_CHANGE_THRESHOLD: "featureLabelFoldChangeThreshold",
|
|
9506
9510
|
// Treemap
|
|
9507
|
-
HIERARCHY_LEVELS: "hierarchyLevels"
|
|
9511
|
+
HIERARCHY_LEVELS: "hierarchyLevels",
|
|
9512
|
+
// Annotation frames
|
|
9513
|
+
ANNOTATION_STORY: "annotationStory",
|
|
9514
|
+
ANNOTATION_FRAME_INDEX: "annotationFrameIndex",
|
|
9515
|
+
ANNOTATION_SHAPES: "annotationShapes",
|
|
9516
|
+
ANNOTATION_OVERLAY_VISIBLE: "annotationOverlayVisible",
|
|
9517
|
+
ANNOTATION_TRANSITION_DURATION: "annotationTransitionDuration",
|
|
9518
|
+
ANNOTATION_SEMANTIC_ZOOM: "annotationSemanticZoom",
|
|
9519
|
+
ANNOTATION_EDITABLE: "annotationEditable"
|
|
9508
9520
|
};
|
|
9509
9521
|
const STATUS$1 = {
|
|
9510
9522
|
SUCCESS: "success"
|
|
@@ -9536,7 +9548,8 @@ const ViewHelpMapping = {
|
|
|
9536
9548
|
SAMPLE_SET_PAIR_MANAGER: "Select pairs of sample groups.",
|
|
9537
9549
|
FEATURE_STATS_TABLE: "This table displays per-feature statistics, for example, from a differential expression test.",
|
|
9538
9550
|
LAYER_CONTROLLER_BETA: "The spatial layer controller provides an interface for manipulating the visualization layers displayed in the spatial view.",
|
|
9539
|
-
SPATIAL_BETA: "The spatial view displays (potentially layered) spatially-resolved data including RGB or multiplexed images, segmentations of observations (bitmask- or polygon-based), and/or points (e.g., representing FISH transcripts)."
|
|
9551
|
+
SPATIAL_BETA: "The spatial view displays (potentially layered) spatially-resolved data including RGB or multiplexed images, segmentations of observations (bitmask- or polygon-based), and/or points (e.g., representing FISH transcripts).",
|
|
9552
|
+
ANNOTATION_CONTROLLER: "The annotation controller displays a guided sequence of narrative frames, each with descriptive text and optional shapes (rectangles, lines, arrows, ellipses, or polygons)."
|
|
9540
9553
|
};
|
|
9541
9554
|
({
|
|
9542
9555
|
// For new file types
|
|
@@ -9552,6 +9565,7 @@ const ViewHelpMapping = {
|
|
|
9552
9565
|
[FileType$1.OBS_SEGMENTATIONS_JSON]: DataType$3.OBS_SEGMENTATIONS,
|
|
9553
9566
|
[FileType$1.OBS_SETS_CSV]: DataType$3.OBS_SETS,
|
|
9554
9567
|
[FileType$1.OBS_SETS_JSON]: DataType$3.OBS_SETS,
|
|
9568
|
+
[FileType$1.ANNOTATION_STORY_JSON]: DataType$3.ANNOTATION_STORY,
|
|
9555
9569
|
[FileType$1.IMAGE_OME_ZARR]: DataType$3.IMAGE,
|
|
9556
9570
|
[FileType$1.OBS_SEGMENTATIONS_OME_ZARR]: DataType$3.OBS_SEGMENTATIONS,
|
|
9557
9571
|
[FileType$1.OBS_FEATURE_MATRIX_ANNDATA_ZARR]: DataType$3.OBS_FEATURE_MATRIX,
|
|
@@ -9674,7 +9688,8 @@ const ViewHelpMapping = {
|
|
|
9674
9688
|
[DataType$3.OBS_SET_STATS]: [
|
|
9675
9689
|
CoordinationType$1.OBS_TYPE
|
|
9676
9690
|
// TODO: should sampleType, obsSetSelection, and/or sampleSetSelection be used here?
|
|
9677
|
-
]
|
|
9691
|
+
],
|
|
9692
|
+
[DataType$3.ANNOTATION_STORY]: []
|
|
9678
9693
|
});
|
|
9679
9694
|
const ALT_ZARR_STORE_TYPES = {
|
|
9680
9695
|
// For AnnData:
|
|
@@ -9807,7 +9822,9 @@ const ALT_ZARR_STORE_TYPES = {
|
|
|
9807
9822
|
CoordinationType$1.SPATIAL_TARGET_Z,
|
|
9808
9823
|
CoordinationType$1.SPATIAL_AXIS_FIXED,
|
|
9809
9824
|
CoordinationType$1.SPATIAL_ORBIT_AXIS,
|
|
9810
|
-
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY
|
|
9825
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
9826
|
+
// Annotation shapes are specific to a view's coordinate system.
|
|
9827
|
+
CoordinationType$1.ANNOTATION_SHAPES
|
|
9811
9828
|
];
|
|
9812
9829
|
const COMPONENT_COORDINATION_TYPES = {
|
|
9813
9830
|
[ViewType$1.NEUROGLANCER]: [
|
|
@@ -9899,7 +9916,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
9899
9916
|
CoordinationType$1.EMBEDDING_CONTOURS_FILLED,
|
|
9900
9917
|
CoordinationType$1.EMBEDDING_CONTOUR_PERCENTILES,
|
|
9901
9918
|
CoordinationType$1.CONTOUR_COLOR_ENCODING,
|
|
9902
|
-
CoordinationType$1.CONTOUR_COLOR
|
|
9919
|
+
CoordinationType$1.CONTOUR_COLOR,
|
|
9920
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
9921
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
9922
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
9923
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
9924
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
9925
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
9926
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
9903
9927
|
],
|
|
9904
9928
|
[ViewType$1.DUAL_SCATTERPLOT]: [
|
|
9905
9929
|
CoordinationType$1.DATASET,
|
|
@@ -10015,7 +10039,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10015
10039
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
10016
10040
|
CoordinationType$1.MOLECULE_HIGHLIGHT,
|
|
10017
10041
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
10018
|
-
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
10042
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
|
|
10043
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10044
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10045
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10046
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10047
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10048
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10049
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10019
10050
|
],
|
|
10020
10051
|
[ViewType$1.SPATIAL_BETA]: [
|
|
10021
10052
|
CoordinationType$1.META_COORDINATION_SCOPES,
|
|
@@ -10093,7 +10124,27 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10093
10124
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
10094
10125
|
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
10095
10126
|
CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER,
|
|
10096
|
-
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
10127
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
|
|
10128
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10129
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10130
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10131
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10132
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10133
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10134
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10135
|
+
],
|
|
10136
|
+
[ViewType$1.ANNOTATION_CONTROLLER]: [
|
|
10137
|
+
CoordinationType$1.DATASET,
|
|
10138
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10139
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10140
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10141
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10142
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10143
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10144
|
+
// Note: the annotation controller also needs to read the coordination state
|
|
10145
|
+
// of all other views/coordination types via the full config.
|
|
10146
|
+
// Note: we get/set the CoordinationType.ANNOTATION_SHAPES from the full config,
|
|
10147
|
+
// as this info is view-specific rather than global to the story.
|
|
10097
10148
|
],
|
|
10098
10149
|
[ViewType$1.HEATMAP]: [
|
|
10099
10150
|
CoordinationType$1.DATASET,
|
|
@@ -11193,6 +11244,124 @@ const moleculesLayerObj = z.object({
|
|
|
11193
11244
|
radius: z.number(),
|
|
11194
11245
|
opacity: z.number()
|
|
11195
11246
|
});
|
|
11247
|
+
const shapeBaseObj = z.object({
|
|
11248
|
+
uid: z.string(),
|
|
11249
|
+
text: z.string().optional(),
|
|
11250
|
+
strokeColor: z.array(z.number()).length(3).optional(),
|
|
11251
|
+
strokeWidth: z.number().optional(),
|
|
11252
|
+
// SVG-style dash pattern, e.g. "10 5" or "10 20 30 10". "none" or omitted = solid.
|
|
11253
|
+
strokeDashArray: z.string().optional(),
|
|
11254
|
+
visible: z.boolean().optional()
|
|
11255
|
+
// TODO: define unit modes for x and y axes
|
|
11256
|
+
// ("pixels" vs "normalized" vs "physical" etc.)
|
|
11257
|
+
// TODO: a coordinate system identifier (e.g., "DeckGL" for now,
|
|
11258
|
+
// but a coordinate system from OME-NGFF/SpatialData eventually?)
|
|
11259
|
+
});
|
|
11260
|
+
const rectangleShapeObj = shapeBaseObj.extend({
|
|
11261
|
+
type: z.literal("rectangle"),
|
|
11262
|
+
// OME-XML field names verbatim (upper-left origin)
|
|
11263
|
+
x: z.number(),
|
|
11264
|
+
y: z.number(),
|
|
11265
|
+
width: z.number(),
|
|
11266
|
+
height: z.number(),
|
|
11267
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11268
|
+
fillOpacity: z.number().optional()
|
|
11269
|
+
});
|
|
11270
|
+
const lineShapeObj = shapeBaseObj.extend({
|
|
11271
|
+
type: z.literal("line"),
|
|
11272
|
+
// OME-XML field names verbatim
|
|
11273
|
+
x1: z.number(),
|
|
11274
|
+
y1: z.number(),
|
|
11275
|
+
x2: z.number(),
|
|
11276
|
+
y2: z.number(),
|
|
11277
|
+
markerStart: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11278
|
+
markerEnd: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11279
|
+
textPosition: z.enum(["start", "middle", "end"]).optional(),
|
|
11280
|
+
textBufferPx: z.number().optional()
|
|
11281
|
+
});
|
|
11282
|
+
const ellipseShapeObj = shapeBaseObj.extend({
|
|
11283
|
+
type: z.literal("ellipse"),
|
|
11284
|
+
// OME-XML field names verbatim (centre point + radii)
|
|
11285
|
+
x1: z.number(),
|
|
11286
|
+
y1: z.number(),
|
|
11287
|
+
radiusX: z.number(),
|
|
11288
|
+
radiusY: z.number(),
|
|
11289
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11290
|
+
fillOpacity: z.number().optional()
|
|
11291
|
+
});
|
|
11292
|
+
const polygonShapeObj = shapeBaseObj.extend({
|
|
11293
|
+
type: z.literal("polygon"),
|
|
11294
|
+
// OME-XML: array of [x, y] coordinate pairs, closed automatically
|
|
11295
|
+
points: z.array(z.tuple([z.number(), z.number()])),
|
|
11296
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11297
|
+
fillOpacity: z.number().optional()
|
|
11298
|
+
});
|
|
11299
|
+
const polylineShapeObj = shapeBaseObj.extend({
|
|
11300
|
+
type: z.literal("polyline"),
|
|
11301
|
+
// OME-XML: array of [x, y] coordinate pairs, open (not closed)
|
|
11302
|
+
points: z.array(z.tuple([z.number(), z.number()])),
|
|
11303
|
+
markerStart: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11304
|
+
markerEnd: z.enum(["Arrow", "Tick"]).nullable().optional()
|
|
11305
|
+
});
|
|
11306
|
+
const annotationShapeObj = z.discriminatedUnion("type", [
|
|
11307
|
+
rectangleShapeObj,
|
|
11308
|
+
lineShapeObj,
|
|
11309
|
+
ellipseShapeObj,
|
|
11310
|
+
polygonShapeObj,
|
|
11311
|
+
polylineShapeObj
|
|
11312
|
+
]);
|
|
11313
|
+
const annotationShapesArray = z.array(annotationShapeObj);
|
|
11314
|
+
const annotationFrameObj = z.object({
|
|
11315
|
+
uid: z.string(),
|
|
11316
|
+
title: z.string().optional(),
|
|
11317
|
+
description: z.string().optional(),
|
|
11318
|
+
descriptionType: z.enum(["text", "markdown"]).optional(),
|
|
11319
|
+
// A frame can define per-view: coordinationValues
|
|
11320
|
+
// (if the view's state should not be coordinated with other views)
|
|
11321
|
+
// or per-view coordinationScopes/coordinationScopesBy
|
|
11322
|
+
// (if at this frame, the view should be coordinated with other views).
|
|
11323
|
+
// We can also define a frame-level coordination space,
|
|
11324
|
+
// which will be merged with the global coordination space.
|
|
11325
|
+
// TODO: datasets
|
|
11326
|
+
// TODO: coordinationSpace
|
|
11327
|
+
layout: z.array(
|
|
11328
|
+
// Note: for now, we will infer view objects which have a uid
|
|
11329
|
+
// that is present in the global layout, and do NOT have x/y/w/h defined,
|
|
11330
|
+
// to mean that in this frame, the layout and set of views is unchanged
|
|
11331
|
+
// from the global layout.
|
|
11332
|
+
// This will allow each frame to omit the full list of views from the layout,
|
|
11333
|
+
// and only specify the views whose coordination state is changing in this frame.
|
|
11334
|
+
// If a frame includes a view with a uid that is not present
|
|
11335
|
+
// in the global layout, then that view will be added to the layout at this frame.
|
|
11336
|
+
// This frame should also define x/y/w/h for all views,
|
|
11337
|
+
// since it will otherwise be ambiguous how to layout the updated set of views
|
|
11338
|
+
// for this frame.
|
|
11339
|
+
z.object({
|
|
11340
|
+
// The view UID. If this view uid is not present in the global layout,
|
|
11341
|
+
// it will be added to the layout at this frame,
|
|
11342
|
+
// and will need to have its coordination values initialized to their defaults
|
|
11343
|
+
// for any that were not fully specified.
|
|
11344
|
+
uid: z.string(),
|
|
11345
|
+
coordinationValues: z.record(
|
|
11346
|
+
z.string(),
|
|
11347
|
+
// The coordination type name, e.g. "embeddingType"
|
|
11348
|
+
z.any()
|
|
11349
|
+
).optional()
|
|
11350
|
+
// TODO: support coordinationScopes/coordinationScopesBy for per-view coordination
|
|
11351
|
+
// at this frame.
|
|
11352
|
+
// TODO: view x/y/w/h once we support view layout changes per-frame.
|
|
11353
|
+
})
|
|
11354
|
+
).optional()
|
|
11355
|
+
});
|
|
11356
|
+
const annotationStoryObj = z.object({
|
|
11357
|
+
// TODO: schema version for the story schema?
|
|
11358
|
+
// Same as current Vitessce schema version?
|
|
11359
|
+
uid: z.string(),
|
|
11360
|
+
title: z.string().optional(),
|
|
11361
|
+
description: z.string().optional(),
|
|
11362
|
+
descriptionType: z.enum(["text", "markdown"]).optional(),
|
|
11363
|
+
frames: z.array(annotationFrameObj)
|
|
11364
|
+
});
|
|
11196
11365
|
class PluginViewType {
|
|
11197
11366
|
name;
|
|
11198
11367
|
component;
|
|
@@ -18426,7 +18595,7 @@ const { tss } = createTss({
|
|
|
18426
18595
|
},
|
|
18427
18596
|
"usePlugin": useMuiThemeStyleOverridesPlugin
|
|
18428
18597
|
});
|
|
18429
|
-
const useStyles$
|
|
18598
|
+
const useStyles$A = tss.create({});
|
|
18430
18599
|
function createChainedFunction$1(...funcs) {
|
|
18431
18600
|
return funcs.reduce((acc, func) => {
|
|
18432
18601
|
if (func == null) {
|
|
@@ -19537,7 +19706,7 @@ var values$5 = Object.values || function(obj) {
|
|
|
19537
19706
|
return obj[k];
|
|
19538
19707
|
});
|
|
19539
19708
|
};
|
|
19540
|
-
var defaultProps$
|
|
19709
|
+
var defaultProps$R = {
|
|
19541
19710
|
component: "div",
|
|
19542
19711
|
childFactory: function childFactory(child) {
|
|
19543
19712
|
return child;
|
|
@@ -19664,7 +19833,7 @@ TransitionGroup.propTypes = {
|
|
|
19664
19833
|
*/
|
|
19665
19834
|
childFactory: _pt.func
|
|
19666
19835
|
};
|
|
19667
|
-
TransitionGroup.defaultProps = defaultProps$
|
|
19836
|
+
TransitionGroup.defaultProps = defaultProps$R;
|
|
19668
19837
|
const UNINITIALIZED = {};
|
|
19669
19838
|
function useLazyRef(init2, initArg) {
|
|
19670
19839
|
const ref2 = React.useRef(UNINITIALIZED);
|
|
@@ -45818,6 +45987,12 @@ InputAdornment$1.propTypes = {
|
|
|
45818
45987
|
const AddIcon = createSvgIcon(/* @__PURE__ */ jsx$1("path", {
|
|
45819
45988
|
d: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z"
|
|
45820
45989
|
}), "Add");
|
|
45990
|
+
const ArrowRight = createSvgIcon(/* @__PURE__ */ jsx$1("path", {
|
|
45991
|
+
d: "m10 17 5-5-5-5z"
|
|
45992
|
+
}), "ArrowRight");
|
|
45993
|
+
const ArrowLeft = createSvgIcon(/* @__PURE__ */ jsx$1("path", {
|
|
45994
|
+
d: "m14 7-5 5 5 5z"
|
|
45995
|
+
}), "ArrowLeft");
|
|
45821
45996
|
const CenterFocusStrong = createSvgIcon(/* @__PURE__ */ jsx$1("path", {
|
|
45822
45997
|
d: "M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4m-7 7H3v4c0 1.1.9 2 2 2h4v-2H5zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2m0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2z"
|
|
45823
45998
|
}), "CenterFocusStrong");
|
|
@@ -72714,7 +72889,7 @@ const Popper = React.forwardRef((props, ref2) => {
|
|
|
72714
72889
|
}, [handlePopperRef]);
|
|
72715
72890
|
React.useImperativeHandle(popperRefProp, () => popperRef.current, []);
|
|
72716
72891
|
const [exited, setExited] = React.useState(true);
|
|
72717
|
-
const { theme } = useStyles$
|
|
72892
|
+
const { theme } = useStyles$A();
|
|
72718
72893
|
const rtlPlacement = flipPlacement(initialPlacement, theme);
|
|
72719
72894
|
const [placement, setPlacement] = React.useState(rtlPlacement);
|
|
72720
72895
|
React.useEffect(() => {
|
|
@@ -73448,7 +73623,7 @@ var VariableSizeList$1 = /* @__PURE__ */ createListComponent({
|
|
|
73448
73623
|
});
|
|
73449
73624
|
const VariableSizeList = VariableSizeList$1;
|
|
73450
73625
|
const LIST_ROW_HEIGHT$1 = 48;
|
|
73451
|
-
const useStyles$
|
|
73626
|
+
const useStyles$z = makeStyles()(() => ({
|
|
73452
73627
|
searchInput: {
|
|
73453
73628
|
lineHeight: "initial",
|
|
73454
73629
|
height: "auto !important"
|
|
@@ -73488,7 +73663,7 @@ const ListboxComponent$1 = React__default.forwardRef((props, ref2) => {
|
|
|
73488
73663
|
});
|
|
73489
73664
|
function SimpleAutocomplete(props) {
|
|
73490
73665
|
const { getMatches, onChange, textInputLabel = "Enter a gene", getItemLabel = (option) => option.label } = props;
|
|
73491
|
-
const { classes: classes2 } = useStyles$
|
|
73666
|
+
const { classes: classes2 } = useStyles$z();
|
|
73492
73667
|
const [potentialItems, setPotentialItems] = useState([]);
|
|
73493
73668
|
const handleInputChange = async (_event, value2) => {
|
|
73494
73669
|
if (!value2) {
|
|
@@ -83038,7 +83213,7 @@ function defaultUrlTransform(value2) {
|
|
|
83038
83213
|
}
|
|
83039
83214
|
return "";
|
|
83040
83215
|
}
|
|
83041
|
-
const useStyles$
|
|
83216
|
+
const useStyles$y = makeStyles()((theme) => ({
|
|
83042
83217
|
description: {
|
|
83043
83218
|
"& p, details, table": {
|
|
83044
83219
|
fontSize: "80%",
|
|
@@ -83075,7 +83250,7 @@ const useStyles$x = makeStyles()((theme) => ({
|
|
|
83075
83250
|
}));
|
|
83076
83251
|
function Description(props) {
|
|
83077
83252
|
const { description: description2, metadata: metadata2, descriptionType } = props;
|
|
83078
|
-
const { classes: classes2 } = useStyles$
|
|
83253
|
+
const { classes: classes2 } = useStyles$y();
|
|
83079
83254
|
return jsxs("div", { className: classes2.description, children: [descriptionType && descriptionType === DescriptionType.MARKDOWN ? jsx$1(Markdown, { children: description2 }) : jsx$1("p", { children: description2 }), metadata2 && Array.from(metadata2.entries()).map(([layerIndex, { name: layerName, metadata: metadataRecord }]) => metadataRecord && Object.entries(metadataRecord).length > 0 ? jsxs("details", { children: [jsx$1("summary", { children: layerName }), jsx$1("div", { className: classes2.metadataContainer, children: jsx$1("table", { children: jsx$1("tbody", { children: Object.entries(metadataRecord).map(([key2, value2]) => jsxs("tr", { children: [jsx$1("th", { title: key2, children: key2 }), jsx$1("td", { title: value2, children: value2 })] }, key2)) }) }) })] }, layerIndex) : null)] });
|
|
83080
83255
|
}
|
|
83081
83256
|
function DescriptionSubscriber(props) {
|
|
@@ -93697,7 +93872,7 @@ const Tooltip$2 = /* @__PURE__ */ React.forwardRef((props, ref2) => {
|
|
|
93697
93872
|
}, extraProps), getChildren());
|
|
93698
93873
|
});
|
|
93699
93874
|
const nodeHeight = 32;
|
|
93700
|
-
const useStyles$
|
|
93875
|
+
const useStyles$x = makeStyles()((theme) => ({
|
|
93701
93876
|
setsManager: {
|
|
93702
93877
|
position: "relative",
|
|
93703
93878
|
width: "100%",
|
|
@@ -93864,7 +94039,7 @@ const useStyles$w = makeStyles()((theme) => ({
|
|
|
93864
94039
|
}));
|
|
93865
94040
|
function SetsManagerTreeGlobalStyles(props) {
|
|
93866
94041
|
const { classes: classes2 } = props;
|
|
93867
|
-
const { theme } = useStyles$
|
|
94042
|
+
const { theme } = useStyles$A();
|
|
93868
94043
|
return jsx$1(ScopedGlobalStyles, { parentClassName: classes2.setsManagerTree, styles: {
|
|
93869
94044
|
".rc-tree": {
|
|
93870
94045
|
paddingLeft: "0",
|
|
@@ -94205,7 +94380,7 @@ function HelpTooltipGlobalStyles(props) {
|
|
|
94205
94380
|
}
|
|
94206
94381
|
function PopoverGlobalStyles(props) {
|
|
94207
94382
|
const { classes: classes2 } = props;
|
|
94208
|
-
const { theme } = useStyles$
|
|
94383
|
+
const { theme } = useStyles$A();
|
|
94209
94384
|
return jsx$1(ScopedGlobalStyles, { parentClassName: classes2.popover, styles: {
|
|
94210
94385
|
".rc-tooltip-inner": {
|
|
94211
94386
|
boxSizing: "border-box",
|
|
@@ -98889,7 +99064,7 @@ function NamedSetNodeStatic(props) {
|
|
|
98889
99064
|
const onClick = level === 0 && !expanded ? () => onCheckLevel(nodeKey, nextLevelToCheck) : () => onNodeView(path2);
|
|
98890
99065
|
const tooltipProps = disableTooltip ? { visible: false } : {};
|
|
98891
99066
|
const popoverMenuConfig = makeNodeViewMenuConfig(props);
|
|
98892
|
-
const { classes: classes2 } = useStyles$
|
|
99067
|
+
const { classes: classes2 } = useStyles$x();
|
|
98893
99068
|
return jsxs("span", { children: [jsx$1(HelpTooltip, { title: tooltipText, ...tooltipProps, children: jsx$1("button", { type: "button", onClick, onKeyPress: (e3) => callbackOnKeyPress(e3, "v", () => onNodeView(path2)), className: classes2.titleButton, children: title2 }) }), popoverMenuConfig.length > 0 ? jsx$1(PopoverMenu, { menuConfig: makeNodeViewMenuConfig(props), color: level > 0 && editable ? color2 || getDefaultColor(theme) : null, setColor: (c2) => onNodeSetColor(path2, c2), children: jsx$1("span", { children: jsx$1(SvgMenu, { className: classes2.nodeMenuIcon, "aria-label": "Open Node View Menu" }) }) }) : null, level > 0 && isChecking ? checkbox2 : null, level > 0 && jsx$1("span", { className: classes2.nodeSizeLabel, children: niceSize })] });
|
|
98894
99069
|
}
|
|
98895
99070
|
function NamedSetNodeEditing(props) {
|
|
@@ -98901,7 +99076,7 @@ function NamedSetNodeEditing(props) {
|
|
|
98901
99076
|
onNodeSetName(path2, currentTitle, true);
|
|
98902
99077
|
}
|
|
98903
99078
|
}
|
|
98904
|
-
const { classes: classes2 } = useStyles$
|
|
99079
|
+
const { classes: classes2 } = useStyles$x();
|
|
98905
99080
|
return jsxs("span", { className: classes2.titleButtonWithInput, children: [jsx$1("input", {
|
|
98906
99081
|
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
98907
99082
|
autoFocus: true,
|
|
@@ -98927,7 +99102,7 @@ function LevelsButtons(props) {
|
|
|
98927
99102
|
onCheckLevel(nodeKey, newLevel);
|
|
98928
99103
|
}
|
|
98929
99104
|
}
|
|
98930
|
-
const { classes: classes2 } = useStyles$
|
|
99105
|
+
const { classes: classes2 } = useStyles$x();
|
|
98931
99106
|
return jsx$1("div", { className: classes2.levelButtonsContainer, children: range$e(1, height2 + 1).map((i2) => {
|
|
98932
99107
|
const isChecked = isEqual$3(path2, checkedLevelPath) && i2 === checkedLevelIndex;
|
|
98933
99108
|
return jsx$1("div", { children: jsx$1(HelpTooltip, { title: getLevelTooltipText(i2), children: jsx$1("input", { className: clsx(classes2.levelRadioButton, { [classes2.levelRadioButtonChecked]: isChecked && !hasColorEncoding }), type: "checkbox", value: i2, checked: isChecked && hasColorEncoding, onChange: onCheck }) }) }, i2);
|
|
@@ -99011,7 +99186,7 @@ let TreeNode$1 = class TreeNode extends TreeNode$2 {
|
|
|
99011
99186
|
};
|
|
99012
99187
|
function PlusButton(props) {
|
|
99013
99188
|
const { datatype, onError, onImportTree, onCreateLevelZeroNode, importable, editable } = props;
|
|
99014
|
-
const { classes: classes2 } = useStyles$
|
|
99189
|
+
const { classes: classes2 } = useStyles$x();
|
|
99015
99190
|
const onImport = useCallback((importHandler, mimeType) => () => {
|
|
99016
99191
|
const uploadInputNode = document.createElement("input");
|
|
99017
99192
|
uploadInputNode.setAttribute("type", "file");
|
|
@@ -99128,7 +99303,7 @@ function SetsManager(props) {
|
|
|
99128
99303
|
}, onNodeCheckNewName, onNodeSetIsEditing: setIsEditingNodeName, onNodeRemove, onExportLevelZeroNodeJSON, onExportLevelZeroNodeTabular, onExportSetJSON, disableTooltip: isDragging, onDragStart: () => setIsDragging(true), onDragEnd: () => setIsDragging(false), children: renderTreeNodes(node2.children, readOnly, newPath) }, pathToKey$1(newPath));
|
|
99129
99304
|
});
|
|
99130
99305
|
}
|
|
99131
|
-
const { classes: classes2 } = useStyles$
|
|
99306
|
+
const { classes: classes2 } = useStyles$x();
|
|
99132
99307
|
return jsxs("div", { className: classes2.setsManager, children: [jsx$1(SetsManagerTreeGlobalStyles, { classes: classes2 }), jsxs("div", { className: classes2.setsManagerTree, children: [jsx$1(Tree$1, { draggable: false, checkable, checkedKeys: setSelectionKeys, expandedKeys: setExpansionKeys, autoExpandParent, onCheck: (checkedKeys, info2) => onCheckNode(info2.node.props.nodeKey, info2.checked), onExpand: (expandedKeys, info2) => onExpandNode(expandedKeys, info2.node.props.nodeKey, info2.expanded), children: renderTreeNodes(processedSets.tree, true, []) }), jsx$1(Tree$1, { draggable: true, checkable, checkedKeys: additionalSetSelectionKeys, expandedKeys: additionalSetExpansionKeys, autoExpandParent, onCheck: (checkedKeys, info2) => onCheckNode(info2.node.props.nodeKey, info2.checked), onExpand: (expandedKeys, info2) => onExpandNode(expandedKeys, info2.node.props.nodeKey, info2.expanded), onDrop: (info2) => {
|
|
99133
99308
|
const { eventKey: dropKey } = info2.node.props;
|
|
99134
99309
|
const { eventKey: dragKey } = info2.dragNode.props;
|
|
@@ -111499,6 +111674,12 @@ function multiply$4(out, a2, b2) {
|
|
|
111499
111674
|
out[2] = a2[2] * b2[2];
|
|
111500
111675
|
return out;
|
|
111501
111676
|
}
|
|
111677
|
+
function distance$3(a2, b2) {
|
|
111678
|
+
var x2 = b2[0] - a2[0];
|
|
111679
|
+
var y2 = b2[1] - a2[1];
|
|
111680
|
+
var z2 = b2[2] - a2[2];
|
|
111681
|
+
return Math.hypot(x2, y2, z2);
|
|
111682
|
+
}
|
|
111502
111683
|
function squaredLength$2(a2) {
|
|
111503
111684
|
var x2 = a2[0];
|
|
111504
111685
|
var y2 = a2[1];
|
|
@@ -111622,6 +111803,7 @@ function angle$3(a2, b2) {
|
|
|
111622
111803
|
}
|
|
111623
111804
|
var sub$1 = subtract$1;
|
|
111624
111805
|
var mul$1 = multiply$4;
|
|
111806
|
+
var dist$1 = distance$3;
|
|
111625
111807
|
var len = length$5;
|
|
111626
111808
|
var sqrLen = squaredLength$2;
|
|
111627
111809
|
(function() {
|
|
@@ -126092,7 +126274,7 @@ function noop$9() {
|
|
|
126092
126274
|
const getCursor$1 = ({
|
|
126093
126275
|
isDragging
|
|
126094
126276
|
}) => isDragging ? "grabbing" : "grab";
|
|
126095
|
-
const defaultProps$
|
|
126277
|
+
const defaultProps$Q = {
|
|
126096
126278
|
id: "",
|
|
126097
126279
|
width: "100%",
|
|
126098
126280
|
height: "100%",
|
|
@@ -126223,7 +126405,7 @@ class Deck {
|
|
|
126223
126405
|
this._lastPointerDownInfo = pickedInfo.result[0] || pickedInfo.emptyInfo;
|
|
126224
126406
|
});
|
|
126225
126407
|
this.props = {
|
|
126226
|
-
...defaultProps$
|
|
126408
|
+
...defaultProps$Q,
|
|
126227
126409
|
...props
|
|
126228
126410
|
};
|
|
126229
126411
|
props = this.props;
|
|
@@ -126725,7 +126907,7 @@ class Deck {
|
|
|
126725
126907
|
metrics.gpuMemory = memoryStats.get("GPU Memory").count;
|
|
126726
126908
|
}
|
|
126727
126909
|
}
|
|
126728
|
-
_defineProperty$3(Deck, "defaultProps", defaultProps$
|
|
126910
|
+
_defineProperty$3(Deck, "defaultProps", defaultProps$Q);
|
|
126729
126911
|
_defineProperty$3(Deck, "VERSION", deckGlobal.VERSION);
|
|
126730
126912
|
class ShaderAttribute {
|
|
126731
126913
|
constructor(dataColumn, opts2) {
|
|
@@ -129480,7 +129662,7 @@ const areViewportsEqual = memoize$3(({
|
|
|
129480
129662
|
return oldViewport.equals(viewport2);
|
|
129481
129663
|
});
|
|
129482
129664
|
let pickingColorCache = new Uint8ClampedArray(0);
|
|
129483
|
-
const defaultProps$
|
|
129665
|
+
const defaultProps$P = {
|
|
129484
129666
|
data: {
|
|
129485
129667
|
type: "data",
|
|
129486
129668
|
value: EMPTY_ARRAY$1,
|
|
@@ -130355,7 +130537,7 @@ class Layer extends Component {
|
|
|
130355
130537
|
this.setNeedsUpdate();
|
|
130356
130538
|
}
|
|
130357
130539
|
}
|
|
130358
|
-
_defineProperty$3(Layer, "defaultProps", defaultProps$
|
|
130540
|
+
_defineProperty$3(Layer, "defaultProps", defaultProps$P);
|
|
130359
130541
|
_defineProperty$3(Layer, "layerName", "Layer");
|
|
130360
130542
|
const TRACE_RENDER_LAYERS = "compositeLayer.renderLayers";
|
|
130361
130543
|
class CompositeLayer extends Layer {
|
|
@@ -131514,7 +131696,7 @@ const parameters = {
|
|
|
131514
131696
|
blendEquation: [32774, 32774],
|
|
131515
131697
|
depthTest: false
|
|
131516
131698
|
};
|
|
131517
|
-
const defaultProps$
|
|
131699
|
+
const defaultProps$O = {
|
|
131518
131700
|
getFilterValue: {
|
|
131519
131701
|
type: "accessor",
|
|
131520
131702
|
value: 0
|
|
@@ -131690,8 +131872,126 @@ class DataFilterExtension extends LayerExtension {
|
|
|
131690
131872
|
}
|
|
131691
131873
|
}
|
|
131692
131874
|
}
|
|
131693
|
-
_defineProperty$3(DataFilterExtension, "defaultProps", defaultProps$
|
|
131875
|
+
_defineProperty$3(DataFilterExtension, "defaultProps", defaultProps$O);
|
|
131694
131876
|
_defineProperty$3(DataFilterExtension, "extensionName", "DataFilterExtension");
|
|
131877
|
+
const dashShaders = {
|
|
131878
|
+
inject: {
|
|
131879
|
+
"vs:#decl": "\nattribute vec2 instanceDashArrays;\nattribute float instanceDashOffsets;\nvarying vec2 vDashArray;\nvarying float vDashOffset;\n",
|
|
131880
|
+
"vs:#main-end": "\nvDashArray = instanceDashArrays;\nvDashOffset = instanceDashOffsets / width.x;\n",
|
|
131881
|
+
"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",
|
|
131882
|
+
"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"
|
|
131883
|
+
}
|
|
131884
|
+
};
|
|
131885
|
+
const offsetShaders = {
|
|
131886
|
+
inject: {
|
|
131887
|
+
"vs:#decl": "\nattribute float instanceOffsets;\n",
|
|
131888
|
+
"vs:DECKGL_FILTER_SIZE": "\n float offsetWidth = abs(instanceOffsets * 2.0) + 1.0;\n size *= offsetWidth;\n",
|
|
131889
|
+
"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",
|
|
131890
|
+
"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"
|
|
131891
|
+
}
|
|
131892
|
+
};
|
|
131893
|
+
const defaultProps$N = {
|
|
131894
|
+
getDashArray: {
|
|
131895
|
+
type: "accessor",
|
|
131896
|
+
value: [0, 0]
|
|
131897
|
+
},
|
|
131898
|
+
getOffset: {
|
|
131899
|
+
type: "accessor",
|
|
131900
|
+
value: 0
|
|
131901
|
+
},
|
|
131902
|
+
dashJustified: false,
|
|
131903
|
+
dashGapPickable: false
|
|
131904
|
+
};
|
|
131905
|
+
class PathStyleExtension extends LayerExtension {
|
|
131906
|
+
constructor({
|
|
131907
|
+
dash: dash2 = false,
|
|
131908
|
+
offset: offset2 = false,
|
|
131909
|
+
highPrecisionDash = false
|
|
131910
|
+
} = {}) {
|
|
131911
|
+
super({
|
|
131912
|
+
dash: dash2 || highPrecisionDash,
|
|
131913
|
+
offset: offset2,
|
|
131914
|
+
highPrecisionDash
|
|
131915
|
+
});
|
|
131916
|
+
}
|
|
131917
|
+
isEnabled(layer) {
|
|
131918
|
+
return "pathTesselator" in layer.state;
|
|
131919
|
+
}
|
|
131920
|
+
getShaders(extension2) {
|
|
131921
|
+
if (!extension2.isEnabled(this)) {
|
|
131922
|
+
return null;
|
|
131923
|
+
}
|
|
131924
|
+
let result = {};
|
|
131925
|
+
if (extension2.opts.dash) {
|
|
131926
|
+
result = mergeShaders(result, dashShaders);
|
|
131927
|
+
}
|
|
131928
|
+
if (extension2.opts.offset) {
|
|
131929
|
+
result = mergeShaders(result, offsetShaders);
|
|
131930
|
+
}
|
|
131931
|
+
return result;
|
|
131932
|
+
}
|
|
131933
|
+
initializeState(context2, extension2) {
|
|
131934
|
+
const attributeManager = this.getAttributeManager();
|
|
131935
|
+
if (!attributeManager || !extension2.isEnabled(this)) {
|
|
131936
|
+
return;
|
|
131937
|
+
}
|
|
131938
|
+
if (extension2.opts.dash) {
|
|
131939
|
+
attributeManager.addInstanced({
|
|
131940
|
+
instanceDashArrays: {
|
|
131941
|
+
size: 2,
|
|
131942
|
+
accessor: "getDashArray"
|
|
131943
|
+
}
|
|
131944
|
+
});
|
|
131945
|
+
}
|
|
131946
|
+
if (extension2.opts.highPrecisionDash) {
|
|
131947
|
+
attributeManager.addInstanced({
|
|
131948
|
+
instanceDashOffsets: {
|
|
131949
|
+
size: 1,
|
|
131950
|
+
accessor: "getPath",
|
|
131951
|
+
transform: extension2.getDashOffsets.bind(this)
|
|
131952
|
+
}
|
|
131953
|
+
});
|
|
131954
|
+
}
|
|
131955
|
+
if (extension2.opts.offset) {
|
|
131956
|
+
attributeManager.addInstanced({
|
|
131957
|
+
instanceOffsets: {
|
|
131958
|
+
size: 1,
|
|
131959
|
+
accessor: "getOffset"
|
|
131960
|
+
}
|
|
131961
|
+
});
|
|
131962
|
+
}
|
|
131963
|
+
}
|
|
131964
|
+
updateState(params2, extension2) {
|
|
131965
|
+
if (!extension2.isEnabled(this)) {
|
|
131966
|
+
return;
|
|
131967
|
+
}
|
|
131968
|
+
const uniforms = {};
|
|
131969
|
+
if (extension2.opts.dash) {
|
|
131970
|
+
uniforms.dashAlignMode = this.props.dashJustified ? 1 : 0;
|
|
131971
|
+
uniforms.dashGapPickable = Boolean(this.props.dashGapPickable);
|
|
131972
|
+
}
|
|
131973
|
+
this.state.model.setUniforms(uniforms);
|
|
131974
|
+
}
|
|
131975
|
+
getDashOffsets(path2) {
|
|
131976
|
+
const result = [0];
|
|
131977
|
+
const positionSize = this.props.positionFormat === "XY" ? 2 : 3;
|
|
131978
|
+
const isNested2 = Array.isArray(path2[0]);
|
|
131979
|
+
const geometrySize = isNested2 ? path2.length : path2.length / positionSize;
|
|
131980
|
+
let p;
|
|
131981
|
+
let prevP;
|
|
131982
|
+
for (let i2 = 0; i2 < geometrySize - 1; i2++) {
|
|
131983
|
+
p = isNested2 ? path2[i2] : path2.slice(i2 * positionSize, i2 * positionSize + positionSize);
|
|
131984
|
+
p = this.projectPosition(p);
|
|
131985
|
+
if (i2 > 0) {
|
|
131986
|
+
result[i2] = result[i2 - 1] + dist$1(prevP, p);
|
|
131987
|
+
}
|
|
131988
|
+
prevP = p;
|
|
131989
|
+
}
|
|
131990
|
+
return result;
|
|
131991
|
+
}
|
|
131992
|
+
}
|
|
131993
|
+
_defineProperty$3(PathStyleExtension, "defaultProps", defaultProps$N);
|
|
131994
|
+
_defineProperty$3(PathStyleExtension, "extensionName", "PathStyleExtension");
|
|
131695
131995
|
const defaultProps$M = {
|
|
131696
131996
|
clipBounds: [0, 0, 1, 1]
|
|
131697
131997
|
};
|
|
@@ -205110,22 +205410,22 @@ async function getDecoder(fileDirectory) {
|
|
|
205110
205410
|
const Decoder = await importFn();
|
|
205111
205411
|
return new Decoder(fileDirectory);
|
|
205112
205412
|
}
|
|
205113
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
205114
|
-
addDecoder(5, () => import("./lzw-
|
|
205413
|
+
addDecoder([void 0, 1], () => import("./raw-CR3kVxsB.js").then((m2) => m2.default));
|
|
205414
|
+
addDecoder(5, () => import("./lzw-CIpLYaya.js").then((m2) => m2.default));
|
|
205115
205415
|
addDecoder(6, () => {
|
|
205116
205416
|
throw new Error("old style JPEG compression is not supported.");
|
|
205117
205417
|
});
|
|
205118
|
-
addDecoder(7, () => import("./jpeg-
|
|
205119
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
205120
|
-
addDecoder(32773, () => import("./packbits-
|
|
205418
|
+
addDecoder(7, () => import("./jpeg-DXSq15HV.js").then((m2) => m2.default));
|
|
205419
|
+
addDecoder([8, 32946], () => import("./deflate-BKJk_mLF.js").then((m2) => m2.default));
|
|
205420
|
+
addDecoder(32773, () => import("./packbits-Cf0TB9M_.js").then((m2) => m2.default));
|
|
205121
205421
|
addDecoder(
|
|
205122
205422
|
34887,
|
|
205123
|
-
() => import("./lerc-
|
|
205423
|
+
() => import("./lerc-uTsWAc7Y.js").then(async (m2) => {
|
|
205124
205424
|
await m2.zstd.init();
|
|
205125
205425
|
return m2;
|
|
205126
205426
|
}).then((m2) => m2.default)
|
|
205127
205427
|
);
|
|
205128
|
-
addDecoder(50001, () => import("./webimage-
|
|
205428
|
+
addDecoder(50001, () => import("./webimage-Dp3HLfwF.js").then((m2) => m2.default));
|
|
205129
205429
|
function copyNewSize(array2, width2, height2, samplesPerPixel = 1) {
|
|
205130
205430
|
return new (Object.getPrototypeOf(array2)).constructor(width2 * height2 * samplesPerPixel);
|
|
205131
205431
|
}
|
|
@@ -215621,7 +215921,7 @@ function padColors({ colors: colors2, channelsVisible }) {
|
|
|
215621
215921
|
).reduce((acc, val) => acc.concat(val), []);
|
|
215622
215922
|
return paddedColors;
|
|
215623
215923
|
}
|
|
215624
|
-
const defaultProps$3$
|
|
215924
|
+
const defaultProps$3$2 = {
|
|
215625
215925
|
colors: { type: "array", value: null, compare: true },
|
|
215626
215926
|
opacity: { type: "number", value: 1, compare: true },
|
|
215627
215927
|
transparentColor: { type: "array", value: null, compare: true },
|
|
@@ -215638,9 +215938,9 @@ const ColorPaletteExtension = class extends LayerExtension {
|
|
|
215638
215938
|
const {
|
|
215639
215939
|
colors: colors2,
|
|
215640
215940
|
channelsVisible,
|
|
215641
|
-
opacity: opacity2 = defaultProps$3$
|
|
215642
|
-
transparentColor = defaultProps$3$
|
|
215643
|
-
useTransparentColor = defaultProps$3$
|
|
215941
|
+
opacity: opacity2 = defaultProps$3$2.opacity.value,
|
|
215942
|
+
transparentColor = defaultProps$3$2.transparentColor.value,
|
|
215943
|
+
useTransparentColor = defaultProps$3$2.useTransparentColor.value
|
|
215644
215944
|
} = this.props;
|
|
215645
215945
|
const paddedColors = padColors({
|
|
215646
215946
|
channelsVisible: channelsVisible || this.selections.map(() => true),
|
|
@@ -215656,7 +215956,7 @@ const ColorPaletteExtension = class extends LayerExtension {
|
|
|
215656
215956
|
}
|
|
215657
215957
|
};
|
|
215658
215958
|
ColorPaletteExtension.extensionName = "ColorPaletteExtension";
|
|
215659
|
-
ColorPaletteExtension.defaultProps = defaultProps$3$
|
|
215959
|
+
ColorPaletteExtension.defaultProps = defaultProps$3$2;
|
|
215660
215960
|
const fs$4 = `// lens bounds for ellipse
|
|
215661
215961
|
uniform float majorLensAxis;
|
|
215662
215962
|
uniform float minorLensAxis;
|
|
@@ -216958,7 +217258,7 @@ const MultiscaleImageLayer = class extends CompositeLayer {
|
|
|
216958
217258
|
};
|
|
216959
217259
|
MultiscaleImageLayer.layerName = "MultiscaleImageLayer";
|
|
216960
217260
|
MultiscaleImageLayer.defaultProps = defaultProps$4;
|
|
216961
|
-
const defaultProps$3 = {
|
|
217261
|
+
const defaultProps$3$1 = {
|
|
216962
217262
|
pickable: { type: "boolean", value: true, compare: true },
|
|
216963
217263
|
loader: {
|
|
216964
217264
|
type: "object",
|
|
@@ -217045,7 +217345,7 @@ const OverviewLayer = class extends CompositeLayer {
|
|
|
217045
217345
|
}
|
|
217046
217346
|
};
|
|
217047
217347
|
OverviewLayer.layerName = "OverviewLayer";
|
|
217048
|
-
OverviewLayer.defaultProps = defaultProps$3;
|
|
217348
|
+
OverviewLayer.defaultProps = defaultProps$3$1;
|
|
217049
217349
|
function getPosition$1(boundingBox, position2, length2) {
|
|
217050
217350
|
const viewWidth2 = boundingBox[2][0] - boundingBox[0][0];
|
|
217051
217351
|
const viewHeight2 = boundingBox[2][1] - boundingBox[0][1];
|
|
@@ -218058,7 +218358,7 @@ function padWithDefault$1(arr, defaultValue2, padWidth) {
|
|
|
218058
218358
|
}
|
|
218059
218359
|
return newArr;
|
|
218060
218360
|
}
|
|
218061
|
-
const defaultProps$
|
|
218361
|
+
const defaultProps$3 = {
|
|
218062
218362
|
hoveredCell: { type: "number", value: null, compare: true },
|
|
218063
218363
|
// We do not want to deep-compare cellColorData,
|
|
218064
218364
|
// as it is potentially a TypedArray with millions of elements.
|
|
@@ -218175,7 +218475,7 @@ let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
|
|
|
218175
218475
|
}
|
|
218176
218476
|
};
|
|
218177
218477
|
BitmaskLayer$1.layerName = "BitmaskLayer";
|
|
218178
|
-
BitmaskLayer$1.defaultProps = defaultProps$
|
|
218478
|
+
BitmaskLayer$1.defaultProps = defaultProps$3;
|
|
218179
218479
|
const vs = `
|
|
218180
218480
|
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
218181
218481
|
|
|
@@ -218517,7 +218817,7 @@ function isEqualShallow(prevArr, nextArr) {
|
|
|
218517
218817
|
}
|
|
218518
218818
|
return prevArr === nextArr;
|
|
218519
218819
|
}
|
|
218520
|
-
const defaultProps$
|
|
218820
|
+
const defaultProps$2 = {
|
|
218521
218821
|
channelStrokeWidths: { type: "array", value: null, compare: true },
|
|
218522
218822
|
channelsFilled: { type: "array", value: null, compare: true },
|
|
218523
218823
|
channelOpacities: { type: "array", value: null, compare: true },
|
|
@@ -218781,7 +219081,7 @@ class BitmaskLayer2 extends XRLayer {
|
|
|
218781
219081
|
}
|
|
218782
219082
|
}
|
|
218783
219083
|
BitmaskLayer2.layerName = "BitmaskLayer";
|
|
218784
|
-
BitmaskLayer2.defaultProps = defaultProps$
|
|
219084
|
+
BitmaskLayer2.defaultProps = defaultProps$2;
|
|
218785
219085
|
var isNumeric$2 = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, mathceil = Math.ceil, mathfloor$1 = Math.floor, bignumberError = "[BigNumber Error] ", tooManyDigits = bignumberError + "Number primitive has more than 15 significant digits: ", BASE$1 = 1e14, LOG_BASE$1 = 14, MAX_SAFE_INTEGER$3 = 9007199254740991, POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], SQRT_BASE = 1e7, MAX$1 = 1e9;
|
|
218786
219086
|
function clone$3(configObject) {
|
|
218787
219087
|
var div2, convertBase2, parseNumeric, P2 = 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 = {
|
|
@@ -221724,7 +222024,7 @@ function ringArea(coords) {
|
|
|
221724
222024
|
return total * FACTOR;
|
|
221725
222025
|
}
|
|
221726
222026
|
const DEFAULT_THRESHOLD = 1;
|
|
221727
|
-
const defaultProps = {
|
|
222027
|
+
const defaultProps$1 = {
|
|
221728
222028
|
// for text
|
|
221729
222029
|
obsSetPath: { type: "object" },
|
|
221730
222030
|
sampleSetPath: { type: "object" },
|
|
@@ -221898,8 +222198,1078 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
221898
222198
|
}
|
|
221899
222199
|
}
|
|
221900
222200
|
ContourLayerWithText.layerName = "ContourLayerWithText";
|
|
221901
|
-
ContourLayerWithText.defaultProps = defaultProps;
|
|
221902
|
-
const
|
|
222201
|
+
ContourLayerWithText.defaultProps = defaultProps$1;
|
|
222202
|
+
const ARROW_SCREEN_PX = 14;
|
|
222203
|
+
const LABEL_FONT_FAMILY$1 = '"Roboto", "Helvetica", "Arial", sans-serif';
|
|
222204
|
+
const LABEL_FONT_WEIGHT = "bold";
|
|
222205
|
+
const LABEL_FONT_SIZE = 14;
|
|
222206
|
+
const RATIO_CLUSTER = 0.1;
|
|
222207
|
+
const RATIO_DOT = 0.3;
|
|
222208
|
+
const RATIO_GEO_FADE = 0.55;
|
|
222209
|
+
const RATIO_TIPS = 0.7;
|
|
222210
|
+
const RATIO_LABEL = 0.55;
|
|
222211
|
+
const RATIO_LABEL_FULL = 0.75;
|
|
222212
|
+
function textBgColor(strokeColor) {
|
|
222213
|
+
const [r3, g2, b2] = strokeColor;
|
|
222214
|
+
const lum = (0.299 * r3 + 0.587 * g2 + 0.114 * b2) / 255;
|
|
222215
|
+
return lum > 0.45 ? [20, 20, 20, 210] : [245, 245, 245, 210];
|
|
222216
|
+
}
|
|
222217
|
+
function parseDashArray(strokeDashArray) {
|
|
222218
|
+
if (!strokeDashArray || strokeDashArray === "none")
|
|
222219
|
+
return null;
|
|
222220
|
+
const nums = strokeDashArray.trim().split(/\s+/).map(Number).filter((n3) => !Number.isNaN(n3) && n3 >= 0);
|
|
222221
|
+
return nums.length >= 2 ? [nums[0], nums[1]] : null;
|
|
222222
|
+
}
|
|
222223
|
+
function computeEllipsePolygon(cx, cy, rx, ry, numSegments = 64) {
|
|
222224
|
+
const pts = [];
|
|
222225
|
+
for (let i2 = 0; i2 < numSegments; i2++) {
|
|
222226
|
+
const angle2 = 2 * Math.PI * i2 / numSegments;
|
|
222227
|
+
pts.push([cx + rx * Math.cos(angle2), cy + ry * Math.sin(angle2)]);
|
|
222228
|
+
}
|
|
222229
|
+
return pts;
|
|
222230
|
+
}
|
|
222231
|
+
function createPreviewLayer(inProgress, hoverCoord, strokeColor = [255, 255, 0]) {
|
|
222232
|
+
if (!inProgress || inProgress.vertices.length === 0)
|
|
222233
|
+
return null;
|
|
222234
|
+
const { type: type2, vertices } = inProgress;
|
|
222235
|
+
const base2 = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN };
|
|
222236
|
+
const previewColor = [...strokeColor, 160];
|
|
222237
|
+
const cursor2 = hoverCoord ?? vertices[vertices.length - 1];
|
|
222238
|
+
if (type2 === "rectangle" && vertices.length === 1) {
|
|
222239
|
+
const [ax, ay] = vertices[0];
|
|
222240
|
+
const [bx, by] = cursor2;
|
|
222241
|
+
const path2 = [[ax, ay], [bx, ay], [bx, by], [ax, by], [ax, ay]];
|
|
222242
|
+
return new PathLayer({
|
|
222243
|
+
...base2,
|
|
222244
|
+
id: "annotation-preview-rectangle",
|
|
222245
|
+
data: [{ path: path2 }],
|
|
222246
|
+
getPath: (d) => d.path,
|
|
222247
|
+
getColor: previewColor,
|
|
222248
|
+
getWidth: 1,
|
|
222249
|
+
widthUnits: "pixels",
|
|
222250
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
222251
|
+
getDashArray: [8, 4]
|
|
222252
|
+
});
|
|
222253
|
+
}
|
|
222254
|
+
if (type2 === "line" && vertices.length === 1) {
|
|
222255
|
+
const path2 = [vertices[0], cursor2];
|
|
222256
|
+
return new PathLayer({
|
|
222257
|
+
...base2,
|
|
222258
|
+
id: "annotation-preview-line",
|
|
222259
|
+
data: [{ path: path2 }],
|
|
222260
|
+
getPath: (d) => d.path,
|
|
222261
|
+
getColor: previewColor,
|
|
222262
|
+
getWidth: 1,
|
|
222263
|
+
widthUnits: "pixels",
|
|
222264
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
222265
|
+
getDashArray: [8, 4]
|
|
222266
|
+
});
|
|
222267
|
+
}
|
|
222268
|
+
if (type2 === "ellipse" && vertices.length === 1) {
|
|
222269
|
+
const [cx, cy] = vertices[0];
|
|
222270
|
+
const [ex, ey] = cursor2;
|
|
222271
|
+
const rx = Math.abs(ex - cx);
|
|
222272
|
+
const ry = Math.abs(ey - cy);
|
|
222273
|
+
if (rx < 1 && ry < 1)
|
|
222274
|
+
return null;
|
|
222275
|
+
const pts = computeEllipsePolygon(cx, cy, Math.max(rx, 1), Math.max(ry, 1));
|
|
222276
|
+
const path2 = [...pts, pts[0]];
|
|
222277
|
+
return new PathLayer({
|
|
222278
|
+
...base2,
|
|
222279
|
+
id: "annotation-preview-ellipse",
|
|
222280
|
+
data: [{ path: path2 }],
|
|
222281
|
+
getPath: (d) => d.path,
|
|
222282
|
+
getColor: previewColor,
|
|
222283
|
+
getWidth: 1,
|
|
222284
|
+
widthUnits: "pixels",
|
|
222285
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
222286
|
+
getDashArray: [8, 4]
|
|
222287
|
+
});
|
|
222288
|
+
}
|
|
222289
|
+
if ((type2 === "polygon" || type2 === "polyline") && vertices.length >= 1) {
|
|
222290
|
+
const path2 = [...vertices, cursor2];
|
|
222291
|
+
if (type2 === "polygon" && vertices.length >= 2)
|
|
222292
|
+
path2.push(vertices[0]);
|
|
222293
|
+
return new PathLayer({
|
|
222294
|
+
...base2,
|
|
222295
|
+
id: `annotation-preview-${type2}`,
|
|
222296
|
+
data: [{ path: path2 }],
|
|
222297
|
+
getPath: (d) => d.path,
|
|
222298
|
+
getColor: previewColor,
|
|
222299
|
+
getWidth: 1,
|
|
222300
|
+
widthUnits: "pixels",
|
|
222301
|
+
jointRounded: true,
|
|
222302
|
+
capRounded: true,
|
|
222303
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
222304
|
+
getDashArray: [8, 4]
|
|
222305
|
+
});
|
|
222306
|
+
}
|
|
222307
|
+
return null;
|
|
222308
|
+
}
|
|
222309
|
+
function computeTickCap(tipX, tipY, dirX, dirY, dataSize) {
|
|
222310
|
+
const len2 = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
222311
|
+
if (len2 === 0)
|
|
222312
|
+
return null;
|
|
222313
|
+
const ux = dirX / len2;
|
|
222314
|
+
const uy = dirY / len2;
|
|
222315
|
+
const px2 = -uy;
|
|
222316
|
+
const py2 = ux;
|
|
222317
|
+
const half = dataSize * 0.55;
|
|
222318
|
+
return [
|
|
222319
|
+
[tipX + px2 * half, tipY + py2 * half],
|
|
222320
|
+
[tipX - px2 * half, tipY - py2 * half]
|
|
222321
|
+
];
|
|
222322
|
+
}
|
|
222323
|
+
function computeArrowhead(tipX, tipY, dirX, dirY, dataSize) {
|
|
222324
|
+
const len2 = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
222325
|
+
if (len2 === 0)
|
|
222326
|
+
return null;
|
|
222327
|
+
const ux = dirX / len2;
|
|
222328
|
+
const uy = dirY / len2;
|
|
222329
|
+
const px2 = -uy;
|
|
222330
|
+
const py2 = ux;
|
|
222331
|
+
const halfBase = dataSize * 0.4;
|
|
222332
|
+
const bx = tipX - ux * dataSize;
|
|
222333
|
+
const by = tipY - uy * dataSize;
|
|
222334
|
+
return [
|
|
222335
|
+
[tipX, tipY],
|
|
222336
|
+
[bx + px2 * halfBase, by + py2 * halfBase],
|
|
222337
|
+
[bx - px2 * halfBase, by - py2 * halfBase]
|
|
222338
|
+
];
|
|
222339
|
+
}
|
|
222340
|
+
function fmtCommas(n3) {
|
|
222341
|
+
return Math.round(n3).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
222342
|
+
}
|
|
222343
|
+
function getMeasurementLabel(shape2, physicalPixelSize, viewType = ViewType$1.SPATIAL) {
|
|
222344
|
+
const pps = physicalPixelSize;
|
|
222345
|
+
const px2 = pps?.x ?? 1;
|
|
222346
|
+
const py2 = pps?.y ?? 1;
|
|
222347
|
+
const unit2 = pps ? pps.unit ?? "" : null;
|
|
222348
|
+
const hasPhys = !!pps;
|
|
222349
|
+
const isEmbedding = viewType === ViewType$1.SCATTERPLOT;
|
|
222350
|
+
const fmtDist = (d) => {
|
|
222351
|
+
if (hasPhys)
|
|
222352
|
+
return `${d.toFixed(2)} ${unit2}`;
|
|
222353
|
+
if (isEmbedding)
|
|
222354
|
+
return d.toFixed(2);
|
|
222355
|
+
return `${fmtCommas(d)} px`;
|
|
222356
|
+
};
|
|
222357
|
+
const fmtArea = (a2) => {
|
|
222358
|
+
if (hasPhys)
|
|
222359
|
+
return `${a2.toFixed(2)} ${unit2}²`;
|
|
222360
|
+
if (isEmbedding)
|
|
222361
|
+
return a2.toFixed(2);
|
|
222362
|
+
return `${fmtCommas(a2)} px²`;
|
|
222363
|
+
};
|
|
222364
|
+
if (shape2.type === "line") {
|
|
222365
|
+
const dx = (shape2.x2 ?? 0) - (shape2.x1 ?? 0);
|
|
222366
|
+
const dy = (shape2.y2 ?? 0) - (shape2.y1 ?? 0);
|
|
222367
|
+
const dist2 = hasPhys ? Math.sqrt((dx * px2) ** 2 + (dy * py2) ** 2) : Math.sqrt(dx * dx + dy * dy);
|
|
222368
|
+
return fmtDist(dist2);
|
|
222369
|
+
}
|
|
222370
|
+
if (shape2.type === "rectangle") {
|
|
222371
|
+
return fmtArea(hasPhys ? Math.abs(shape2.width ?? 0) * px2 * Math.abs(shape2.height ?? 0) * py2 : Math.abs((shape2.width ?? 0) * (shape2.height ?? 0)));
|
|
222372
|
+
}
|
|
222373
|
+
if (shape2.type === "ellipse") {
|
|
222374
|
+
const rx = Math.abs(shape2.radiusX ?? 0);
|
|
222375
|
+
const ry = Math.abs(shape2.radiusY ?? 0);
|
|
222376
|
+
return fmtArea(hasPhys ? Math.PI * rx * px2 * ry * py2 : Math.PI * rx * ry);
|
|
222377
|
+
}
|
|
222378
|
+
if (shape2.type === "polygon" && shape2.points?.length >= 3) {
|
|
222379
|
+
const pts = shape2.points;
|
|
222380
|
+
let shoelace = 0;
|
|
222381
|
+
for (let i2 = 0; i2 < pts.length; i2++) {
|
|
222382
|
+
const [ax, ay] = pts[i2];
|
|
222383
|
+
const [bx, by] = pts[(i2 + 1) % pts.length];
|
|
222384
|
+
shoelace += (hasPhys ? ax * px2 : ax) * (hasPhys ? by * py2 : by) - (hasPhys ? bx * px2 : bx) * (hasPhys ? ay * py2 : ay);
|
|
222385
|
+
}
|
|
222386
|
+
return fmtArea(Math.abs(shoelace / 2));
|
|
222387
|
+
}
|
|
222388
|
+
if (shape2.type === "polyline" && shape2.points?.length >= 2) {
|
|
222389
|
+
let total = 0;
|
|
222390
|
+
for (let i2 = 0; i2 < shape2.points.length - 1; i2++) {
|
|
222391
|
+
const [ax, ay] = shape2.points[i2];
|
|
222392
|
+
const [bx, by] = shape2.points[i2 + 1];
|
|
222393
|
+
total += hasPhys ? Math.sqrt(((bx - ax) * px2) ** 2 + ((by - ay) * py2) ** 2) : Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
|
|
222394
|
+
}
|
|
222395
|
+
return fmtDist(total);
|
|
222396
|
+
}
|
|
222397
|
+
return null;
|
|
222398
|
+
}
|
|
222399
|
+
function pickBelowPerp(ux, uy) {
|
|
222400
|
+
const rp = [uy, -ux];
|
|
222401
|
+
const lp = [-uy, ux];
|
|
222402
|
+
return rp[1] > lp[1] || rp[1] === lp[1] && rp[0] > lp[0] ? rp : lp;
|
|
222403
|
+
}
|
|
222404
|
+
function readableAngle(deg) {
|
|
222405
|
+
let a2 = deg;
|
|
222406
|
+
if (a2 > 90)
|
|
222407
|
+
a2 -= 180;
|
|
222408
|
+
if (a2 < -90)
|
|
222409
|
+
a2 += 180;
|
|
222410
|
+
return a2;
|
|
222411
|
+
}
|
|
222412
|
+
function getShapeCentroid(shape2) {
|
|
222413
|
+
if (shape2.type === "rectangle") {
|
|
222414
|
+
return [(shape2.x ?? 0) + (shape2.width ?? 0) / 2, (shape2.y ?? 0) + (shape2.height ?? 0) / 2];
|
|
222415
|
+
}
|
|
222416
|
+
if (shape2.type === "line") {
|
|
222417
|
+
return [((shape2.x1 ?? 0) + (shape2.x2 ?? 0)) / 2, ((shape2.y1 ?? 0) + (shape2.y2 ?? 0)) / 2];
|
|
222418
|
+
}
|
|
222419
|
+
if (shape2.type === "ellipse") {
|
|
222420
|
+
return [shape2.x1 ?? 0, shape2.y1 ?? 0];
|
|
222421
|
+
}
|
|
222422
|
+
if ((shape2.type === "polygon" || shape2.type === "polyline") && shape2.points?.length >= 1) {
|
|
222423
|
+
const mx = shape2.points.reduce((s2, p) => s2 + p[0], 0) / shape2.points.length;
|
|
222424
|
+
const my = shape2.points.reduce((s2, p) => s2 + p[1], 0) / shape2.points.length;
|
|
222425
|
+
return [mx, my];
|
|
222426
|
+
}
|
|
222427
|
+
return [0, 0];
|
|
222428
|
+
}
|
|
222429
|
+
function computeClusters(shapeList, zoom2, cellPx = 50) {
|
|
222430
|
+
const cellSize = cellPx / 2 ** Math.floor(zoom2);
|
|
222431
|
+
const cells = /* @__PURE__ */ new Map();
|
|
222432
|
+
shapeList.forEach(({ shape: shape2 }) => {
|
|
222433
|
+
const [cx, cy] = getShapeCentroid(shape2);
|
|
222434
|
+
const key2 = `${Math.floor(cx / cellSize)},${Math.floor(cy / cellSize)}`;
|
|
222435
|
+
if (!cells.has(key2)) {
|
|
222436
|
+
cells.set(key2, { sumX: 0, sumY: 0, count: 0, color: shape2.strokeColor ?? [255, 255, 255] });
|
|
222437
|
+
}
|
|
222438
|
+
const c2 = cells.get(key2);
|
|
222439
|
+
c2.sumX += cx;
|
|
222440
|
+
c2.sumY += cy;
|
|
222441
|
+
c2.count++;
|
|
222442
|
+
});
|
|
222443
|
+
return Array.from(cells.values()).map((c2) => ({
|
|
222444
|
+
position: [c2.sumX / c2.count, c2.sumY / c2.count, 0],
|
|
222445
|
+
count: c2.count,
|
|
222446
|
+
color: c2.color
|
|
222447
|
+
}));
|
|
222448
|
+
}
|
|
222449
|
+
function createAnnotationLayers(shapes = [], zoom2 = 0, selectedShapeUid = null, physicalPixelSize = null, authoredZoom = null, semanticZoom = true, viewType = ViewType$1.SPATIAL) {
|
|
222450
|
+
const selectionLayers = [];
|
|
222451
|
+
if (selectedShapeUid) {
|
|
222452
|
+
const sel = shapes.find((s2) => s2.uid === selectedShapeUid);
|
|
222453
|
+
if (sel) {
|
|
222454
|
+
const { uid: sUid, type: sType, strokeWidth: sStrokeWidth = 3 } = sel;
|
|
222455
|
+
const haloColor = [255, 220, 50, 70];
|
|
222456
|
+
const haloWidth = Math.max(sStrokeWidth + 8, 10);
|
|
222457
|
+
const base2 = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN };
|
|
222458
|
+
if (sType === "rectangle") {
|
|
222459
|
+
const { x: x2, y: y2, width: width2, height: height2 } = sel;
|
|
222460
|
+
selectionLayers.push(new PathLayer({
|
|
222461
|
+
...base2,
|
|
222462
|
+
id: `annotation-select-${sUid}`,
|
|
222463
|
+
data: [{
|
|
222464
|
+
path: [
|
|
222465
|
+
[x2, y2],
|
|
222466
|
+
[x2 + width2, y2],
|
|
222467
|
+
[x2 + width2, y2 + height2],
|
|
222468
|
+
[x2, y2 + height2],
|
|
222469
|
+
[x2, y2]
|
|
222470
|
+
]
|
|
222471
|
+
}],
|
|
222472
|
+
getPath: (d) => d.path,
|
|
222473
|
+
getColor: haloColor,
|
|
222474
|
+
getWidth: haloWidth,
|
|
222475
|
+
widthUnits: "pixels",
|
|
222476
|
+
jointRounded: true,
|
|
222477
|
+
capRounded: true
|
|
222478
|
+
}));
|
|
222479
|
+
}
|
|
222480
|
+
if (sType === "line") {
|
|
222481
|
+
const { x1: x12, y1: y12, x2, y2 } = sel;
|
|
222482
|
+
selectionLayers.push(new PathLayer({
|
|
222483
|
+
...base2,
|
|
222484
|
+
id: `annotation-select-${sUid}`,
|
|
222485
|
+
data: [{ path: [[x12, y12], [x2, y2]] }],
|
|
222486
|
+
getPath: (d) => d.path,
|
|
222487
|
+
getColor: haloColor,
|
|
222488
|
+
getWidth: haloWidth,
|
|
222489
|
+
widthUnits: "pixels",
|
|
222490
|
+
capRounded: true
|
|
222491
|
+
}));
|
|
222492
|
+
}
|
|
222493
|
+
if (sType === "ellipse") {
|
|
222494
|
+
const polygon2 = computeEllipsePolygon(sel.x1, sel.y1, sel.radiusX, sel.radiusY);
|
|
222495
|
+
selectionLayers.push(new PathLayer({
|
|
222496
|
+
...base2,
|
|
222497
|
+
id: `annotation-select-${sUid}`,
|
|
222498
|
+
data: [{ path: [...polygon2, polygon2[0]] }],
|
|
222499
|
+
getPath: (d) => d.path,
|
|
222500
|
+
getColor: haloColor,
|
|
222501
|
+
getWidth: haloWidth,
|
|
222502
|
+
widthUnits: "pixels",
|
|
222503
|
+
jointRounded: true
|
|
222504
|
+
}));
|
|
222505
|
+
}
|
|
222506
|
+
if (sType === "polygon" && sel.points?.length >= 3) {
|
|
222507
|
+
selectionLayers.push(new PathLayer({
|
|
222508
|
+
...base2,
|
|
222509
|
+
id: `annotation-select-${sUid}`,
|
|
222510
|
+
data: [{ path: [...sel.points, sel.points[0]] }],
|
|
222511
|
+
getPath: (d) => d.path,
|
|
222512
|
+
getColor: haloColor,
|
|
222513
|
+
getWidth: haloWidth,
|
|
222514
|
+
widthUnits: "pixels",
|
|
222515
|
+
jointRounded: true
|
|
222516
|
+
}));
|
|
222517
|
+
}
|
|
222518
|
+
if (sType === "polyline" && sel.points?.length >= 2) {
|
|
222519
|
+
selectionLayers.push(new PathLayer({
|
|
222520
|
+
...base2,
|
|
222521
|
+
id: `annotation-select-${sUid}`,
|
|
222522
|
+
data: [{ path: sel.points }],
|
|
222523
|
+
getPath: (d) => d.path,
|
|
222524
|
+
getColor: haloColor,
|
|
222525
|
+
getWidth: haloWidth,
|
|
222526
|
+
widthUnits: "pixels",
|
|
222527
|
+
jointRounded: true,
|
|
222528
|
+
capRounded: true
|
|
222529
|
+
}));
|
|
222530
|
+
}
|
|
222531
|
+
}
|
|
222532
|
+
}
|
|
222533
|
+
const layers = [];
|
|
222534
|
+
const dotShapes = [];
|
|
222535
|
+
const clusterDotShapes = [];
|
|
222536
|
+
shapes.forEach((shape2, i2) => {
|
|
222537
|
+
const { uid: uid2, type: type2, strokeColor = [255, 255, 255], strokeWidth = 3, strokeDashArray } = shape2;
|
|
222538
|
+
const isSelected = uid2 === selectedShapeUid;
|
|
222539
|
+
let shapeOpacity = 1;
|
|
222540
|
+
let tipsOpacity = 1;
|
|
222541
|
+
let labelOpacity = 0;
|
|
222542
|
+
if (isSelected || !semanticZoom || authoredZoom === null) {
|
|
222543
|
+
tipsOpacity = 1;
|
|
222544
|
+
labelOpacity = 1;
|
|
222545
|
+
} else {
|
|
222546
|
+
const zoomRatio = 2 ** (zoom2 - authoredZoom);
|
|
222547
|
+
if (zoomRatio < RATIO_CLUSTER) {
|
|
222548
|
+
clusterDotShapes.push({ shape: shape2 });
|
|
222549
|
+
return;
|
|
222550
|
+
}
|
|
222551
|
+
if (zoomRatio < RATIO_DOT) {
|
|
222552
|
+
dotShapes.push({ shape: shape2, alpha: 200 });
|
|
222553
|
+
return;
|
|
222554
|
+
}
|
|
222555
|
+
if (zoomRatio < RATIO_GEO_FADE) {
|
|
222556
|
+
const t4 = (zoomRatio - RATIO_DOT) / (RATIO_GEO_FADE - RATIO_DOT);
|
|
222557
|
+
shapeOpacity = t4;
|
|
222558
|
+
dotShapes.push({ shape: shape2, alpha: Math.round((1 - t4) * 200) });
|
|
222559
|
+
}
|
|
222560
|
+
tipsOpacity = zoomRatio >= RATIO_TIPS ? shapeOpacity : Math.max(0, (zoomRatio - RATIO_GEO_FADE) / (RATIO_TIPS - RATIO_GEO_FADE) * shapeOpacity);
|
|
222561
|
+
if (zoomRatio >= RATIO_LABEL_FULL) {
|
|
222562
|
+
labelOpacity = shapeOpacity;
|
|
222563
|
+
} else if (zoomRatio >= RATIO_LABEL) {
|
|
222564
|
+
labelOpacity = (zoomRatio - RATIO_LABEL) / (RATIO_LABEL_FULL - RATIO_LABEL) * shapeOpacity;
|
|
222565
|
+
}
|
|
222566
|
+
}
|
|
222567
|
+
const arrowDataSize = Math.max(ARROW_SCREEN_PX, strokeWidth * 4) / 2 ** zoom2;
|
|
222568
|
+
const base2 = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: shapeOpacity };
|
|
222569
|
+
const tipsBase = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: tipsOpacity };
|
|
222570
|
+
const labelBase = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: labelOpacity };
|
|
222571
|
+
const labelBgProps = shape2.labelBackground ? {
|
|
222572
|
+
background: true,
|
|
222573
|
+
getBackgroundColor: textBgColor(strokeColor),
|
|
222574
|
+
backgroundPadding: [3, 1, 3, 2]
|
|
222575
|
+
} : {};
|
|
222576
|
+
const labelProps = { ...labelBgProps };
|
|
222577
|
+
const dashArray = parseDashArray(strokeDashArray);
|
|
222578
|
+
const dashExt = [new PathStyleExtension({ dash: true })];
|
|
222579
|
+
const getDash = dashArray ?? [0, 0];
|
|
222580
|
+
if (type2 === "rectangle") {
|
|
222581
|
+
const { x: x2, y: y2, width: width2, height: height2, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
222582
|
+
const filled = fillOpacity > 0;
|
|
222583
|
+
const rectPolygon = [[x2, y2], [x2 + width2, y2], [x2 + width2, y2 + height2], [x2, y2 + height2]];
|
|
222584
|
+
layers.push(new PolygonLayer({
|
|
222585
|
+
...base2,
|
|
222586
|
+
id: `annotation-rect-${uid2}-${i2}`,
|
|
222587
|
+
data: [{ polygon: rectPolygon }],
|
|
222588
|
+
getPolygon: (d) => d.polygon,
|
|
222589
|
+
filled,
|
|
222590
|
+
stroked: true,
|
|
222591
|
+
getFillColor: filled ? [...fillColor, Math.round(fillOpacity * 255)] : [0, 0, 0, 0],
|
|
222592
|
+
getLineColor: strokeColor,
|
|
222593
|
+
getLineWidth: strokeWidth,
|
|
222594
|
+
lineWidthUnits: "pixels",
|
|
222595
|
+
...dashArray ? {
|
|
222596
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
222597
|
+
getDashArray: dashArray
|
|
222598
|
+
} : {}
|
|
222599
|
+
}));
|
|
222600
|
+
if (shape2.text && labelOpacity > 0) {
|
|
222601
|
+
layers.push(new TextLayer({
|
|
222602
|
+
...labelBase,
|
|
222603
|
+
...labelProps,
|
|
222604
|
+
id: `annotation-rect-text-${uid2}-${i2}`,
|
|
222605
|
+
data: [{ position: [x2, y2], text: shape2.text }],
|
|
222606
|
+
getPosition: (d) => d.position,
|
|
222607
|
+
getText: (d) => d.text,
|
|
222608
|
+
getColor: strokeColor,
|
|
222609
|
+
getSize: LABEL_FONT_SIZE,
|
|
222610
|
+
sizeUnits: "pixels",
|
|
222611
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
222612
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
222613
|
+
getPixelOffset: [3, -7],
|
|
222614
|
+
getTextAnchor: "start",
|
|
222615
|
+
getAlignmentBaseline: "bottom"
|
|
222616
|
+
}));
|
|
222617
|
+
}
|
|
222618
|
+
}
|
|
222619
|
+
if (type2 === "line") {
|
|
222620
|
+
const { x1: x12, y1: y12, x2, y2, markerStart, markerEnd } = shape2;
|
|
222621
|
+
const dx = x2 - x12;
|
|
222622
|
+
const dy = y2 - y12;
|
|
222623
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
222624
|
+
const ux = len2 > 0 ? dx / len2 : 0;
|
|
222625
|
+
const uy = len2 > 0 ? dy / len2 : 0;
|
|
222626
|
+
const srcX = markerStart === "Arrow" ? x12 + ux * arrowDataSize : x12;
|
|
222627
|
+
const srcY = markerStart === "Arrow" ? y12 + uy * arrowDataSize : y12;
|
|
222628
|
+
const tgtX = markerEnd === "Arrow" ? x2 - ux * arrowDataSize : x2;
|
|
222629
|
+
const tgtY = markerEnd === "Arrow" ? y2 - uy * arrowDataSize : y2;
|
|
222630
|
+
layers.push(new PathLayer({
|
|
222631
|
+
...base2,
|
|
222632
|
+
id: `annotation-line-${uid2}-${i2}`,
|
|
222633
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
222634
|
+
getDashArray: dashArray ?? [0, 0],
|
|
222635
|
+
data: [{ path: [[srcX, srcY], [tgtX, tgtY]] }],
|
|
222636
|
+
getPath: (d) => d.path,
|
|
222637
|
+
getColor: strokeColor,
|
|
222638
|
+
getWidth: strokeWidth,
|
|
222639
|
+
widthUnits: "pixels",
|
|
222640
|
+
capRounded: true
|
|
222641
|
+
}));
|
|
222642
|
+
if (markerEnd === "Arrow" && tipsOpacity > 0) {
|
|
222643
|
+
const head = computeArrowhead(x2, y2, x2 - x12, y2 - y12, arrowDataSize);
|
|
222644
|
+
if (head) {
|
|
222645
|
+
layers.push(new PolygonLayer({
|
|
222646
|
+
...tipsBase,
|
|
222647
|
+
id: `annotation-end-arrow-${uid2}-${i2}`,
|
|
222648
|
+
data: [{ polygon: head }],
|
|
222649
|
+
getPolygon: (d) => d.polygon,
|
|
222650
|
+
filled: true,
|
|
222651
|
+
stroked: false,
|
|
222652
|
+
getFillColor: strokeColor
|
|
222653
|
+
}));
|
|
222654
|
+
}
|
|
222655
|
+
}
|
|
222656
|
+
if (markerStart === "Arrow" && tipsOpacity > 0) {
|
|
222657
|
+
const head = computeArrowhead(x12, y12, x12 - x2, y12 - y2, arrowDataSize);
|
|
222658
|
+
if (head) {
|
|
222659
|
+
layers.push(new PolygonLayer({
|
|
222660
|
+
...tipsBase,
|
|
222661
|
+
id: `annotation-start-arrow-${uid2}-${i2}`,
|
|
222662
|
+
data: [{ polygon: head }],
|
|
222663
|
+
getPolygon: (d) => d.polygon,
|
|
222664
|
+
filled: true,
|
|
222665
|
+
stroked: false,
|
|
222666
|
+
getFillColor: strokeColor
|
|
222667
|
+
}));
|
|
222668
|
+
}
|
|
222669
|
+
}
|
|
222670
|
+
if (markerEnd === "Tick" && tipsOpacity > 0) {
|
|
222671
|
+
const tick2 = computeTickCap(x2, y2, x2 - x12, y2 - y12, arrowDataSize);
|
|
222672
|
+
if (tick2) {
|
|
222673
|
+
layers.push(new PathLayer({
|
|
222674
|
+
...tipsBase,
|
|
222675
|
+
id: `annotation-end-tick-${uid2}-${i2}`,
|
|
222676
|
+
data: [{ path: tick2 }],
|
|
222677
|
+
getPath: (d) => d.path,
|
|
222678
|
+
getColor: strokeColor,
|
|
222679
|
+
getWidth: strokeWidth,
|
|
222680
|
+
widthUnits: "pixels",
|
|
222681
|
+
capRounded: true
|
|
222682
|
+
}));
|
|
222683
|
+
}
|
|
222684
|
+
}
|
|
222685
|
+
if (markerStart === "Tick" && tipsOpacity > 0) {
|
|
222686
|
+
const tick2 = computeTickCap(x12, y12, x12 - x2, y12 - y2, arrowDataSize);
|
|
222687
|
+
if (tick2) {
|
|
222688
|
+
layers.push(new PathLayer({
|
|
222689
|
+
...tipsBase,
|
|
222690
|
+
id: `annotation-start-tick-${uid2}-${i2}`,
|
|
222691
|
+
data: [{ path: tick2 }],
|
|
222692
|
+
getPath: (d) => d.path,
|
|
222693
|
+
getColor: strokeColor,
|
|
222694
|
+
getWidth: strokeWidth,
|
|
222695
|
+
widthUnits: "pixels",
|
|
222696
|
+
capRounded: true
|
|
222697
|
+
}));
|
|
222698
|
+
}
|
|
222699
|
+
}
|
|
222700
|
+
if (shape2.text) {
|
|
222701
|
+
const pos = shape2.textPosition ?? "start";
|
|
222702
|
+
let textX;
|
|
222703
|
+
let textY;
|
|
222704
|
+
if (pos === "start") {
|
|
222705
|
+
textX = x12;
|
|
222706
|
+
textY = y12;
|
|
222707
|
+
} else if (pos === "end") {
|
|
222708
|
+
textX = x2;
|
|
222709
|
+
textY = y2;
|
|
222710
|
+
} else {
|
|
222711
|
+
textX = (x12 + x2) / 2;
|
|
222712
|
+
textY = (y12 + y2) / 2;
|
|
222713
|
+
}
|
|
222714
|
+
let pixelOffset = [0, 0];
|
|
222715
|
+
let textAnchor = "middle";
|
|
222716
|
+
let alignmentBaseline = "center";
|
|
222717
|
+
if (pos !== "middle") {
|
|
222718
|
+
const dxT = x2 - x12;
|
|
222719
|
+
const dyT = y2 - y12;
|
|
222720
|
+
const lenT = Math.sqrt(dxT * dxT + dyT * dyT);
|
|
222721
|
+
if (lenT > 0) {
|
|
222722
|
+
const uxT = dxT / lenT;
|
|
222723
|
+
const uyT = dyT / lenT;
|
|
222724
|
+
const sign2 = pos === "start" ? -1 : 1;
|
|
222725
|
+
const bufferPx = shape2.textBufferPx ?? 8;
|
|
222726
|
+
const offsetX = sign2 * uxT * bufferPx;
|
|
222727
|
+
const offsetY = sign2 * uyT * bufferPx;
|
|
222728
|
+
pixelOffset = [offsetX, offsetY];
|
|
222729
|
+
const absX = Math.abs(offsetX);
|
|
222730
|
+
const absY = Math.abs(offsetY);
|
|
222731
|
+
if (absX >= absY) {
|
|
222732
|
+
textAnchor = offsetX > 0 ? "start" : "end";
|
|
222733
|
+
}
|
|
222734
|
+
if (absY >= absX) {
|
|
222735
|
+
alignmentBaseline = offsetY > 0 ? "top" : "bottom";
|
|
222736
|
+
}
|
|
222737
|
+
}
|
|
222738
|
+
} else if (len2 > 0) {
|
|
222739
|
+
const belowPerp = pickBelowPerp(ux, uy);
|
|
222740
|
+
const bufferPx = shape2.textBufferPx ?? 14;
|
|
222741
|
+
pixelOffset = [-belowPerp[0] * bufferPx, -belowPerp[1] * bufferPx];
|
|
222742
|
+
textAnchor = "middle";
|
|
222743
|
+
alignmentBaseline = "center";
|
|
222744
|
+
}
|
|
222745
|
+
const middleAngle = pos === "middle" && len2 > 0 ? -readableAngle(Math.atan2(dy, dx) * 180 / Math.PI) : null;
|
|
222746
|
+
if (labelOpacity <= 0)
|
|
222747
|
+
return;
|
|
222748
|
+
layers.push(new TextLayer({
|
|
222749
|
+
...labelBase,
|
|
222750
|
+
...labelProps,
|
|
222751
|
+
id: `annotation-line-text-${uid2}-${i2}`,
|
|
222752
|
+
data: [{ position: [textX, textY], text: shape2.text }],
|
|
222753
|
+
getPosition: (d) => d.position,
|
|
222754
|
+
getText: (d) => d.text,
|
|
222755
|
+
getColor: strokeColor,
|
|
222756
|
+
getSize: LABEL_FONT_SIZE,
|
|
222757
|
+
sizeUnits: "pixels",
|
|
222758
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
222759
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
222760
|
+
getPixelOffset: pixelOffset,
|
|
222761
|
+
getTextAnchor: textAnchor,
|
|
222762
|
+
getAlignmentBaseline: alignmentBaseline,
|
|
222763
|
+
...middleAngle !== null && { getAngle: middleAngle }
|
|
222764
|
+
}));
|
|
222765
|
+
}
|
|
222766
|
+
}
|
|
222767
|
+
if (type2 === "ellipse") {
|
|
222768
|
+
const { x1: x12, y1: y12, radiusX, radiusY, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
222769
|
+
const polygon2 = computeEllipsePolygon(x12, y12, radiusX, radiusY);
|
|
222770
|
+
const filled = fillOpacity > 0;
|
|
222771
|
+
layers.push(new PolygonLayer({
|
|
222772
|
+
...base2,
|
|
222773
|
+
id: `annotation-ellipse-${uid2}-${i2}`,
|
|
222774
|
+
data: [{ polygon: polygon2 }],
|
|
222775
|
+
getPolygon: (d) => d.polygon,
|
|
222776
|
+
filled,
|
|
222777
|
+
stroked: true,
|
|
222778
|
+
getFillColor: filled ? [...fillColor, Math.round(fillOpacity * 255)] : [0, 0, 0, 0],
|
|
222779
|
+
getLineColor: strokeColor,
|
|
222780
|
+
getLineWidth: strokeWidth,
|
|
222781
|
+
lineWidthUnits: "pixels",
|
|
222782
|
+
...dashArray ? {
|
|
222783
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
222784
|
+
getDashArray: dashArray
|
|
222785
|
+
} : {}
|
|
222786
|
+
}));
|
|
222787
|
+
if (shape2.text && labelOpacity > 0) {
|
|
222788
|
+
layers.push(new TextLayer({
|
|
222789
|
+
...labelBase,
|
|
222790
|
+
...labelProps,
|
|
222791
|
+
id: `annotation-ellipse-text-${uid2}-${i2}`,
|
|
222792
|
+
data: [{ position: [x12, y12 - radiusY], text: shape2.text }],
|
|
222793
|
+
getPosition: (d) => d.position,
|
|
222794
|
+
getText: (d) => d.text,
|
|
222795
|
+
getColor: strokeColor,
|
|
222796
|
+
getSize: LABEL_FONT_SIZE,
|
|
222797
|
+
sizeUnits: "pixels",
|
|
222798
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
222799
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
222800
|
+
getPixelOffset: [0, -4],
|
|
222801
|
+
getTextAnchor: "middle",
|
|
222802
|
+
getAlignmentBaseline: "bottom"
|
|
222803
|
+
}));
|
|
222804
|
+
}
|
|
222805
|
+
}
|
|
222806
|
+
if (type2 === "polygon") {
|
|
222807
|
+
const { points: points2, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
222808
|
+
if (!points2 || points2.length < 3)
|
|
222809
|
+
return;
|
|
222810
|
+
const closedPath = [...points2, points2[0]];
|
|
222811
|
+
if (fillOpacity > 0) {
|
|
222812
|
+
layers.push(new PolygonLayer({
|
|
222813
|
+
...base2,
|
|
222814
|
+
id: `annotation-polygon-fill-${uid2}-${i2}`,
|
|
222815
|
+
data: [{ polygon: points2 }],
|
|
222816
|
+
getPolygon: (d) => d.polygon,
|
|
222817
|
+
stroked: false,
|
|
222818
|
+
filled: true,
|
|
222819
|
+
getFillColor: [...fillColor, Math.round(fillOpacity * 255)]
|
|
222820
|
+
}));
|
|
222821
|
+
}
|
|
222822
|
+
layers.push(new PathLayer({
|
|
222823
|
+
...base2,
|
|
222824
|
+
id: `annotation-polygon-${uid2}-${i2}`,
|
|
222825
|
+
extensions: dashExt,
|
|
222826
|
+
getDashArray: getDash,
|
|
222827
|
+
data: [{ path: closedPath }],
|
|
222828
|
+
getPath: (d) => d.path,
|
|
222829
|
+
getColor: strokeColor,
|
|
222830
|
+
getWidth: strokeWidth,
|
|
222831
|
+
widthUnits: "pixels",
|
|
222832
|
+
jointRounded: true
|
|
222833
|
+
}));
|
|
222834
|
+
if (shape2.text && labelOpacity > 0) {
|
|
222835
|
+
const minX = Math.min(...points2.map((p) => p[0]));
|
|
222836
|
+
const maxX = Math.max(...points2.map((p) => p[0]));
|
|
222837
|
+
const minY = Math.min(...points2.map((p) => p[1]));
|
|
222838
|
+
const topCenterX = (minX + maxX) / 2;
|
|
222839
|
+
layers.push(new TextLayer({
|
|
222840
|
+
...labelBase,
|
|
222841
|
+
...labelProps,
|
|
222842
|
+
id: `annotation-polygon-text-${uid2}-${i2}`,
|
|
222843
|
+
data: [{ position: [topCenterX, minY], text: shape2.text }],
|
|
222844
|
+
getPosition: (d) => d.position,
|
|
222845
|
+
getText: (d) => d.text,
|
|
222846
|
+
getColor: strokeColor,
|
|
222847
|
+
getSize: LABEL_FONT_SIZE,
|
|
222848
|
+
sizeUnits: "pixels",
|
|
222849
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
222850
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
222851
|
+
getPixelOffset: [0, -4],
|
|
222852
|
+
getTextAnchor: "middle",
|
|
222853
|
+
getAlignmentBaseline: "bottom"
|
|
222854
|
+
}));
|
|
222855
|
+
}
|
|
222856
|
+
}
|
|
222857
|
+
if (type2 === "polyline") {
|
|
222858
|
+
const { points: points2, markerStart, markerEnd } = shape2;
|
|
222859
|
+
if (!points2 || points2.length < 2)
|
|
222860
|
+
return;
|
|
222861
|
+
let pathPoints = points2;
|
|
222862
|
+
if (markerStart === "Arrow") {
|
|
222863
|
+
const [x02, y02] = points2[0];
|
|
222864
|
+
const [x12, y12] = points2[1];
|
|
222865
|
+
const dx = x02 - x12;
|
|
222866
|
+
const dy = y02 - y12;
|
|
222867
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
222868
|
+
if (len2 > 0) {
|
|
222869
|
+
const ux = dx / len2;
|
|
222870
|
+
const uy = dy / len2;
|
|
222871
|
+
pathPoints = [[x02 - ux * arrowDataSize, y02 - uy * arrowDataSize], ...pathPoints.slice(1)];
|
|
222872
|
+
}
|
|
222873
|
+
}
|
|
222874
|
+
if (markerEnd === "Arrow") {
|
|
222875
|
+
const last = pathPoints[pathPoints.length - 1];
|
|
222876
|
+
const prev2 = pathPoints[pathPoints.length - 2];
|
|
222877
|
+
const dx = last[0] - prev2[0];
|
|
222878
|
+
const dy = last[1] - prev2[1];
|
|
222879
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
222880
|
+
if (len2 > 0) {
|
|
222881
|
+
const ux = dx / len2;
|
|
222882
|
+
const uy = dy / len2;
|
|
222883
|
+
const shortened = [last[0] - ux * arrowDataSize, last[1] - uy * arrowDataSize];
|
|
222884
|
+
pathPoints = [...pathPoints.slice(0, -1), shortened];
|
|
222885
|
+
}
|
|
222886
|
+
}
|
|
222887
|
+
layers.push(new PathLayer({
|
|
222888
|
+
...base2,
|
|
222889
|
+
id: `annotation-polyline-${uid2}-${i2}`,
|
|
222890
|
+
extensions: dashExt,
|
|
222891
|
+
getDashArray: getDash,
|
|
222892
|
+
data: [{ path: pathPoints }],
|
|
222893
|
+
getPath: (d) => d.path,
|
|
222894
|
+
getColor: strokeColor,
|
|
222895
|
+
getWidth: strokeWidth,
|
|
222896
|
+
widthUnits: "pixels",
|
|
222897
|
+
jointRounded: true,
|
|
222898
|
+
capRounded: true
|
|
222899
|
+
}));
|
|
222900
|
+
if (markerStart === "Arrow" && tipsOpacity > 0) {
|
|
222901
|
+
const [x02, y02] = points2[0];
|
|
222902
|
+
const [x12, y12] = points2[1];
|
|
222903
|
+
const head = computeArrowhead(x02, y02, x02 - x12, y02 - y12, arrowDataSize);
|
|
222904
|
+
if (head) {
|
|
222905
|
+
layers.push(new PolygonLayer({
|
|
222906
|
+
...tipsBase,
|
|
222907
|
+
id: `annotation-polyline-start-arrow-${uid2}-${i2}`,
|
|
222908
|
+
data: [{ polygon: head }],
|
|
222909
|
+
getPolygon: (d) => d.polygon,
|
|
222910
|
+
filled: true,
|
|
222911
|
+
stroked: false,
|
|
222912
|
+
getFillColor: strokeColor
|
|
222913
|
+
}));
|
|
222914
|
+
}
|
|
222915
|
+
}
|
|
222916
|
+
if (markerEnd === "Arrow" && tipsOpacity > 0) {
|
|
222917
|
+
const last = points2[points2.length - 1];
|
|
222918
|
+
const prev2 = points2[points2.length - 2];
|
|
222919
|
+
const dxArrow = last[0] - prev2[0];
|
|
222920
|
+
const dyArrow = last[1] - prev2[1];
|
|
222921
|
+
const head = computeArrowhead(last[0], last[1], dxArrow, dyArrow, arrowDataSize);
|
|
222922
|
+
if (head) {
|
|
222923
|
+
layers.push(new PolygonLayer({
|
|
222924
|
+
...tipsBase,
|
|
222925
|
+
id: `annotation-polyline-end-arrow-${uid2}-${i2}`,
|
|
222926
|
+
data: [{ polygon: head }],
|
|
222927
|
+
getPolygon: (d) => d.polygon,
|
|
222928
|
+
filled: true,
|
|
222929
|
+
stroked: false,
|
|
222930
|
+
getFillColor: strokeColor
|
|
222931
|
+
}));
|
|
222932
|
+
}
|
|
222933
|
+
}
|
|
222934
|
+
if (markerStart === "Tick" && tipsOpacity > 0) {
|
|
222935
|
+
const [x02, y02] = points2[0];
|
|
222936
|
+
const [x12, y12] = points2[1];
|
|
222937
|
+
const tick2 = computeTickCap(x02, y02, x02 - x12, y02 - y12, arrowDataSize);
|
|
222938
|
+
if (tick2) {
|
|
222939
|
+
layers.push(new PathLayer({
|
|
222940
|
+
...tipsBase,
|
|
222941
|
+
id: `annotation-polyline-start-tick-${uid2}-${i2}`,
|
|
222942
|
+
data: [{ path: tick2 }],
|
|
222943
|
+
getPath: (d) => d.path,
|
|
222944
|
+
getColor: strokeColor,
|
|
222945
|
+
getWidth: strokeWidth,
|
|
222946
|
+
widthUnits: "pixels",
|
|
222947
|
+
capRounded: true
|
|
222948
|
+
}));
|
|
222949
|
+
}
|
|
222950
|
+
}
|
|
222951
|
+
if (markerEnd === "Tick" && tipsOpacity > 0) {
|
|
222952
|
+
const last = points2[points2.length - 1];
|
|
222953
|
+
const prev2 = points2[points2.length - 2];
|
|
222954
|
+
const dxTick = last[0] - prev2[0];
|
|
222955
|
+
const dyTick = last[1] - prev2[1];
|
|
222956
|
+
const tick2 = computeTickCap(last[0], last[1], dxTick, dyTick, arrowDataSize);
|
|
222957
|
+
if (tick2) {
|
|
222958
|
+
layers.push(new PathLayer({
|
|
222959
|
+
...tipsBase,
|
|
222960
|
+
id: `annotation-polyline-end-tick-${uid2}-${i2}`,
|
|
222961
|
+
data: [{ path: tick2 }],
|
|
222962
|
+
getPath: (d) => d.path,
|
|
222963
|
+
getColor: strokeColor,
|
|
222964
|
+
getWidth: strokeWidth,
|
|
222965
|
+
widthUnits: "pixels",
|
|
222966
|
+
capRounded: true
|
|
222967
|
+
}));
|
|
222968
|
+
}
|
|
222969
|
+
}
|
|
222970
|
+
if (shape2.text) {
|
|
222971
|
+
const pos = shape2.textPosition ?? "start";
|
|
222972
|
+
const bufferPx = shape2.textBufferPx ?? 8;
|
|
222973
|
+
let textPt;
|
|
222974
|
+
let dirX;
|
|
222975
|
+
let dirY;
|
|
222976
|
+
if (pos === "end") {
|
|
222977
|
+
const last = points2[points2.length - 1];
|
|
222978
|
+
const prev2 = points2[points2.length - 2];
|
|
222979
|
+
textPt = last;
|
|
222980
|
+
dirX = last[0] - prev2[0];
|
|
222981
|
+
dirY = last[1] - prev2[1];
|
|
222982
|
+
} else if (pos === "middle") {
|
|
222983
|
+
const mx = points2.reduce((s2, p) => s2 + p[0], 0) / points2.length;
|
|
222984
|
+
const my = points2.reduce((s2, p) => s2 + p[1], 0) / points2.length;
|
|
222985
|
+
textPt = [mx, my];
|
|
222986
|
+
dirX = 0;
|
|
222987
|
+
dirY = 0;
|
|
222988
|
+
} else {
|
|
222989
|
+
[textPt] = points2;
|
|
222990
|
+
dirX = points2[0][0] - points2[1][0];
|
|
222991
|
+
dirY = points2[0][1] - points2[1][1];
|
|
222992
|
+
}
|
|
222993
|
+
const [textX, textY] = textPt;
|
|
222994
|
+
const lenT = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
222995
|
+
let polylinePixelOffset = [0, 0];
|
|
222996
|
+
let polylineTextAnchor = "middle";
|
|
222997
|
+
let polylineAlignmentBaseline = pos === "middle" ? "center" : "bottom";
|
|
222998
|
+
if (lenT > 0) {
|
|
222999
|
+
const uxT = dirX / lenT;
|
|
223000
|
+
const uyT = dirY / lenT;
|
|
223001
|
+
const offX = uxT * bufferPx;
|
|
223002
|
+
const offY = uyT * bufferPx;
|
|
223003
|
+
polylinePixelOffset = [offX, offY];
|
|
223004
|
+
if (Math.abs(offX) >= Math.abs(offY)) {
|
|
223005
|
+
polylineTextAnchor = offX > 0 ? "start" : "end";
|
|
223006
|
+
}
|
|
223007
|
+
if (Math.abs(offY) >= Math.abs(offX)) {
|
|
223008
|
+
polylineAlignmentBaseline = offY > 0 ? "top" : "bottom";
|
|
223009
|
+
}
|
|
223010
|
+
}
|
|
223011
|
+
if (labelOpacity <= 0)
|
|
223012
|
+
return;
|
|
223013
|
+
layers.push(new TextLayer({
|
|
223014
|
+
...labelBase,
|
|
223015
|
+
...labelProps,
|
|
223016
|
+
id: `annotation-polyline-text-${uid2}-${i2}`,
|
|
223017
|
+
data: [{ position: [textX, textY], text: shape2.text }],
|
|
223018
|
+
getPosition: (d) => d.position,
|
|
223019
|
+
getText: (d) => d.text,
|
|
223020
|
+
getColor: strokeColor,
|
|
223021
|
+
getSize: LABEL_FONT_SIZE,
|
|
223022
|
+
sizeUnits: "pixels",
|
|
223023
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
223024
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
223025
|
+
getPixelOffset: polylinePixelOffset,
|
|
223026
|
+
getTextAnchor: polylineTextAnchor,
|
|
223027
|
+
getAlignmentBaseline: polylineAlignmentBaseline
|
|
223028
|
+
}));
|
|
223029
|
+
}
|
|
223030
|
+
}
|
|
223031
|
+
});
|
|
223032
|
+
if (dotShapes.length > 0) {
|
|
223033
|
+
layers.push(new ScatterplotLayer({
|
|
223034
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
223035
|
+
id: "annotation-dots",
|
|
223036
|
+
data: dotShapes.map(({ shape: s2, alpha: alpha2 }) => ({
|
|
223037
|
+
position: getShapeCentroid(s2),
|
|
223038
|
+
color: [...s2.strokeColor ?? [255, 255, 255], alpha2]
|
|
223039
|
+
})),
|
|
223040
|
+
getPosition: (d) => d.position,
|
|
223041
|
+
getFillColor: (d) => d.color,
|
|
223042
|
+
getRadius: 4,
|
|
223043
|
+
radiusUnits: "pixels",
|
|
223044
|
+
filled: true,
|
|
223045
|
+
stroked: false
|
|
223046
|
+
}));
|
|
223047
|
+
}
|
|
223048
|
+
if (clusterDotShapes.length > 0) {
|
|
223049
|
+
const clusters = computeClusters(clusterDotShapes, zoom2);
|
|
223050
|
+
layers.push(new ScatterplotLayer({
|
|
223051
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
223052
|
+
id: "annotation-clusters",
|
|
223053
|
+
data: clusters,
|
|
223054
|
+
getPosition: (d) => d.position,
|
|
223055
|
+
getFillColor: (d) => [...d.color, 180],
|
|
223056
|
+
getRadius: (d) => Math.max(6, 4 + Math.sqrt(d.count) * 2),
|
|
223057
|
+
radiusUnits: "pixels",
|
|
223058
|
+
filled: true,
|
|
223059
|
+
stroked: true,
|
|
223060
|
+
getLineColor: (d) => [...d.color, 220],
|
|
223061
|
+
lineWidthMinPixels: 1.5
|
|
223062
|
+
}));
|
|
223063
|
+
const multiClusters = clusters.filter((c2) => c2.count > 1);
|
|
223064
|
+
if (multiClusters.length > 0) {
|
|
223065
|
+
layers.push(new TextLayer({
|
|
223066
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
223067
|
+
id: "annotation-cluster-counts",
|
|
223068
|
+
data: multiClusters,
|
|
223069
|
+
getPosition: (d) => d.position,
|
|
223070
|
+
getText: (d) => String(d.count),
|
|
223071
|
+
getColor: [255, 255, 255],
|
|
223072
|
+
getSize: 10,
|
|
223073
|
+
sizeUnits: "pixels",
|
|
223074
|
+
fontWeight: "bold",
|
|
223075
|
+
getTextAnchor: "middle",
|
|
223076
|
+
getAlignmentBaseline: "center"
|
|
223077
|
+
}));
|
|
223078
|
+
}
|
|
223079
|
+
}
|
|
223080
|
+
const measureLayers = [];
|
|
223081
|
+
shapes.forEach((shape2) => {
|
|
223082
|
+
if (!shape2.showMeasure)
|
|
223083
|
+
return;
|
|
223084
|
+
const mIsSelected = shape2.uid === selectedShapeUid;
|
|
223085
|
+
const label2 = getMeasurementLabel(shape2, physicalPixelSize, viewType);
|
|
223086
|
+
if (!label2)
|
|
223087
|
+
return;
|
|
223088
|
+
const color2 = shape2.strokeColor ?? [255, 255, 255];
|
|
223089
|
+
let mShapeOpacity = 1;
|
|
223090
|
+
let mLabelFactor = 0;
|
|
223091
|
+
if (mIsSelected || !semanticZoom || authoredZoom === null) {
|
|
223092
|
+
mLabelFactor = 1;
|
|
223093
|
+
} else {
|
|
223094
|
+
const mZoomRatio = 2 ** (zoom2 - authoredZoom);
|
|
223095
|
+
if (mZoomRatio < RATIO_DOT)
|
|
223096
|
+
return;
|
|
223097
|
+
if (mZoomRatio < RATIO_GEO_FADE) {
|
|
223098
|
+
mShapeOpacity = (mZoomRatio - RATIO_DOT) / (RATIO_GEO_FADE - RATIO_DOT);
|
|
223099
|
+
}
|
|
223100
|
+
if (mZoomRatio >= RATIO_LABEL_FULL) {
|
|
223101
|
+
mLabelFactor = 1;
|
|
223102
|
+
} else if (mZoomRatio >= RATIO_LABEL) {
|
|
223103
|
+
mLabelFactor = (mZoomRatio - RATIO_LABEL) / (RATIO_LABEL_FULL - RATIO_LABEL);
|
|
223104
|
+
}
|
|
223105
|
+
}
|
|
223106
|
+
const measureOpacity = mShapeOpacity * mLabelFactor;
|
|
223107
|
+
if (measureOpacity <= 0)
|
|
223108
|
+
return;
|
|
223109
|
+
const base2 = {
|
|
223110
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
223111
|
+
opacity: measureOpacity,
|
|
223112
|
+
getText: (d) => d.text,
|
|
223113
|
+
getPosition: (d) => d.position,
|
|
223114
|
+
getColor: color2,
|
|
223115
|
+
getSize: 13,
|
|
223116
|
+
sizeUnits: "pixels",
|
|
223117
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
223118
|
+
fontWeight: "bold",
|
|
223119
|
+
// 'auto' builds the font atlas from the actual rendered characters (e.g. µ, ²)
|
|
223120
|
+
// instead of deck.gl's default ASCII-only atlas.
|
|
223121
|
+
characterSet: "auto",
|
|
223122
|
+
...shape2.measureBackground ? {
|
|
223123
|
+
background: true,
|
|
223124
|
+
getBackgroundColor: textBgColor(color2),
|
|
223125
|
+
backgroundPadding: [3, 1, 3, 2]
|
|
223126
|
+
} : {}
|
|
223127
|
+
};
|
|
223128
|
+
if (shape2.type === "line") {
|
|
223129
|
+
const mx = ((shape2.x1 ?? 0) + (shape2.x2 ?? 0)) / 2;
|
|
223130
|
+
const my = ((shape2.y1 ?? 0) + (shape2.y2 ?? 0)) / 2;
|
|
223131
|
+
const dx = (shape2.x2 ?? 0) - (shape2.x1 ?? 0);
|
|
223132
|
+
const dy = (shape2.y2 ?? 0) - (shape2.y1 ?? 0);
|
|
223133
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
223134
|
+
if (len2 === 0)
|
|
223135
|
+
return;
|
|
223136
|
+
const perp = pickBelowPerp(dx / len2, dy / len2);
|
|
223137
|
+
const angle2 = readableAngle(Math.atan2(dy, dx) * 180 / Math.PI);
|
|
223138
|
+
measureLayers.push(new TextLayer({
|
|
223139
|
+
...base2,
|
|
223140
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
223141
|
+
data: [{ position: [mx, my], text: label2 }],
|
|
223142
|
+
getAngle: -angle2,
|
|
223143
|
+
getTextAnchor: "middle",
|
|
223144
|
+
getAlignmentBaseline: "center",
|
|
223145
|
+
getPixelOffset: [perp[0] * 16, perp[1] * 16]
|
|
223146
|
+
}));
|
|
223147
|
+
} else if (shape2.type === "polyline" && shape2.points?.length >= 2) {
|
|
223148
|
+
const pts = shape2.points;
|
|
223149
|
+
const mi = Math.floor((pts.length - 1) / 2);
|
|
223150
|
+
const [ax, ay] = pts[mi];
|
|
223151
|
+
const [bx, by] = pts[mi + 1];
|
|
223152
|
+
const dx = bx - ax;
|
|
223153
|
+
const dy = by - ay;
|
|
223154
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
223155
|
+
if (len2 === 0)
|
|
223156
|
+
return;
|
|
223157
|
+
const perp = pickBelowPerp(dx / len2, dy / len2);
|
|
223158
|
+
const angle2 = readableAngle(Math.atan2(dy, dx) * 180 / Math.PI);
|
|
223159
|
+
measureLayers.push(new TextLayer({
|
|
223160
|
+
...base2,
|
|
223161
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
223162
|
+
data: [{ position: [(ax + bx) / 2, (ay + by) / 2], text: label2 }],
|
|
223163
|
+
getAngle: -angle2,
|
|
223164
|
+
getTextAnchor: "middle",
|
|
223165
|
+
getAlignmentBaseline: "center",
|
|
223166
|
+
getPixelOffset: [perp[0] * 16, perp[1] * 16]
|
|
223167
|
+
}));
|
|
223168
|
+
} else if (shape2.type === "rectangle") {
|
|
223169
|
+
const x02 = shape2.x ?? 0;
|
|
223170
|
+
const y02 = shape2.y ?? 0;
|
|
223171
|
+
const w2 = shape2.width ?? 0;
|
|
223172
|
+
const h2 = shape2.height ?? 0;
|
|
223173
|
+
const rx = x02 + (w2 >= 0 ? w2 : 0);
|
|
223174
|
+
const ry = y02 + (h2 >= 0 ? h2 : 0);
|
|
223175
|
+
measureLayers.push(new TextLayer({
|
|
223176
|
+
...base2,
|
|
223177
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
223178
|
+
data: [{ position: [rx, ry], text: label2 }],
|
|
223179
|
+
getTextAnchor: "end",
|
|
223180
|
+
getAlignmentBaseline: "bottom",
|
|
223181
|
+
getPixelOffset: [-6, -6]
|
|
223182
|
+
}));
|
|
223183
|
+
} else if (shape2.type === "ellipse") {
|
|
223184
|
+
const cx = shape2.x1 ?? 0;
|
|
223185
|
+
const cy = shape2.y1 ?? 0;
|
|
223186
|
+
const ry = Math.abs(shape2.radiusY ?? 0);
|
|
223187
|
+
measureLayers.push(new TextLayer({
|
|
223188
|
+
...base2,
|
|
223189
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
223190
|
+
data: [{ position: [cx, cy + ry], text: label2 }],
|
|
223191
|
+
getTextAnchor: "middle",
|
|
223192
|
+
getAlignmentBaseline: "top",
|
|
223193
|
+
getPixelOffset: [0, 8]
|
|
223194
|
+
}));
|
|
223195
|
+
} else if (shape2.type === "polygon" && shape2.points?.length >= 3) {
|
|
223196
|
+
const xs = shape2.points.map((p) => p[0]);
|
|
223197
|
+
const ys = shape2.points.map((p) => p[1]);
|
|
223198
|
+
const cx = (Math.min(...xs) + Math.max(...xs)) / 2;
|
|
223199
|
+
const maxY2 = Math.max(...ys);
|
|
223200
|
+
measureLayers.push(new TextLayer({
|
|
223201
|
+
...base2,
|
|
223202
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
223203
|
+
data: [{ position: [cx, maxY2], text: label2 }],
|
|
223204
|
+
getTextAnchor: "middle",
|
|
223205
|
+
getAlignmentBaseline: "top",
|
|
223206
|
+
getPixelOffset: [0, 8]
|
|
223207
|
+
}));
|
|
223208
|
+
}
|
|
223209
|
+
});
|
|
223210
|
+
return [...selectionLayers, ...layers, ...measureLayers];
|
|
223211
|
+
}
|
|
223212
|
+
const defaultProps = {
|
|
223213
|
+
// Array of annotation shape objects (see annotationShapeObj in @vitessce/schemas).
|
|
223214
|
+
data: { type: "object", value: [], compare: true },
|
|
223215
|
+
// UID of the shape to highlight with a selection halo.
|
|
223216
|
+
selectedShapeUid: { type: "string", value: null },
|
|
223217
|
+
// { x, y, unit } used to format measurement labels in physical units.
|
|
223218
|
+
physicalPixelSize: { type: "object", value: null, compare: true },
|
|
223219
|
+
// The zoom level at which the shapes were authored (reference for semantic zoom).
|
|
223220
|
+
authoredZoom: { type: "number", value: null },
|
|
223221
|
+
// Whether to apply semantic zoom (level-of-detail) based on authoredZoom.
|
|
223222
|
+
semanticZoom: { type: "boolean", value: true },
|
|
223223
|
+
// The view type in which the layer is rendered (affects measurement label formatting).
|
|
223224
|
+
viewType: { type: "string", value: ViewType$1.SPATIAL },
|
|
223225
|
+
// In-progress shape being drawn, as { type, vertices }.
|
|
223226
|
+
inProgressShape: { type: "object", value: null, compare: true },
|
|
223227
|
+
// Current mouse position (in data coordinates) while drawing.
|
|
223228
|
+
hoverCoord: { type: "array", value: null, compare: true },
|
|
223229
|
+
// Stroke color [r, g, b] of the in-progress shape preview.
|
|
223230
|
+
previewStrokeColor: { type: "color", value: [255, 255, 0] }
|
|
223231
|
+
};
|
|
223232
|
+
class AnnotationLayer extends CompositeLayer {
|
|
223233
|
+
// The semantic zoom and arrowhead sizes depend on the current zoom level,
|
|
223234
|
+
// so the sublayers must also be re-rendered when the viewport changes.
|
|
223235
|
+
// eslint-disable-next-line class-methods-use-this
|
|
223236
|
+
shouldUpdateState({ changeFlags }) {
|
|
223237
|
+
return changeFlags.propsOrDataChanged || changeFlags.viewportChanged;
|
|
223238
|
+
}
|
|
223239
|
+
/**
|
|
223240
|
+
* Prefix the sublayer ID with this layer's ID (so that multiple
|
|
223241
|
+
* AnnotationLayers can co-exist), and combine this layer's
|
|
223242
|
+
* opacity with the per-shape opacity of the sublayer.
|
|
223243
|
+
* Note: we avoid getSubLayerProps here, since it would
|
|
223244
|
+
* overwrite the sublayer extensions (e.g., PathStyleExtension)
|
|
223245
|
+
* and opacity values.
|
|
223246
|
+
* @param {object} layer A DeckGL layer instance.
|
|
223247
|
+
* @returns {object} The cloned layer instance.
|
|
223248
|
+
*/
|
|
223249
|
+
wrapSubLayer(layer) {
|
|
223250
|
+
const { id: id2, opacity: opacity2, pickable, visible } = this.props;
|
|
223251
|
+
return layer.clone({
|
|
223252
|
+
id: `${id2}-${layer.id}`,
|
|
223253
|
+
opacity: layer.props.opacity * opacity2,
|
|
223254
|
+
pickable,
|
|
223255
|
+
visible
|
|
223256
|
+
});
|
|
223257
|
+
}
|
|
223258
|
+
renderLayers() {
|
|
223259
|
+
const { data: data2, selectedShapeUid, physicalPixelSize, authoredZoom, semanticZoom, viewType, inProgressShape, hoverCoord, previewStrokeColor } = this.props;
|
|
223260
|
+
const zoom2 = this.context.viewport?.zoom ?? 0;
|
|
223261
|
+
const visibleShapes = (data2 ?? []).filter((shape2) => shape2.visible !== false);
|
|
223262
|
+
const annotationLayers = createAnnotationLayers(visibleShapes, zoom2, selectedShapeUid, physicalPixelSize, authoredZoom, semanticZoom, viewType);
|
|
223263
|
+
const previewLayer = createPreviewLayer(inProgressShape, hoverCoord, previewStrokeColor.slice(0, 3));
|
|
223264
|
+
return [
|
|
223265
|
+
...annotationLayers,
|
|
223266
|
+
...previewLayer ? [previewLayer] : []
|
|
223267
|
+
].map((layer) => this.wrapSubLayer(layer));
|
|
223268
|
+
}
|
|
223269
|
+
}
|
|
223270
|
+
AnnotationLayer.layerName = "AnnotationLayer";
|
|
223271
|
+
AnnotationLayer.defaultProps = defaultProps;
|
|
223272
|
+
const useStyles$w = makeStyles()(() => ({
|
|
221903
223273
|
toolButton: {
|
|
221904
223274
|
display: "inline-flex",
|
|
221905
223275
|
"&:active": {
|
|
@@ -221961,12 +223331,12 @@ const useStyles$v = makeStyles()(() => ({
|
|
|
221961
223331
|
}));
|
|
221962
223332
|
function IconTool(props) {
|
|
221963
223333
|
const { alt, onClick, isActive: isActive2, children: children3 } = props;
|
|
221964
|
-
const { classes: classes2 } = useStyles$
|
|
223334
|
+
const { classes: classes2 } = useStyles$w();
|
|
221965
223335
|
return jsx$1("button", { className: clsx(classes2.toolIcon, { [classes2.toolActive]: isActive2 }), onClick, type: "button", title: alt, children: children3 });
|
|
221966
223336
|
}
|
|
221967
223337
|
function IconButton(props) {
|
|
221968
223338
|
const { alt, onClick, children: children3 } = props;
|
|
221969
|
-
const { classes: classes2 } = useStyles$
|
|
223339
|
+
const { classes: classes2 } = useStyles$w();
|
|
221970
223340
|
return jsx$1("button", { className: clsx(classes2.toolIcon, classes2.toolButton), onClick, type: "button", title: alt, children: children3 });
|
|
221971
223341
|
}
|
|
221972
223342
|
function ToolMenu(props) {
|
|
@@ -221974,7 +223344,7 @@ function ToolMenu(props) {
|
|
|
221974
223344
|
const lassoIconAltText = "Select lasso";
|
|
221975
223345
|
const { setActiveTool, activeTool, visibleTools = { pan: true, selectLasso: true, recenter: true }, recenterOnClick = () => {
|
|
221976
223346
|
} } = props;
|
|
221977
|
-
const { classes: classes2 } = useStyles$
|
|
223347
|
+
const { classes: classes2 } = useStyles$w();
|
|
221978
223348
|
const onRecenterButtonCLick = () => {
|
|
221979
223349
|
recenterOnClick();
|
|
221980
223350
|
};
|
|
@@ -222456,11 +223826,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
222456
223826
|
this.cellSetsLabelPrevZoom = null;
|
|
222457
223827
|
this.cellSetsLayers = [];
|
|
222458
223828
|
this.contourLayers = [];
|
|
223829
|
+
this.annotationLayer = null;
|
|
222459
223830
|
this.onUpdateCellsData();
|
|
222460
223831
|
this.onUpdateCellsLayer();
|
|
222461
223832
|
this.onUpdateCellSetsLayers();
|
|
222462
223833
|
this.onUpdateStratifiedData();
|
|
222463
223834
|
this.onUpdateContourLayers();
|
|
223835
|
+
this.onUpdateAnnotationLayer();
|
|
222464
223836
|
}
|
|
222465
223837
|
// Want to support multiple types of contour layers
|
|
222466
223838
|
// - One layer for all data points (no filtering)
|
|
@@ -222524,6 +223896,21 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
222524
223896
|
}));
|
|
222525
223897
|
return layers;
|
|
222526
223898
|
}
|
|
223899
|
+
createAnnotationLayer() {
|
|
223900
|
+
const { annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection } = this.props;
|
|
223901
|
+
return new AnnotationLayer({
|
|
223902
|
+
data: annotationShapes,
|
|
223903
|
+
visible: annotationOverlayVisible,
|
|
223904
|
+
semanticZoom: annotationSemanticZoom,
|
|
223905
|
+
selectedShapeUid: annotationShapeSelection,
|
|
223906
|
+
viewType: ViewType$1.SCATTERPLOT
|
|
223907
|
+
// TODO: is this needed?
|
|
223908
|
+
// TODO: these are view-level properties, rather than layer-level.
|
|
223909
|
+
// annotationTransitionDuration,
|
|
223910
|
+
// annotationEditable,
|
|
223911
|
+
// Other coordination types related to editing...
|
|
223912
|
+
});
|
|
223913
|
+
}
|
|
222527
223914
|
createCellsLayer() {
|
|
222528
223915
|
const {
|
|
222529
223916
|
obsEmbeddingIndex: obsIndex,
|
|
@@ -222657,12 +224044,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
222657
224044
|
], flipYTooltip, this.props.onSelectionBusy);
|
|
222658
224045
|
}
|
|
222659
224046
|
getLayers() {
|
|
222660
|
-
const { cellsLayer, cellSetsLayers, contourLayers } = this;
|
|
224047
|
+
const { cellsLayer, cellSetsLayers, contourLayers, annotationLayer } = this;
|
|
222661
224048
|
return [
|
|
222662
224049
|
cellsLayer,
|
|
222663
224050
|
...contourLayers,
|
|
222664
224051
|
...cellSetsLayers,
|
|
222665
|
-
this.createSelectionLayer()
|
|
224052
|
+
this.createSelectionLayer(),
|
|
224053
|
+
annotationLayer
|
|
222666
224054
|
];
|
|
222667
224055
|
}
|
|
222668
224056
|
/**
|
|
@@ -222699,6 +224087,14 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
222699
224087
|
this.cellsLayer = null;
|
|
222700
224088
|
}
|
|
222701
224089
|
}
|
|
224090
|
+
onUpdateAnnotationLayer() {
|
|
224091
|
+
const { annotationShapes } = this.props;
|
|
224092
|
+
if (annotationShapes) {
|
|
224093
|
+
this.annotationLayer = this.createAnnotationLayer();
|
|
224094
|
+
} else {
|
|
224095
|
+
this.annotationLayer = null;
|
|
224096
|
+
}
|
|
224097
|
+
}
|
|
222702
224098
|
onUpdateStratifiedData() {
|
|
222703
224099
|
const { stratifiedData } = this.props;
|
|
222704
224100
|
if (stratifiedData) {
|
|
@@ -222814,6 +224210,16 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
222814
224210
|
this.onUpdateCellSetsLayers(true);
|
|
222815
224211
|
forceUpdate = true;
|
|
222816
224212
|
}
|
|
224213
|
+
if ([
|
|
224214
|
+
"annotationShapes",
|
|
224215
|
+
"annotationOverlayVisible",
|
|
224216
|
+
"annotationSemanticZoom",
|
|
224217
|
+
"annotationTransitionDuration",
|
|
224218
|
+
"annotationEditable"
|
|
224219
|
+
].some(shallowDiff2)) {
|
|
224220
|
+
this.onUpdateAnnotationLayer();
|
|
224221
|
+
forceUpdate = true;
|
|
224222
|
+
}
|
|
222817
224223
|
if (forceUpdate) {
|
|
222818
224224
|
this.forceUpdate();
|
|
222819
224225
|
}
|
|
@@ -223169,7 +224575,7 @@ function ScatterplotOptions(props) {
|
|
|
223169
224575
|
id: `feature-aggregation-strategy-${scatterplotOptionsId}`
|
|
223170
224576
|
}, children: FEATURE_AGGREGATION_STRATEGIES$2.map((opt) => jsx$1("option", { value: opt, children: capitalize$3(opt) }, opt)) }) })] }) : null] });
|
|
223171
224577
|
}
|
|
223172
|
-
const useStyles$
|
|
224578
|
+
const useStyles$v = makeStyles()((theme) => ({
|
|
223173
224579
|
tooltipAnchor: {
|
|
223174
224580
|
position: "relative",
|
|
223175
224581
|
width: "0px",
|
|
@@ -223200,7 +224606,7 @@ const useStyles$u = makeStyles()((theme) => ({
|
|
|
223200
224606
|
function Tooltip3(props) {
|
|
223201
224607
|
const { x: x2, y: y2, parentWidth, parentHeight, children: children3 } = props;
|
|
223202
224608
|
const ref2 = useRef();
|
|
223203
|
-
const { classes: classes2 } = useStyles$
|
|
224609
|
+
const { classes: classes2 } = useStyles$v();
|
|
223204
224610
|
const [placementX, setPlacementX] = useState("start");
|
|
223205
224611
|
const [placementY, setPlacementY] = useState("bottom");
|
|
223206
224612
|
const getTooltipContainer = useVitessceContainer(ref2);
|
|
@@ -223216,7 +224622,7 @@ function Tooltip3(props) {
|
|
|
223216
224622
|
}, [x2, y2, parentWidth, parentHeight]);
|
|
223217
224623
|
return jsx$1("div", { ref: ref2, className: classes2.tooltipAnchor, children: ref2 && ref2.current ? jsx$1(Popper, { open: true, anchorEl: ref2.current, container: getTooltipContainer, transition: true, placement: `${placementY}-${placementX}`, children: jsx$1(Paper, { elevation: 8, className: classes2.tooltipContent, children: children3 }) }) : null });
|
|
223218
224624
|
}
|
|
223219
|
-
const useStyles$
|
|
224625
|
+
const useStyles$u = makeStyles()((theme) => ({
|
|
223220
224626
|
cellEmphasisCrosshair: {
|
|
223221
224627
|
zIndex: 50,
|
|
223222
224628
|
position: "absolute",
|
|
@@ -223227,7 +224633,7 @@ const useStyles$t = makeStyles()((theme) => ({
|
|
|
223227
224633
|
}));
|
|
223228
224634
|
function Tooltip2D(props) {
|
|
223229
224635
|
const { parentUuid, sourceUuid, x: x2, y: y2, parentWidth, parentHeight, children: children3 } = props;
|
|
223230
|
-
const { classes: classes2 } = useStyles$
|
|
224636
|
+
const { classes: classes2 } = useStyles$u();
|
|
223231
224637
|
if (x2 < 0 || x2 > parentWidth || y2 < 0 || y2 > parentHeight) {
|
|
223232
224638
|
return null;
|
|
223233
224639
|
}
|
|
@@ -227139,7 +228545,7 @@ function getXlinkHref(cmap) {
|
|
|
227139
228545
|
const xlinkHref = ramp(color2.copy().domain(quantize$3(interpolate$1$1(0, 1), n3))).toDataURL();
|
|
227140
228546
|
return xlinkHref;
|
|
227141
228547
|
}
|
|
227142
|
-
const useStyles$
|
|
228548
|
+
const useStyles$t = makeStyles()(() => ({
|
|
227143
228549
|
legend: {
|
|
227144
228550
|
position: "relative",
|
|
227145
228551
|
// Needed for absolute positioning of slider overlay
|
|
@@ -227336,7 +228742,7 @@ function Legend(props) {
|
|
|
227336
228742
|
contourThresholds
|
|
227337
228743
|
} = props;
|
|
227338
228744
|
const svgRef = useRef(null);
|
|
227339
|
-
const { classes: classes2 } = useStyles$
|
|
228745
|
+
const { classes: classes2 } = useStyles$t();
|
|
227340
228746
|
const [localRange, setLocalRange] = useState(featureValueColormapRange);
|
|
227341
228747
|
useEffect(() => {
|
|
227342
228748
|
setLocalRange(featureValueColormapRange);
|
|
@@ -227670,7 +229076,7 @@ function Legend(props) {
|
|
|
227670
229076
|
}
|
|
227671
229077
|
} })] })] });
|
|
227672
229078
|
}
|
|
227673
|
-
const useStyles$
|
|
229079
|
+
const useStyles$s = makeStyles()(() => ({
|
|
227674
229080
|
multiLegend: {
|
|
227675
229081
|
position: "absolute",
|
|
227676
229082
|
top: "0px",
|
|
@@ -227697,7 +229103,7 @@ function MultiLegend(props) {
|
|
|
227697
229103
|
pointLayerCoordination,
|
|
227698
229104
|
pointMultiIndicesData
|
|
227699
229105
|
} = props;
|
|
227700
|
-
const { classes: classes2 } = useStyles$
|
|
229106
|
+
const { classes: classes2 } = useStyles$s();
|
|
227701
229107
|
const reversedSegmentationLayerScopes = useMemo$1(() => [...segmentationLayerScopes || []].reverse(), [segmentationLayerScopes]);
|
|
227702
229108
|
const reversedSpotLayerScopes = useMemo$1(() => [...spotLayerScopes || []].reverse(), [spotLayerScopes]);
|
|
227703
229109
|
const reversedPointLayerScopes = useMemo$1(() => [...pointLayerScopes || []].reverse(), [pointLayerScopes]);
|
|
@@ -227790,7 +229196,7 @@ function MultiLegend(props) {
|
|
|
227790
229196
|
}) : null;
|
|
227791
229197
|
}) : null] });
|
|
227792
229198
|
}
|
|
227793
|
-
const useStyles$
|
|
229199
|
+
const useStyles$r = makeStyles()(() => ({
|
|
227794
229200
|
channelNamesLegendContainer: {
|
|
227795
229201
|
position: "absolute",
|
|
227796
229202
|
bottom: "0px",
|
|
@@ -227813,7 +229219,7 @@ const useStyles$q = makeStyles()(() => ({
|
|
|
227813
229219
|
}));
|
|
227814
229220
|
function ChannelNamesLegend(props) {
|
|
227815
229221
|
const { images, imageLayerScopes, imageLayerCoordination, imageChannelScopesByLayer, imageChannelCoordination } = props;
|
|
227816
|
-
const { classes: classes2 } = useStyles$
|
|
229222
|
+
const { classes: classes2 } = useStyles$r();
|
|
227817
229223
|
const reversedImageLayerScopes = useMemo$1(() => [...imageLayerScopes || []].reverse(), [imageLayerScopes]);
|
|
227818
229224
|
return jsx$1("div", { className: classes2.channelNamesLegendContainer, children: imageLayerScopes ? reversedImageLayerScopes.map((layerScope) => {
|
|
227819
229225
|
const layerCoordination = imageLayerCoordination[0][layerScope];
|
|
@@ -227843,7 +229249,6 @@ const DEFAULT_FEATURE_AGGREGATION_STRATEGY$3 = "first";
|
|
|
227843
229249
|
function EmbeddingScatterplotSubscriber(props) {
|
|
227844
229250
|
const {
|
|
227845
229251
|
uuid: uuid2,
|
|
227846
|
-
coordinationScopes: coordinationScopesRaw,
|
|
227847
229252
|
closeButtonVisible,
|
|
227848
229253
|
downloadButtonVisible,
|
|
227849
229254
|
removeGridComponent,
|
|
@@ -227859,16 +229264,23 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
227859
229264
|
circleScaleFactor = 0.8
|
|
227860
229265
|
} = props;
|
|
227861
229266
|
const loaders = useLoaders();
|
|
227862
|
-
const
|
|
229267
|
+
const [
|
|
229268
|
+
// eslint-disable-next-line no-unused-vars
|
|
229269
|
+
coordinationScopes,
|
|
229270
|
+
_coordinationScopesBy,
|
|
229271
|
+
coordinationValues
|
|
229272
|
+
] = useViewMapping(uuid2);
|
|
227863
229273
|
const setComponentHover = useSetComponentHover();
|
|
227864
229274
|
const setComponentViewInfo = useSetComponentViewInfo(uuid2);
|
|
227865
|
-
|
|
227866
|
-
const { embeddingZoom:
|
|
229275
|
+
useAnnotationFrameCoordination(uuid2, coordinationScopes, coordinationValues);
|
|
229276
|
+
const [{ dataset, obsType, featureType, featureValueType, sampleType, embeddingZoom: zoom2, embeddingTargetX: targetX2, embeddingTargetY: targetY2, embeddingTargetZ: targetZ, embeddingType: mapping, obsFilter: cellFilter, obsHighlight: cellHighlight, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, embeddingObsSetPolygonsVisible: cellSetPolygonsVisible, embeddingObsSetLabelsVisible: cellSetLabelsVisible, embeddingObsSetLabelSize: cellSetLabelSize, embeddingObsRadius: cellRadiusFixed, embeddingObsRadiusMode: cellRadiusMode, embeddingObsOpacity: cellOpacityFixed, embeddingObsOpacityMode: cellOpacityMode, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible, sampleSetSelection: sampleSetSelectionFromCoordination, sampleSetColor, embeddingPointsVisible, embeddingContoursVisible, embeddingContoursFilled, embeddingContourPercentiles: contourPercentiles, contourColorEncoding, contourColor, featureAggregationStrategy, annotationStory, annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationTransitionDuration, annotationEditable }, { setEmbeddingZoom: setZoom, setEmbeddingTargetX: setTargetX, setEmbeddingTargetY: setTargetY, setEmbeddingTargetZ: setTargetZ, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setEmbeddingObsSetPolygonsVisible: setCellSetPolygonsVisible, setEmbeddingObsSetLabelsVisible: setCellSetLabelsVisible, setEmbeddingObsSetLabelSize: setCellSetLabelSize, setEmbeddingObsRadius: setCellRadiusFixed, setEmbeddingObsRadiusMode: setCellRadiusMode, setEmbeddingObsOpacity: setCellOpacityFixed, setEmbeddingObsOpacityMode: setCellOpacityMode, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setTooltipsVisible, setEmbeddingPointsVisible, setEmbeddingContoursVisible, setEmbeddingContoursFilled, setEmbeddingContourPercentiles: setContourPercentiles, setContourColorEncoding, setFeatureAggregationStrategy, setAnnotationStory }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes, coordinationValues, uuid2);
|
|
229277
|
+
const { embeddingZoom: initialZoom, embeddingTargetX: initialTargetX, embeddingTargetY: initialTargetY } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes, coordinationValues);
|
|
227867
229278
|
const observationsLabel = observationsLabelOverride || obsType;
|
|
227868
229279
|
const sampleSetSelection = sampleSetSelectionFromProps || sampleSetSelectionFromCoordination;
|
|
227869
229280
|
const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY$3;
|
|
227870
229281
|
const [width2, height2, deckRef] = useDeckCanvasSize();
|
|
227871
229282
|
const title2 = titleOverride || `Scatterplot (${mapping})`;
|
|
229283
|
+
const [, annotationStoryStatus, annotationStoryUrls, annotationStoryError] = useAnnotationStoryData(loaders, dataset, false, { setAnnotationStory }, { annotationStory }, {});
|
|
227872
229284
|
const [
|
|
227873
229285
|
// eslint-disable-next-line no-unused-vars
|
|
227874
229286
|
obsLabelsTypes,
|
|
@@ -227900,11 +229312,13 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
227900
229312
|
matrixIndicesError,
|
|
227901
229313
|
featureLabelsError,
|
|
227902
229314
|
sampleSetsError,
|
|
227903
|
-
sampleEdgesError
|
|
229315
|
+
sampleEdgesError,
|
|
229316
|
+
annotationStoryError
|
|
227904
229317
|
];
|
|
227905
229318
|
const isReady = useReady([
|
|
227906
229319
|
obsEmbeddingStatus,
|
|
227907
229320
|
obsSetsStatus,
|
|
229321
|
+
annotationStoryStatus,
|
|
227908
229322
|
featureSelectionStatus,
|
|
227909
229323
|
featureLabelsStatus,
|
|
227910
229324
|
expandedFeatureLabelsStatus,
|
|
@@ -227918,7 +229332,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
227918
229332
|
matrixIndicesUrls,
|
|
227919
229333
|
featureLabelsUrls,
|
|
227920
229334
|
sampleSetsUrl,
|
|
227921
|
-
sampleEdgesUrl
|
|
229335
|
+
sampleEdgesUrl,
|
|
229336
|
+
annotationStoryUrls
|
|
227922
229337
|
]);
|
|
227923
229338
|
const [dynamicCellRadius, setDynamicCellRadius] = useState(cellRadiusFixed);
|
|
227924
229339
|
const [isSelectionPending, setIsSelectionPending] = useState(false);
|
|
@@ -228195,7 +229610,13 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
228195
229610
|
embeddingPointsVisible,
|
|
228196
229611
|
embeddingContoursVisible,
|
|
228197
229612
|
circleInfo,
|
|
228198
|
-
featureSelection: geneSelection
|
|
229613
|
+
featureSelection: geneSelection,
|
|
229614
|
+
// Annotation stuff
|
|
229615
|
+
annotationShapes,
|
|
229616
|
+
annotationOverlayVisible,
|
|
229617
|
+
annotationSemanticZoom,
|
|
229618
|
+
annotationTransitionDuration,
|
|
229619
|
+
annotationEditable
|
|
228199
229620
|
}), tooltipsVisible && width2 && height2 ? jsx$1(ScatterplotTooltipSubscriber, { parentUuid: uuid2, obsHighlight: cellHighlight, width: width2, height: height2, getObsInfo: getObsInfo2, featureType, featureLabelsMap }) : null, jsx$1(Legend, {
|
|
228200
229621
|
visible: true,
|
|
228201
229622
|
theme,
|
|
@@ -243356,8 +244777,8 @@ async function getSingleSelectionStats2D({ loader: loader2, selection }) {
|
|
|
243356
244777
|
const filteredSelection = filterSelection(loader2, selection);
|
|
243357
244778
|
const raster = await data2.getRaster({ selection: filteredSelection });
|
|
243358
244779
|
const selectionStats = getChannelStats(raster.data);
|
|
243359
|
-
const { domain: domain2, contrastLimits: slider } = selectionStats;
|
|
243360
|
-
return { domain: domain2, slider };
|
|
244780
|
+
const { domain: domain2, contrastLimits: slider, q1, q3 } = selectionStats;
|
|
244781
|
+
return { domain: domain2, slider, q1, q3 };
|
|
243361
244782
|
}
|
|
243362
244783
|
async function getSingleSelectionStats3D({ loader: loader2, selection }) {
|
|
243363
244784
|
const lowResSource = loader2[loader2.length - 1];
|
|
@@ -243384,7 +244805,9 @@ async function getSingleSelectionStats3D({ loader: loader2, selection }) {
|
|
|
243384
244805
|
slider: [
|
|
243385
244806
|
Math.min(stats0.contrastLimits[0], statsMid.contrastLimits[0], statsTop.contrastLimits[0]),
|
|
243386
244807
|
Math.max(stats0.contrastLimits[1], statsMid.contrastLimits[1], statsTop.contrastLimits[1])
|
|
243387
|
-
]
|
|
244808
|
+
],
|
|
244809
|
+
q1: Math.min(stats0.q1[0], statsMid.q1[0], statsTop.q1[0]),
|
|
244810
|
+
q3: Math.max(stats0.q3[1], statsMid.q3[1], statsTop.q3[1])
|
|
243388
244811
|
};
|
|
243389
244812
|
}
|
|
243390
244813
|
const getSingleSelectionStats = async ({ loader: loader2, selection, use3d }) => {
|
|
@@ -243395,7 +244818,9 @@ const getMultiSelectionStats = async ({ loader: loader2, selections, use3d }) =>
|
|
|
243395
244818
|
const stats = await Promise.all(selections.map((selection) => getSingleSelectionStats({ loader: loader2, selection, use3d })));
|
|
243396
244819
|
const domains = stats.map((stat) => stat.domain);
|
|
243397
244820
|
const sliders = stats.map((stat) => stat.slider);
|
|
243398
|
-
|
|
244821
|
+
const q1s = stats.map((stat) => stat.q1);
|
|
244822
|
+
const q3s = stats.map((stat) => stat.q3);
|
|
244823
|
+
return { domains, sliders, q1s, q3s };
|
|
243399
244824
|
};
|
|
243400
244825
|
function getPhysicalSizeScalingMatrix(loader2) {
|
|
243401
244826
|
const { x: x2, y: y2, z: z2 } = loader2?.meta?.physicalSizes ?? {};
|
|
@@ -247639,6 +249064,7 @@ let Spatial$1 = class Spatial extends AbstractSpatialOrScatterplot {
|
|
|
247639
249064
|
this.obsSegmentationsPolygonLayer = null;
|
|
247640
249065
|
this.obsLocationsLayer = null;
|
|
247641
249066
|
this.neighborhoodsLayer = null;
|
|
249067
|
+
this.annotationLayer = null;
|
|
247642
249068
|
this.layerLoaderSelections = {};
|
|
247643
249069
|
this.randomColorData = {
|
|
247644
249070
|
data: new Uint8Array(2048 * 2048 * 3).map((_, j) => j < 4 ? 0 : Math.round(255 * Math.random())),
|
|
@@ -247660,6 +249086,7 @@ let Spatial$1 = class Spatial extends AbstractSpatialOrScatterplot {
|
|
|
247660
249086
|
this.onUpdateNeighborhoodsData();
|
|
247661
249087
|
this.onUpdateNeighborhoodsLayer();
|
|
247662
249088
|
this.onUpdateImages();
|
|
249089
|
+
this.onUpdateAnnotationLayer();
|
|
247663
249090
|
}
|
|
247664
249091
|
createPolygonSegmentationsLayer(layerDef, hasExplicitPolygons) {
|
|
247665
249092
|
const { stroked, visible, opacity: opacity2, radius: radius2 } = layerDef;
|
|
@@ -247991,7 +249418,7 @@ let Spatial$1 = class Spatial extends AbstractSpatialOrScatterplot {
|
|
|
247991
249418
|
return [];
|
|
247992
249419
|
}
|
|
247993
249420
|
getLayers() {
|
|
247994
|
-
const { imageLayers, obsSegmentationsPolygonLayer, neighborhoodsLayer, obsLocationsLayer, obsSegmentationsBitmaskLayers } = this;
|
|
249421
|
+
const { imageLayers, obsSegmentationsPolygonLayer, neighborhoodsLayer, obsLocationsLayer, obsSegmentationsBitmaskLayers, annotationLayer } = this;
|
|
247995
249422
|
return [
|
|
247996
249423
|
...imageLayers,
|
|
247997
249424
|
...obsSegmentationsBitmaskLayers,
|
|
@@ -247999,7 +249426,8 @@ let Spatial$1 = class Spatial extends AbstractSpatialOrScatterplot {
|
|
|
247999
249426
|
neighborhoodsLayer,
|
|
248000
249427
|
obsLocationsLayer,
|
|
248001
249428
|
this.createScaleBarLayer(),
|
|
248002
|
-
this.createSelectionLayer()
|
|
249429
|
+
this.createSelectionLayer(),
|
|
249430
|
+
annotationLayer
|
|
248003
249431
|
];
|
|
248004
249432
|
}
|
|
248005
249433
|
/**
|
|
@@ -248106,6 +249534,25 @@ let Spatial$1 = class Spatial extends AbstractSpatialOrScatterplot {
|
|
|
248106
249534
|
onUpdateImages() {
|
|
248107
249535
|
this.imageLayers = this.createImageLayers();
|
|
248108
249536
|
}
|
|
249537
|
+
createAnnotationLayer() {
|
|
249538
|
+
const { annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection } = this.props;
|
|
249539
|
+
return new AnnotationLayer({
|
|
249540
|
+
id: "annotation-layer",
|
|
249541
|
+
data: annotationShapes,
|
|
249542
|
+
visible: annotationOverlayVisible,
|
|
249543
|
+
semanticZoom: annotationSemanticZoom,
|
|
249544
|
+
selectedShapeUid: annotationShapeSelection,
|
|
249545
|
+
viewType: ViewType$1.SPATIAL
|
|
249546
|
+
});
|
|
249547
|
+
}
|
|
249548
|
+
onUpdateAnnotationLayer() {
|
|
249549
|
+
const { annotationShapes } = this.props;
|
|
249550
|
+
if (annotationShapes) {
|
|
249551
|
+
this.annotationLayer = this.createAnnotationLayer();
|
|
249552
|
+
} else {
|
|
249553
|
+
this.annotationLayer = null;
|
|
249554
|
+
}
|
|
249555
|
+
}
|
|
248109
249556
|
viewInfoDidUpdate() {
|
|
248110
249557
|
const { obsCentroidsIndex, obsCentroids } = this.props;
|
|
248111
249558
|
super.viewInfoDidUpdate(obsCentroidsIndex, obsCentroids, makeDefaultGetObsCoords$1);
|
|
@@ -248205,6 +249652,15 @@ let Spatial$1 = class Spatial extends AbstractSpatialOrScatterplot {
|
|
|
248205
249652
|
this.onUpdateImages();
|
|
248206
249653
|
forceUpdate = true;
|
|
248207
249654
|
}
|
|
249655
|
+
if ([
|
|
249656
|
+
"annotationShapes",
|
|
249657
|
+
"annotationOverlayVisible",
|
|
249658
|
+
"annotationSemanticZoom",
|
|
249659
|
+
"annotationShapeSelection"
|
|
249660
|
+
].some(shallowDiff2)) {
|
|
249661
|
+
this.onUpdateAnnotationLayer();
|
|
249662
|
+
forceUpdate = true;
|
|
249663
|
+
}
|
|
248208
249664
|
if (forceUpdate) {
|
|
248209
249665
|
this.forceUpdate();
|
|
248210
249666
|
}
|
|
@@ -248304,7 +249760,8 @@ function SpatialSubscriber$1(props) {
|
|
|
248304
249760
|
const loaders = useLoaders();
|
|
248305
249761
|
const setComponentHover = useSetComponentHover();
|
|
248306
249762
|
const setComponentViewInfo = useSetComponentViewInfo(uuid2);
|
|
248307
|
-
|
|
249763
|
+
useAnnotationFrameCoordination(uuid2, coordinationScopes);
|
|
249764
|
+
const [{ dataset, obsType, featureType, featureValueType, spatialZoom: zoom2, spatialTargetX: targetX2, spatialTargetY: targetY2, spatialTargetZ: targetZ, spatialRotationX: rotationX, spatialRotationY: rotationY, spatialRotationZ: rotationZ, spatialRotationOrbit: rotationOrbit, spatialOrbitAxis: orbitAxis, spatialImageLayer: imageLayers, spatialSegmentationLayer: cellsLayer, spatialPointLayer: moleculesLayer, spatialNeighborhoodLayer: neighborhoodsLayer, obsFilter: cellFilter, obsHighlight: cellHighlight, moleculeHighlight, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, spatialAxisFixed, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible, photometricInterpretation: photometricInterpretationFromCoordination, featureAggregationStrategy, annotationStory, annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection }, { setSpatialZoom: setZoom, setSpatialTargetX: setTargetX, setSpatialTargetY: setTargetY, setSpatialTargetZ: setTargetZ, setSpatialRotationX: setRotationX, setSpatialRotationOrbit: setRotationOrbit, setSpatialOrbitAxis: setOrbitAxis, setSpatialImageLayer: setRasterLayers, setSpatialSegmentationLayer: setCellsLayer, setSpatialPointLayer: setMoleculesLayer, setSpatialNeighborhoodLayer: setNeighborhoodsLayer, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setMoleculeHighlight, setSpatialAxisFixed, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setTooltipsVisible, setFeatureAggregationStrategy, setAnnotationStory }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL], coordinationScopes);
|
|
248308
249765
|
const { spatialZoom: initialZoom, spatialTargetX: initialTargetX, spatialTargetY: initialTargetY, spatialTargetZ: initialTargetZ } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL], coordinationScopes);
|
|
248309
249766
|
const observationsLabel = observationsLabelOverride || obsType;
|
|
248310
249767
|
const [{ imageLayerCallbacks, segmentationLayerCallbacks }] = useAuxiliaryCoordination(COMPONENT_COORDINATION_TYPES.layerController, coordinationScopes);
|
|
@@ -248341,6 +249798,7 @@ function SpatialSubscriber$1(props) {
|
|
|
248341
249798
|
const [neighborhoods, neighborhoodsStatus, neighborhoodsUrls, neighborhoodsError] = useNeighborhoodsData(loaders, dataset, false, { setSpatialNeighborhoodLayer: setNeighborhoodsLayer }, { spatialNeighborhoodLayer: neighborhoodsLayer });
|
|
248342
249799
|
const [{ featureLabelsMap: featureLabelsMapOrig }, featureLabelsStatus, featureLabelsUrls, featureLabelsError] = useFeatureLabelsData(loaders, dataset, false, {}, {}, { featureType });
|
|
248343
249800
|
const [featureLabelsMap, expandedFeatureLabelsStatus] = useExpandedFeatureLabelsMap(featureType, featureLabelsMapOrig, { stripCuriePrefixes: true });
|
|
249801
|
+
const [, annotationStoryStatus, annotationStoryUrls, annotationStoryError] = useAnnotationStoryData(loaders, dataset, false, { setAnnotationStory }, { annotationStory }, {});
|
|
248344
249802
|
const errors = [
|
|
248345
249803
|
...obsLabelsErrorsMulti,
|
|
248346
249804
|
obsLocationsError,
|
|
@@ -248352,7 +249810,8 @@ function SpatialSubscriber$1(props) {
|
|
|
248352
249810
|
matrixIndicesError,
|
|
248353
249811
|
imageError,
|
|
248354
249812
|
neighborhoodsError,
|
|
248355
|
-
featureLabelsError
|
|
249813
|
+
featureLabelsError,
|
|
249814
|
+
annotationStoryError
|
|
248356
249815
|
];
|
|
248357
249816
|
const photometricInterpretation = photometricInterpretationFromCoordination ?? instance2?.getPhotometricInterpretation();
|
|
248358
249817
|
const isReady = useReady([
|
|
@@ -248366,7 +249825,8 @@ function SpatialSubscriber$1(props) {
|
|
|
248366
249825
|
imageStatus,
|
|
248367
249826
|
neighborhoodsStatus,
|
|
248368
249827
|
featureLabelsStatus,
|
|
248369
|
-
expandedFeatureLabelsStatus
|
|
249828
|
+
expandedFeatureLabelsStatus,
|
|
249829
|
+
annotationStoryStatus
|
|
248370
249830
|
]);
|
|
248371
249831
|
const urls2 = useUrls([
|
|
248372
249832
|
obsLocationsUrls,
|
|
@@ -248377,7 +249837,8 @@ function SpatialSubscriber$1(props) {
|
|
|
248377
249837
|
matrixIndicesUrls,
|
|
248378
249838
|
imageUrls,
|
|
248379
249839
|
neighborhoodsUrls,
|
|
248380
|
-
featureLabelsUrls
|
|
249840
|
+
featureLabelsUrls,
|
|
249841
|
+
annotationStoryUrls
|
|
248381
249842
|
]);
|
|
248382
249843
|
const obsLocationsFeatureIndex = useMemo$1(() => {
|
|
248383
249844
|
if (obsLocationsLabels) {
|
|
@@ -248616,7 +250077,7 @@ function SpatialSubscriber$1(props) {
|
|
|
248616
250077
|
orbitAxis
|
|
248617
250078
|
}, setViewState, originalViewState, imageLayerDefs: imageLayers, obsSegmentationsLayerDefs: cellsLayer, obsLocationsLayerDefs: moleculesLayer, neighborhoodLayerDefs: neighborhoodsLayer, obsLocationsIndex, obsSegmentationsIndex, obsLocations, obsLocationsLabels, obsLocationsFeatureIndex, hasSegmentations: hasSegmentationsData, obsSegmentations, obsSegmentationsType, obsCentroids, obsCentroidsIndex, cellFilter, cellSelection, cellHighlight, cellColors, neighborhoods, imageLayerLoaders: resolutionFilteredImageLayerLoaders, setCellFilter, setCellSelection: setCellSelectionProp, setCellHighlight, setHoverInfo, setMoleculeHighlight, setComponentHover: () => {
|
|
248618
250079
|
setComponentHover(uuid2);
|
|
248619
|
-
}, updateViewInfo: setComponentViewInfo, imageLayerCallbacks, segmentationLayerCallbacks, spatialAxisFixed, geneExpressionColormap, geneExpressionColormapRange, expressionData: shiftedExpressionDataForBitmask, cellColorEncoding, getExpressionValue, theme, useFullResolutionImage, photometricInterpretation }), tooltipsVisible && jsx$1(SpatialTooltipSubscriber$1, { parentUuid: uuid2, obsHighlight: cellHighlight || moleculeHighlight, width: width2, height: height2, getObsInfo: getTooltipObsInfo, useHoverInfoForTooltip, hoverData, hoverCoord, hoverMode, getObsIdFromHoverData, featureType, featureLabelsMap }), jsx$1(Legend, {
|
|
250080
|
+
}, updateViewInfo: setComponentViewInfo, imageLayerCallbacks, segmentationLayerCallbacks, spatialAxisFixed, geneExpressionColormap, geneExpressionColormapRange, expressionData: shiftedExpressionDataForBitmask, cellColorEncoding, getExpressionValue, theme, useFullResolutionImage, photometricInterpretation, annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection }), tooltipsVisible && jsx$1(SpatialTooltipSubscriber$1, { parentUuid: uuid2, obsHighlight: cellHighlight || moleculeHighlight, width: width2, height: height2, getObsInfo: getTooltipObsInfo, useHoverInfoForTooltip, hoverData, hoverCoord, hoverMode, getObsIdFromHoverData, featureType, featureLabelsMap }), jsx$1(Legend, {
|
|
248620
250081
|
visible: true,
|
|
248621
250082
|
// Fix to dark theme due to black background of spatial plot.
|
|
248622
250083
|
theme: "dark",
|
|
@@ -248864,6 +250325,7 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
248864
250325
|
this.obsSegmentationsLayers = [];
|
|
248865
250326
|
this.obsSpotsLayers = [];
|
|
248866
250327
|
this.obsPointsLayers = [];
|
|
250328
|
+
this.annotationLayer = null;
|
|
248867
250329
|
this.obsPointsLabelsData = {};
|
|
248868
250330
|
this.spotToMatrixIndexMap = {};
|
|
248869
250331
|
this.spotColors = {};
|
|
@@ -248905,6 +250367,7 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
248905
250367
|
this.onUpdateAllSpotsExpressionData();
|
|
248906
250368
|
this.onUpdateSpotsLayer();
|
|
248907
250369
|
this.onUpdateImages();
|
|
250370
|
+
this.onUpdateAnnotationLayer();
|
|
248908
250371
|
}
|
|
248909
250372
|
createPolygonSegmentationLayer(layerScope, layerCoordination, channelScopes, channelCoordinations, layerObsSegmentations, layerFeatureValues) {
|
|
248910
250373
|
const { theme, delegateHover } = this.props;
|
|
@@ -249643,7 +251106,8 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
249643
251106
|
imageLayers,
|
|
249644
251107
|
obsSpotsLayers,
|
|
249645
251108
|
obsPointsLayers,
|
|
249646
|
-
obsSegmentationsLayers
|
|
251109
|
+
obsSegmentationsLayers,
|
|
251110
|
+
annotationLayer
|
|
249647
251111
|
// neighborhoodsLayer,
|
|
249648
251112
|
// obsLocationsLayer,
|
|
249649
251113
|
} = this;
|
|
@@ -249655,7 +251119,8 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
249655
251119
|
// neighborhoodsLayer,
|
|
249656
251120
|
// obsLocationsLayer,
|
|
249657
251121
|
this.createScaleBarLayer(),
|
|
249658
|
-
this.createSelectionLayer()
|
|
251122
|
+
this.createSelectionLayer(),
|
|
251123
|
+
annotationLayer
|
|
249659
251124
|
];
|
|
249660
251125
|
}
|
|
249661
251126
|
// onUpdate functions:
|
|
@@ -250011,6 +251476,25 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
250011
251476
|
onUpdateImages() {
|
|
250012
251477
|
this.imageLayers = this.createImageLayers();
|
|
250013
251478
|
}
|
|
251479
|
+
createAnnotationLayer() {
|
|
251480
|
+
const { annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection } = this.props;
|
|
251481
|
+
return new AnnotationLayer({
|
|
251482
|
+
id: "annotation-layer",
|
|
251483
|
+
data: annotationShapes,
|
|
251484
|
+
visible: annotationOverlayVisible,
|
|
251485
|
+
semanticZoom: annotationSemanticZoom,
|
|
251486
|
+
selectedShapeUid: annotationShapeSelection,
|
|
251487
|
+
viewType: ViewType$1.SPATIAL_BETA
|
|
251488
|
+
});
|
|
251489
|
+
}
|
|
251490
|
+
onUpdateAnnotationLayer() {
|
|
251491
|
+
const { annotationShapes } = this.props;
|
|
251492
|
+
if (annotationShapes) {
|
|
251493
|
+
this.annotationLayer = this.createAnnotationLayer();
|
|
251494
|
+
} else {
|
|
251495
|
+
this.annotationLayer = null;
|
|
251496
|
+
}
|
|
251497
|
+
}
|
|
250014
251498
|
viewInfoDidUpdate() {
|
|
250015
251499
|
super.viewInfoDidUpdate(null, null, makeDefaultGetObsCoords);
|
|
250016
251500
|
}
|
|
@@ -250208,6 +251692,15 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
250208
251692
|
this.onUpdateImages();
|
|
250209
251693
|
forceUpdate = true;
|
|
250210
251694
|
}
|
|
251695
|
+
if ([
|
|
251696
|
+
"annotationShapes",
|
|
251697
|
+
"annotationOverlayVisible",
|
|
251698
|
+
"annotationSemanticZoom",
|
|
251699
|
+
"annotationShapeSelection"
|
|
251700
|
+
].some(shallowDiff2)) {
|
|
251701
|
+
this.onUpdateAnnotationLayer();
|
|
251702
|
+
forceUpdate = true;
|
|
251703
|
+
}
|
|
250211
251704
|
if (forceUpdate) {
|
|
250212
251705
|
this.forceUpdate();
|
|
250213
251706
|
}
|
|
@@ -250347,16 +251840,16 @@ class ErrorBoundary extends React__default.Component {
|
|
|
250347
251840
|
}
|
|
250348
251841
|
}
|
|
250349
251842
|
const LazySpatialThree = React__default.lazy(async () => {
|
|
250350
|
-
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-
|
|
251843
|
+
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-CfweEgJW.js").then((n3) => n3.a);
|
|
250351
251844
|
return { default: SpatialWrapper2 };
|
|
250352
251845
|
});
|
|
250353
251846
|
const SpatialThreeAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialThree, { ...props }) }) }) }));
|
|
250354
251847
|
const LazySpatialAccelerated = React__default.lazy(async () => {
|
|
250355
|
-
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-
|
|
251848
|
+
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-CNXTPnLt.js");
|
|
250356
251849
|
return { default: SpatialWrapper2 };
|
|
250357
251850
|
});
|
|
250358
251851
|
const SpatialAcceleratedAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialAccelerated, { ...props }) }) }) }));
|
|
250359
|
-
const useStyles$
|
|
251852
|
+
const useStyles$q = makeStyles()(() => ({
|
|
250360
251853
|
spatialBetaCameraLabel: {
|
|
250361
251854
|
padding: "0px 0px 0px 16px"
|
|
250362
251855
|
},
|
|
@@ -250367,7 +251860,7 @@ const useStyles$p = makeStyles()(() => ({
|
|
|
250367
251860
|
function SpatialOptions(props) {
|
|
250368
251861
|
const { spatialAxisFixed, setSpatialAxisFixed, use3d } = props;
|
|
250369
251862
|
const toggleAxisId = $bdb11010cef70236$export$f680877a34711e37();
|
|
250370
|
-
const { classes: classes2 } = useStyles$
|
|
251863
|
+
const { classes: classes2 } = useStyles$q();
|
|
250371
251864
|
return jsx$1(OptionsContainer, { children: jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.spatialBetaCameraLabel, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `spatial-camera-axis-${toggleAxisId}`, children: "Fix Camera Axis" }) }), jsx$1(TableCell, { className: classes2.spatialBetaToggleBox, variant: "body", children: jsx$1(Checkbox$1, { onClick: () => setSpatialAxisFixed(!spatialAxisFixed), disabled: !use3d, checked: Boolean(spatialAxisFixed), slotProps: { input: {
|
|
250372
251865
|
"aria-label": "Fix or not fix spatial camera axis",
|
|
250373
251866
|
id: `spatial-camera-axis-${toggleAxisId}`
|
|
@@ -250555,6 +252048,7 @@ function SpatialSubscriber(props) {
|
|
|
250555
252048
|
const mergeCoordination = useMergeCoordination();
|
|
250556
252049
|
const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
|
|
250557
252050
|
const coordinationScopesBy = useCoordinationScopesBy(coordinationScopes, coordinationScopesByRaw);
|
|
252051
|
+
useAnnotationFrameCoordination(uuid2, coordinationScopes);
|
|
250558
252052
|
const [{
|
|
250559
252053
|
dataset,
|
|
250560
252054
|
obsType,
|
|
@@ -250576,7 +252070,12 @@ function SpatialSubscriber(props) {
|
|
|
250576
252070
|
additionalObsSets,
|
|
250577
252071
|
obsSetColor,
|
|
250578
252072
|
obsColorEncoding,
|
|
250579
|
-
obsSetSelection
|
|
252073
|
+
obsSetSelection,
|
|
252074
|
+
annotationStory,
|
|
252075
|
+
annotationShapes,
|
|
252076
|
+
annotationOverlayVisible,
|
|
252077
|
+
annotationSemanticZoom,
|
|
252078
|
+
annotationShapeSelection
|
|
250580
252079
|
}, {
|
|
250581
252080
|
setSpatialZoom: setZoom,
|
|
250582
252081
|
setSpatialTargetX: setTargetX,
|
|
@@ -250592,7 +252091,8 @@ function SpatialSubscriber(props) {
|
|
|
250592
252091
|
setAdditionalObsSets,
|
|
250593
252092
|
setObsSetColor,
|
|
250594
252093
|
setObsColorEncoding,
|
|
250595
|
-
setObsSetSelection
|
|
252094
|
+
setObsSetSelection,
|
|
252095
|
+
setAnnotationStory
|
|
250596
252096
|
}] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL_BETA], coordinationScopes);
|
|
250597
252097
|
const { spatialZoom: initialZoom, spatialTargetX: initialTargetX, spatialTargetY: initialTargetY, spatialTargetZ: initialTargetZ } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL_BETA], coordinationScopes);
|
|
250598
252098
|
const [segmentationLayerScopes, segmentationChannelScopesByLayer] = useMultiCoordinationScopesSecondaryNonNull(CoordinationType$1.SEGMENTATION_CHANNEL, CoordinationType$1.SEGMENTATION_LAYER, coordinationScopes, coordinationScopesBy);
|
|
@@ -250735,6 +252235,7 @@ function SpatialSubscriber(props) {
|
|
|
250735
252235
|
channelCoordination: segmentationChannelCoordination
|
|
250736
252236
|
});
|
|
250737
252237
|
const [imageData, imageDataStatus, imageUrls, imageDataErrors] = useMultiImages(coordinationScopes, coordinationScopesBy, loaders, dataset, mergeCoordination, uuid2);
|
|
252238
|
+
const [, annotationStoryStatus, annotationStoryUrls, annotationStoryError] = useAnnotationStoryData(loaders, dataset, false, { setAnnotationStory }, { annotationStory }, {});
|
|
250738
252239
|
const errors = [
|
|
250739
252240
|
...obsPointsErrors,
|
|
250740
252241
|
...obsSpotsErrors,
|
|
@@ -250749,7 +252250,8 @@ function SpatialSubscriber(props) {
|
|
|
250749
252250
|
...pointMultiIndicesDataErrors,
|
|
250750
252251
|
...segmentationMultiFeatureSelectionErrors,
|
|
250751
252252
|
...segmentationMultiIndicesDataErrors,
|
|
250752
|
-
...obsSegmentationsLocationsDataErrors
|
|
252253
|
+
...obsSegmentationsLocationsDataErrors,
|
|
252254
|
+
annotationStoryError
|
|
250753
252255
|
];
|
|
250754
252256
|
const isReadyToComputeInitialViewState = useReady([
|
|
250755
252257
|
obsPointsDataStatus,
|
|
@@ -250774,13 +252276,16 @@ function SpatialSubscriber(props) {
|
|
|
250774
252276
|
segmentationMultiIndicesDataStatus,
|
|
250775
252277
|
obsSegmentationsLocationsDataStatus,
|
|
250776
252278
|
// Images
|
|
250777
|
-
imageDataStatus
|
|
252279
|
+
imageDataStatus,
|
|
252280
|
+
// Annotations
|
|
252281
|
+
annotationStoryStatus
|
|
250778
252282
|
]);
|
|
250779
252283
|
const urls2 = useUrls([
|
|
250780
252284
|
Object.values(obsSpotsUrls || {}).flat(),
|
|
250781
252285
|
Object.values(obsPointsUrls || {}).flat(),
|
|
250782
252286
|
Object.values(obsSegmentationsUrls || {}).flat(),
|
|
250783
|
-
Object.values(imageUrls || {}).flat()
|
|
252287
|
+
Object.values(imageUrls || {}).flat(),
|
|
252288
|
+
annotationStoryUrls
|
|
250784
252289
|
// TODO: more urls
|
|
250785
252290
|
// TODO: a bit of memoization
|
|
250786
252291
|
]);
|
|
@@ -251028,7 +252533,7 @@ function SpatialSubscriber(props) {
|
|
|
251028
252533
|
target: [targetX2, targetY2, targetZ],
|
|
251029
252534
|
rotationX,
|
|
251030
252535
|
rotationOrbit
|
|
251031
|
-
} : DEFAULT_VIEW_STATE, orbitAxis, spatialAxisFixed, setViewState: isValidViewState ? setViewState : SET_VIEW_STATE_NOOP, originalViewState, spatialRenderingMode, updateViewInfo: setComponentViewInfo, delegateHover, obsPoints: obsPointsData, pointLayerScopes, pointLayerCoordination, pointMultiObsLabels: pointMultiObsLabelsData, pointMatrixIndices: pointMultiIndicesData, obsSpots: obsSpotsData, spotLayerScopes, spotLayerCoordination, obsSpotsSets: obsSpotsSetsData, spotMatrixIndices: spotMultiIndicesData, spotMultiExpressionData: spotMultiExpressionNormDataAggregated || spotMultiExpressionNormData, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, obsSegmentations: obsSegmentationsData, obsSegmentationsLocations: obsSegmentationsLocationsData, obsSegmentationsSets: obsSegmentationsSetsData, segmentationMatrixIndices: segmentationMultiIndicesData, segmentationMultiExpressionData: segmentationMultiExpressionNormDataAggregated || segmentationMultiExpressionNormData, bitmaskValueIsIndex, images: imageData, imageLayerScopes, imageLayerCoordination, imageChannelScopesByLayer, imageChannelCoordination, setTiledPointsLoadingProgress }), !disableTooltip && jsx$1(SpatialTooltipSubscriber, {
|
|
252536
|
+
} : DEFAULT_VIEW_STATE, orbitAxis, spatialAxisFixed, setViewState: isValidViewState ? setViewState : SET_VIEW_STATE_NOOP, originalViewState, spatialRenderingMode, updateViewInfo: setComponentViewInfo, delegateHover, obsPoints: obsPointsData, pointLayerScopes, pointLayerCoordination, pointMultiObsLabels: pointMultiObsLabelsData, pointMatrixIndices: pointMultiIndicesData, obsSpots: obsSpotsData, spotLayerScopes, spotLayerCoordination, obsSpotsSets: obsSpotsSetsData, spotMatrixIndices: spotMultiIndicesData, spotMultiExpressionData: spotMultiExpressionNormDataAggregated || spotMultiExpressionNormData, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, obsSegmentations: obsSegmentationsData, obsSegmentationsLocations: obsSegmentationsLocationsData, obsSegmentationsSets: obsSegmentationsSetsData, segmentationMatrixIndices: segmentationMultiIndicesData, segmentationMultiExpressionData: segmentationMultiExpressionNormDataAggregated || segmentationMultiExpressionNormData, bitmaskValueIsIndex, images: imageData, imageLayerScopes, imageLayerCoordination, imageChannelScopesByLayer, imageChannelCoordination, setTiledPointsLoadingProgress, annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection }), !disableTooltip && jsx$1(SpatialTooltipSubscriber, {
|
|
251032
252537
|
parentUuid: uuid2,
|
|
251033
252538
|
width: width2,
|
|
251034
252539
|
height: height2,
|
|
@@ -258445,7 +259950,7 @@ _defineProperty$3(WindowScroller, "defaultProps", {
|
|
|
258445
259950
|
serverHeight: 0,
|
|
258446
259951
|
serverWidth: 0
|
|
258447
259952
|
});
|
|
258448
|
-
const useStyles$
|
|
259953
|
+
const useStyles$p = makeStyles()((theme) => ({
|
|
258449
259954
|
selectableTable: {
|
|
258450
259955
|
flex: "1 1 auto",
|
|
258451
259956
|
outline: "none"
|
|
@@ -258594,7 +260099,7 @@ function SelectableTable(props) {
|
|
|
258594
260099
|
onChange(null);
|
|
258595
260100
|
}
|
|
258596
260101
|
}, [selectedRows, allowMultiple]);
|
|
258597
|
-
const { classes: classes2 } = useStyles$
|
|
260102
|
+
const { classes: classes2 } = useStyles$p();
|
|
258598
260103
|
const inputUuid = v4$1();
|
|
258599
260104
|
const rowRenderer = ({ index: index2, style: style2 }) => (
|
|
258600
260105
|
// eslint-disable-next-line jsx-a11y/interactive-supports-focus
|
|
@@ -258619,7 +260124,7 @@ const FEATURELIST_SORT_OPTIONS = [
|
|
|
258619
260124
|
"original"
|
|
258620
260125
|
];
|
|
258621
260126
|
const ALT_COLNAME = "Alternate ID";
|
|
258622
|
-
const useStyles$
|
|
260127
|
+
const useStyles$o = makeStyles()(() => ({
|
|
258623
260128
|
searchBar: {
|
|
258624
260129
|
marginTop: "10px",
|
|
258625
260130
|
marginLeft: "10px",
|
|
@@ -258632,7 +260137,7 @@ const useStyles$n = makeStyles()(() => ({
|
|
|
258632
260137
|
}));
|
|
258633
260138
|
function FeatureList(props) {
|
|
258634
260139
|
const { width: width2, height: height2, hasColorEncoding, geneList = [], featureLabelsMap, geneSelection = [], geneFilter = null, setGeneSelection, enableMultiSelect, showFeatureTable, featureListSort, featureListSortKey, hasFeatureLabels, primaryColumnName } = props;
|
|
258635
|
-
const { classes: classes2 } = useStyles$
|
|
260140
|
+
const { classes: classes2 } = useStyles$o();
|
|
258636
260141
|
const [searchTerm, setSearchTerm] = useState("");
|
|
258637
260142
|
const selectableTableSortKey = featureListSortKey === "featureIndex" ? "key" : "name";
|
|
258638
260143
|
const searchResults = useMemo$1(() => geneList.filter((gene) => gene.toLowerCase().includes(searchTerm.toLowerCase()) || featureLabelsMap?.get(gene)?.toLowerCase().includes(searchTerm.toLowerCase()) || featureLabelsMap?.get(cleanFeatureId(gene))?.toLowerCase().includes(searchTerm.toLowerCase())), [geneList, searchTerm, featureLabelsMap]);
|
|
@@ -258705,7 +260210,7 @@ function FeatureListOptions(props) {
|
|
|
258705
260210
|
id: `feature-list-show-alternative-ids-${featureListId}`
|
|
258706
260211
|
} } }) })] })] }) : null] });
|
|
258707
260212
|
}
|
|
258708
|
-
const useStyles$
|
|
260213
|
+
const useStyles$n = makeStyles()((theme) => ({
|
|
258709
260214
|
featureListContainer: {
|
|
258710
260215
|
width: "100%",
|
|
258711
260216
|
height: "100%",
|
|
@@ -258720,7 +260225,7 @@ function FeatureListSubscriber(props) {
|
|
|
258720
260225
|
const loaders = useLoaders();
|
|
258721
260226
|
const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
|
|
258722
260227
|
const [width2, height2, containerRef] = useGridItemSize();
|
|
258723
|
-
const { classes: classes2 } = useStyles$
|
|
260228
|
+
const { classes: classes2 } = useStyles$n();
|
|
258724
260229
|
const [{ dataset, obsType, featureType, featureSelection: geneSelection, featureFilter: geneFilter, obsColorEncoding: cellColorEncoding }, { setFeatureSelection: setGeneSelection, setFeatureFilter: setGeneFilter, setFeatureHighlight: setGeneHighlight, setObsColorEncoding: setCellColorEncoding }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.FEATURE_LIST], coordinationScopes);
|
|
258725
260230
|
const variablesLabel = variablesLabelOverride || featureType;
|
|
258726
260231
|
const title2 = titleOverride || `${capitalize$3(variablesLabel)} List`;
|
|
@@ -258855,7 +260360,7 @@ const useSelectionSliderStyles = makeStyles()(() => ({
|
|
|
258855
260360
|
backgroundColor: "rgba(128, 128, 128, 0.7)"
|
|
258856
260361
|
}
|
|
258857
260362
|
}));
|
|
258858
|
-
const useStyles$
|
|
260363
|
+
const useStyles$m = makeStyles()((theme) => ({
|
|
258859
260364
|
paletteContainer: {
|
|
258860
260365
|
width: "70px",
|
|
258861
260366
|
height: "40px",
|
|
@@ -258876,10 +260381,10 @@ const useStyles$l = makeStyles()((theme) => ({
|
|
|
258876
260381
|
}
|
|
258877
260382
|
}));
|
|
258878
260383
|
const ColorPalette = ({ handleChange }) => {
|
|
258879
|
-
const { classes: classes2 } = useStyles$
|
|
260384
|
+
const { classes: classes2 } = useStyles$m();
|
|
258880
260385
|
return jsx$1("div", { className: classes2.paletteContainer, "aria-label": "Color swatch", children: VIEWER_PALETTE.map((color2) => jsx$1(IconButton$1, { className: classes2.button, onClick: () => handleChange(color2), "aria-label": `Change color to ${color2}`, children: jsx$1(LensIcon, { fontSize: "small", style: { color: `rgb(${color2})` }, className: classes2.icon }) }, color2)) });
|
|
258881
260386
|
};
|
|
258882
|
-
const useStyles$
|
|
260387
|
+
const useStyles$l = makeStyles()(() => ({
|
|
258883
260388
|
menuButton: {
|
|
258884
260389
|
backgroundColor: "transparent"
|
|
258885
260390
|
},
|
|
@@ -258898,7 +260403,7 @@ function MuiSpan(props) {
|
|
|
258898
260403
|
}
|
|
258899
260404
|
function ChannelOptions$1({ handlePropertyChange, handleChannelRemove, handleIQRUpdate }) {
|
|
258900
260405
|
const [open2, setOpen] = useState(false);
|
|
258901
|
-
const { classes: classes2 } = useStyles$
|
|
260406
|
+
const { classes: classes2 } = useStyles$l();
|
|
258902
260407
|
const handleColorSelect = (color2) => {
|
|
258903
260408
|
handlePropertyChange("color", color2);
|
|
258904
260409
|
};
|
|
@@ -259515,7 +261020,7 @@ function LayerController$1(props) {
|
|
|
259515
261020
|
minWidth: "50%"
|
|
259516
261021
|
} })] }), jsx$1(TabPanel, { value: tab2, index: 0, children: FullController }), jsx$1(TabPanel, { value: tab2, index: 1, style: { marginTop: 4 }, children: jsx$1(VolumeOptions, { loader: loader2, handleSlicerSetting, handleRenderingModeChange: setRenderingMode, renderingMode, xSlice, ySlice, zSlice, use3d, setViewState, spatialHeight, spatialWidth, modelMatrix: modelMatrix2 }) })] }) : FullController, shouldShowRemoveLayerButton ? jsx$1(Button, { onClick: handleLayerRemove, fullWidth: true, variant: "outlined", style: buttonStyles, size: "small", children: "Remove Image Layer" }) : null] })] });
|
|
259517
261022
|
}
|
|
259518
|
-
const useStyles$
|
|
261023
|
+
const useStyles$k = makeStyles()(() => ({
|
|
259519
261024
|
addButton: {
|
|
259520
261025
|
marginTop: "10px",
|
|
259521
261026
|
marginBottom: "10px",
|
|
@@ -259527,7 +261032,7 @@ function ImageAddIcon() {
|
|
|
259527
261032
|
}
|
|
259528
261033
|
function ImageAddButton({ imageOptions, handleImageAdd }) {
|
|
259529
261034
|
const [open2, setOpen] = useState(false);
|
|
259530
|
-
const { classes: classes2 } = useStyles$
|
|
261035
|
+
const { classes: classes2 } = useStyles$k();
|
|
259531
261036
|
const handleAdd = (imgData) => {
|
|
259532
261037
|
setOpen((prev2) => !prev2);
|
|
259533
261038
|
handleImageAdd(imgData);
|
|
@@ -259889,7 +261394,7 @@ const channelControlCellSx = {
|
|
|
259889
261394
|
}
|
|
259890
261395
|
};
|
|
259891
261396
|
const channelSpacerCellSx = { flexShrink: 0, minWidth: "44px" };
|
|
259892
|
-
const useStyles$
|
|
261397
|
+
const useStyles$j = makeStyles()(() => ({
|
|
259893
261398
|
colorPickerPaper: {
|
|
259894
261399
|
overflow: "hidden",
|
|
259895
261400
|
"& > ul": {
|
|
@@ -259947,7 +261452,7 @@ function ChannelColorPickerMenu(props) {
|
|
|
259947
261452
|
setColor2([rgb2.r, rgb2.g, rgb2.b]);
|
|
259948
261453
|
}
|
|
259949
261454
|
}
|
|
259950
|
-
const { classes: classes2 } = useStyles$
|
|
261455
|
+
const { classes: classes2 } = useStyles$j();
|
|
259951
261456
|
const currentColor = color2 ? colorArrayToString(color2) : colorArrayToString(getDefaultColor(theme));
|
|
259952
261457
|
const isWritable = typeof setColor2 === "function";
|
|
259953
261458
|
const derivedOpen = isWritable ? isStaticColor && visible ? open2 : false : false;
|
|
@@ -259955,7 +261460,7 @@ function ChannelColorPickerMenu(props) {
|
|
|
259955
261460
|
[classes2.colorIconOutline]: theme !== "dark" && isEqual$3(color2, [255, 255, 255])
|
|
259956
261461
|
}), style: { backgroundColor: currentColor } }) : isColormap && visible && featureValueColormap ? jsx$1("div", { className: classes2.colorIcon, children: jsx$1("svg", { width: "18", height: "18", children: jsx$1("image", { x: 0, y: 0, width: 18, height: 18, preserveAspectRatio: "none", href: getXlinkHref(featureValueColormap), clipPath: "inset(0% round 4px)" }) }) }) : jsx$1("div", { className: classes2.colorIcon }), buttonClassName: classes2.colorIconButton, withPaper: true, paperClassName: classes2.colorPickerPaper, "aria-label": "Open color picker menu", children: jsx$1(Twitter$1, { className: classes2.colorPicker, disableAlpha: true, width: 108, triangle: "hide", colors: defaultPalette, color: currentColor, onChangeComplete: handleColorChange }) });
|
|
259957
261462
|
}
|
|
259958
|
-
const useStyles$
|
|
261463
|
+
const useStyles$i = makeStyles()(() => ({
|
|
259959
261464
|
layerTypeSpotIcon: {
|
|
259960
261465
|
height: "100%",
|
|
259961
261466
|
marginLeft: "1px",
|
|
@@ -259968,7 +261473,7 @@ const useStyles$h = makeStyles()(() => ({
|
|
|
259968
261473
|
function SpotLayerEllipsisMenu(props) {
|
|
259969
261474
|
const { strokeWidth, setStrokeWidth, filled, setFilled, featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible } = props;
|
|
259970
261475
|
const [open2, setOpen] = useState(false);
|
|
259971
|
-
const { classes: classes2 } = useStyles$
|
|
261476
|
+
const { classes: classes2 } = useStyles$i();
|
|
259972
261477
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
259973
261478
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
259974
261479
|
const filledId = $bdb11010cef70236$export$f680877a34711e37();
|
|
@@ -259990,7 +261495,7 @@ function SpotLayerController(props) {
|
|
|
259990
261495
|
const Visibility = useMemo$1(() => visibleSetting ? VisibilityIcon : VisibilityOffIcon, [visibleSetting]);
|
|
259991
261496
|
const isStaticColor = obsColorEncoding === "spatialLayerColor";
|
|
259992
261497
|
const isColormap = obsColorEncoding === "geneSelection";
|
|
259993
|
-
const { classes: classes2 } = useStyles$
|
|
261498
|
+
const { classes: classes2 } = useStyles$i();
|
|
259994
261499
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
259995
261500
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
259996
261501
|
const handleVisibleChange = useCallback(() => {
|
|
@@ -260000,7 +261505,7 @@ function SpotLayerController(props) {
|
|
|
260000
261505
|
const handleOpacityChange = useCallback((e3, v) => setOpacity2(v), [setOpacity2]);
|
|
260001
261506
|
return jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: handleVisibleChange, className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle spot layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: color2, setColor: setColor2, palette, isStaticColor, isColormap, featureValueColormap, visible }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SpotLayerEllipsisMenu, { filled, setFilled, strokeWidth, setStrokeWidth, featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SvgSpots, { className: classes2.layerTypeSpotIcon }) })] }) }) });
|
|
260002
261507
|
}
|
|
260003
|
-
const useStyles$
|
|
261508
|
+
const useStyles$h = makeStyles()(() => ({
|
|
260004
261509
|
layerFeatureControllerGrid: {
|
|
260005
261510
|
padding: "0",
|
|
260006
261511
|
flexWrap: "nowrap"
|
|
@@ -260045,7 +261550,7 @@ function LayerPerFeatureController(props) {
|
|
|
260045
261550
|
]);
|
|
260046
261551
|
}
|
|
260047
261552
|
}, [featureName, featureColor, setFeatureColor, featureColorIndex]);
|
|
260048
|
-
const { classes: classes2 } = useStyles$
|
|
261553
|
+
const { classes: classes2 } = useStyles$h();
|
|
260049
261554
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
260050
261555
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
260051
261556
|
const [open2, setOpen] = useState(false);
|
|
@@ -260099,7 +261604,7 @@ function LayerPerFeatureController(props) {
|
|
|
260099
261604
|
]);
|
|
260100
261605
|
return jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsxs(Paper, { elevation: 2, className: lcClasses.layerControllerSubRow, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: handleRemoveFeature, className: menuClasses.imageLayerVisibleButton, "aria-label": "Remove feature", children: jsx$1(ClearIcon, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(Tooltip$3, { title: colorPickerTooltip ?? "", disableHoverListener: !colorPickerTooltip, placement: "top", children: jsx$1("span", { children: jsx$1(ChannelColorPickerMenu, { theme, color: colorPickerColor, setColor: colorPickerWritable ? handleColorChange : null, palette, isStaticColor: colorPickerReadable, isColormap: false, featureValueColormap, visible: true }) }) }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: featureName }) }), jsx$1(Grid$1, { size: 2, sx: { paddingRight: "12px", overflow: "visible" }, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${featureName}` }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(SvgPoints, { className: classes2.layerTypeFeatureIcon }), null] })] }), loadingDoneFraction < 1 ? jsx$1(Grid$1, { size: 12, container: true, direction: "column", justifyContent: "space-between", className: classes2.layerFeatureControllerGrid, children: jsx$1(LinearProgress, { variant: loadingDoneFraction === 0 ? "indeterminate" : "determinate", value: loadingDoneFraction * 100 }) }) : null] }) }, featureName);
|
|
260101
261606
|
}
|
|
260102
|
-
const useStyles$
|
|
261607
|
+
const useStyles$g = makeStyles()(() => ({
|
|
260103
261608
|
pointLayerButton: {
|
|
260104
261609
|
borderStyle: "dashed",
|
|
260105
261610
|
marginTop: "10px",
|
|
@@ -260216,7 +261721,7 @@ function PointLayerController(props) {
|
|
|
260216
261721
|
featureSelection,
|
|
260217
261722
|
showStaticColor
|
|
260218
261723
|
]);
|
|
260219
|
-
const { classes: classes2 } = useStyles$
|
|
261724
|
+
const { classes: classes2 } = useStyles$g();
|
|
260220
261725
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
260221
261726
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
260222
261727
|
const handleVisibleChange = useCallback(() => {
|
|
@@ -260245,7 +261750,7 @@ function PointLayerController(props) {
|
|
|
260245
261750
|
}, [featureSelection, obsColorEncoding, featureIndex, featureColor]);
|
|
260246
261751
|
return jsxs(Grid$1, { className: lcClasses.layerControllerGrid, children: [jsxs(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", sx: channelRowContainerSx, children: [jsx$1(Grid$1, { size: 1, sx: channelControlCellSx, children: jsx$1(Button, { onClick: handleVisibleChange, className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1, sx: channelControlCellSx, children: jsx$1(ChannelColorPickerMenu, { theme, color: color2, setColor: setColor2, palette, isStaticColor, isColormap, featureValueColormap, visible }) }), jsx$1(Grid$1, { size: 6, sx: channelSelectorCellSx, children: jsx$1(Typography, { className: menuClasses.imageLayerName, title: label2, children: label2 }) }), jsx$1(Grid$1, { size: 2, sx: channelSliderCellSx, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, sx: channelControlCellSx, children: jsx$1(PointLayerEllipsisMenu, { featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible, featureFilterMode, setFeatureFilterMode, featureValueColormap, setFeatureValueColormap }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", sx: channelControlCellSx, children: [jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }), null] })] }), loadingDoneFraction < 1 ? jsx$1(Grid$1, { size: 12, container: true, direction: "column", justifyContent: "space-between", className: classes2.pointFeatureControllerGrid, children: jsx$1(LinearProgress, { variant: loadingDoneFraction === 0 ? "indeterminate" : "determinate", value: loadingDoneFraction * 100 }) }) : null, null] }), layerPerFeatureForPoints && hasSelectedFeatures ? jsxs(Fragment, { children: [featureSelection.map((featureName) => jsx$1(LayerPerFeatureController, { theme, featureName, featureColor, setFeatureColor, spatialLayerColor, featureIndex, featureValueColormap, featureSelection, setFeatureSelection, obsColorEncoding, loadingDoneFraction, opacity: opacity2, handleOpacityChange }, featureName)), jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 2, className: lcClasses.layerControllerSubRow, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: () => setFeatureFilterMode(featureFilterMode === "featureSelection" ? null : "featureSelection"), className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle visibility of unselected points", children: featureFilterMode === "featureSelection" ? jsx$1(VisibilityOffIcon, {}) : jsx$1(VisibilityIcon, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: getDefaultColor("dark"), setColor: null, isStaticColor: true, isColormap: false, visible: true }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: "Unselected" }) }), jsx$1(Grid$1, { size: 2, sx: { paddingRight: "12px", overflow: "visible" }, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": "Adjust opacity for unselected layer" }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }) })] }) }) })] }) : null] });
|
|
260247
261752
|
}
|
|
260248
|
-
const useStyles$
|
|
261753
|
+
const useStyles$f = makeStyles()(() => ({
|
|
260249
261754
|
// Cap the channel name's width; imageLayerName ellipsizes the overflow.
|
|
260250
261755
|
channelName: {
|
|
260251
261756
|
overflow: "hidden",
|
|
@@ -260264,7 +261769,7 @@ const useStyles$e = makeStyles()(() => ({
|
|
|
260264
261769
|
function SegmentationChannelEllipsisMenu(props) {
|
|
260265
261770
|
const { obsType, featureType, featureValueType, strokeWidth, setStrokeWidth, filled, setFilled, featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible } = props;
|
|
260266
261771
|
const [open2, setOpen] = useState(false);
|
|
260267
|
-
const { classes: classes2 } = useStyles$
|
|
261772
|
+
const { classes: classes2 } = useStyles$f();
|
|
260268
261773
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
260269
261774
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
260270
261775
|
const filledId = $bdb11010cef70236$export$f680877a34711e37();
|
|
@@ -260283,7 +261788,7 @@ function SegmentationChannelController(props) {
|
|
|
260283
261788
|
const Visibility = useMemo$1(() => visibleSetting ? VisibilityIcon : VisibilityOffIcon, [visibleSetting]);
|
|
260284
261789
|
const isStaticColor = obsColorEncoding === "spatialChannelColor";
|
|
260285
261790
|
const isColormap = obsColorEncoding === "geneSelection";
|
|
260286
|
-
const { classes: classes2 } = useStyles$
|
|
261791
|
+
const { classes: classes2 } = useStyles$f();
|
|
260287
261792
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
260288
261793
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
260289
261794
|
const handleVisibleChange = useCallback(() => {
|
|
@@ -261524,7 +263029,7 @@ function useBaseQuery(options, Observer, queryClient) {
|
|
|
261524
263029
|
function useQuery(options, queryClient) {
|
|
261525
263030
|
return useBaseQuery(options, QueryObserver);
|
|
261526
263031
|
}
|
|
261527
|
-
const useStyles$
|
|
263032
|
+
const useStyles$e = makeStyles()(() => ({
|
|
261528
263033
|
channelMenuButton: {
|
|
261529
263034
|
backgroundColor: "transparent",
|
|
261530
263035
|
padding: "3px 0",
|
|
@@ -261538,7 +263043,7 @@ const useStyles$d = makeStyles()(() => ({
|
|
|
261538
263043
|
function ChannelOptions(props) {
|
|
261539
263044
|
const { onRemove: onRemove2, onResetWindowUsingIQR, showValueExtent, setShowValueExtent, numResolutions, spatialMaxResolution, setSpatialMaxResolution } = props;
|
|
261540
263045
|
const [open2, setOpen] = useState(false);
|
|
261541
|
-
const { classes: classes2 } = useStyles$
|
|
263046
|
+
const { classes: classes2 } = useStyles$e();
|
|
261542
263047
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
261543
263048
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
261544
263049
|
function handleRemove() {
|
|
@@ -261551,7 +263056,7 @@ function ChannelOptions(props) {
|
|
|
261551
263056
|
const domainTypeId = $bdb11010cef70236$export$f680877a34711e37();
|
|
261552
263057
|
return jsxs(PopperMenu, { open: open2, setOpen, buttonIcon: jsx$1(MoreVertIcon, { fontSize: "small" }), buttonClassName: classes2.channelMenuButton, containerClassName: menuClasses.imageLayerPopperContainer, placement: "bottom-end", withPaper: true, "aria-label": "Open channel options menu", children: [jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: domainTypeId, children: "Best Resolution: " }), jsx$1(Slider, { value: spatialMaxResolution || 1, valueLabelDisplay: "auto", onChange: (e3, v) => setSpatialMaxResolution(v), min: 1, max: numResolutions - 1, step: 1, orientation: "horizontal" })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: domainTypeId, children: "Slider Extent: " }), jsxs(NativeSelect, { onChange: handleDomainTypeChange, value: showValueExtent ? "Value Min/Max" : "Dtype Min/Max", inputProps: { id: domainTypeId, "aria-label": "Slider extent selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "Value Min/Max", children: "Value Min/Max" }), jsx$1("option", { value: "Dtype Min/Max", children: "Dtype Min/Max" })] })] }), jsx$1(MenuItem, { dense: true, disableGutters: true, component: "button", onClick: onResetWindowUsingIQR, className: classes2.menuItemButton, "aria-label": "Click to use IQR for channel", children: "Reset window using IQR" }), jsx$1(MenuItem, { dense: true, disableGutters: true, component: "button", onClick: handleRemove, className: classes2.menuItemButton, "aria-label": "Click to remove channel", children: "Remove channel" })] });
|
|
261553
263058
|
}
|
|
261554
|
-
const useStyles$
|
|
263059
|
+
const useStyles$d = makeStyles()(() => ({
|
|
261555
263060
|
channelSlider: {
|
|
261556
263061
|
marginTop: "7px"
|
|
261557
263062
|
}
|
|
@@ -261561,13 +263066,13 @@ function ChannelSlider(props) {
|
|
|
261561
263066
|
const rgbColor = toRgbUIString(colormapOn, color2, theme);
|
|
261562
263067
|
const dtype = image2?.getDtype();
|
|
261563
263068
|
const fullDomain = dtype ? DOMAINS[dtype] : [0, 0];
|
|
261564
|
-
const { classes: classes2 } = useStyles$
|
|
263069
|
+
const { classes: classes2 } = useStyles$d();
|
|
261565
263070
|
useEffect(() => {
|
|
261566
|
-
if (!window2 && !disabled && Array.isArray(minMaxDomain)) {
|
|
261567
|
-
setWindow2(minMaxDomain);
|
|
263071
|
+
if (!window2 && !disabled && Array.isArray(minMaxDomain?.upperThreeQuarters)) {
|
|
263072
|
+
setWindow2(minMaxDomain?.upperThreeQuarters);
|
|
261568
263073
|
}
|
|
261569
263074
|
}, [minMaxDomain, window2, disabled]);
|
|
261570
|
-
const [min2, max2] = (showValueExtent ? minMaxDomain : fullDomain) || [0, 0];
|
|
263075
|
+
const [min2, max2] = (showValueExtent ? minMaxDomain?.minMax : fullDomain) || [0, 0];
|
|
261571
263076
|
const step = max2 - min2 < 500 && dtype?.startsWith("Float") ? (max2 - min2) / 500 : 1;
|
|
261572
263077
|
const handleChangeDebounced = useCallback(debounce$5(setWindow2 || (() => {
|
|
261573
263078
|
}), 3, { trailing: true }), [setWindow2]);
|
|
@@ -261576,7 +263081,7 @@ function ChannelSlider(props) {
|
|
|
261576
263081
|
return `${labelPrefix} for ${rgbColor} colormap channel`;
|
|
261577
263082
|
}, getAriaValueText: () => `Current colormap values: ${rgbColor}-${window2}`, min: min2, max: max2, step, orientation: "horizontal", className: classes2.channelSlider, style: { color: rgbColor }, disabled });
|
|
261578
263083
|
}
|
|
261579
|
-
const useStyles$
|
|
263084
|
+
const useStyles$c = makeStyles()(() => ({
|
|
261580
263085
|
visibilityCheckbox: {
|
|
261581
263086
|
padding: "10px 0"
|
|
261582
263087
|
}
|
|
@@ -261590,10 +263095,10 @@ function getCheckboxColor(colormapOn, color2, theme) {
|
|
|
261590
263095
|
function ChannelVisibilityCheckbox(props) {
|
|
261591
263096
|
const { color: color2, visible, setVisible, disabled, theme, colormapOn } = props;
|
|
261592
263097
|
const rgbColor = getCheckboxColor(colormapOn, color2, theme);
|
|
261593
|
-
const { classes: classes2 } = useStyles$
|
|
263098
|
+
const { classes: classes2 } = useStyles$c();
|
|
261594
263099
|
return jsx$1(Checkbox$1, { onChange: (e3, v) => setVisible(v), checked: visible, disabled, className: classes2.visibilityCheckbox, style: { color: rgbColor, "&$checked": { color: rgbColor } }, slotProps: { input: { "aria-label": "Toggle channel visibility" } } });
|
|
261595
263100
|
}
|
|
261596
|
-
const useStyles$
|
|
263101
|
+
const useStyles$b = makeStyles()(() => ({
|
|
261597
263102
|
oneLineChannelSelect: {
|
|
261598
263103
|
width: "90%",
|
|
261599
263104
|
marginLeft: "5%",
|
|
@@ -261602,7 +263107,7 @@ const useStyles$a = makeStyles()(() => ({
|
|
|
261602
263107
|
}));
|
|
261603
263108
|
function ChannelSelectionDropdown(props) {
|
|
261604
263109
|
const { featureIndex, channelsSortOrder, targetC, setTargetC, setWindow: setWindow2, disabled } = props;
|
|
261605
|
-
const { classes: classes2 } = useStyles$
|
|
263110
|
+
const { classes: classes2 } = useStyles$b();
|
|
261606
263111
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
261607
263112
|
function handleChange(event2) {
|
|
261608
263113
|
setTargetC(event2.target.value === "" ? null : Number(event2.target.value));
|
|
@@ -261672,7 +263177,13 @@ function ImageChannelController(props) {
|
|
|
261672
263177
|
use3d: ctx.queryKey[5]
|
|
261673
263178
|
});
|
|
261674
263179
|
const [newDomain] = stats.domains;
|
|
261675
|
-
return
|
|
263180
|
+
return {
|
|
263181
|
+
minMax: newDomain,
|
|
263182
|
+
// iqr: [stats.q1s[0], stats.q3s[0]],
|
|
263183
|
+
// This seems to work better than the IQR for the slider
|
|
263184
|
+
// upper bound.
|
|
263185
|
+
upperThreeQuarters: [stats.q1s[0], newDomain[1]]
|
|
263186
|
+
};
|
|
261676
263187
|
},
|
|
261677
263188
|
meta: { image: image2 }
|
|
261678
263189
|
});
|
|
@@ -261680,7 +263191,7 @@ function ImageChannelController(props) {
|
|
|
261680
263191
|
const disabled = minMaxQuery.isLoading;
|
|
261681
263192
|
function handleResetWindowUsingIQR() {
|
|
261682
263193
|
if (!disabled) {
|
|
261683
|
-
setWindow2(minMaxDomain);
|
|
263194
|
+
setWindow2(minMaxDomain?.upperThreeQuarters);
|
|
261684
263195
|
}
|
|
261685
263196
|
}
|
|
261686
263197
|
return jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", sx: channelRowContainerSx, children: [jsx$1(Grid$1, { size: 1, sx: channelControlCellSx, children: jsx$1(ChannelVisibilityCheckbox, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, colormapOn }) }), jsx$1(Grid$1, { size: 1, sx: channelControlCellSx, children: jsx$1(ChannelColorPickerMenu, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, isStaticColor: !colormapOn, palette: VIEWER_PALETTE }) }), jsx$1(Grid$1, { size: 6, sx: channelSelectorCellSx, children: jsx$1(ChannelSelectionDropdown, { featureIndex, targetC, setTargetC, setWindow: setWindow2, disabled: isLoading, channelsSortOrder }) }), jsx$1(Grid$1, { size: 3, sx: channelSliderCellSx, children: jsx$1(ChannelSlider, { image: image2, targetT, targetZ, targetC, window: window2, setWindow: setWindow2, disabled, color: color2, theme, colormapOn, showValueExtent, minMaxDomain }) }), jsx$1(Grid$1, { size: 1, sx: channelControlCellSx, children: jsx$1(ChannelOptions, { onRemove: onRemove2, showValueExtent, setShowValueExtent, onResetWindowUsingIQR: handleResetWindowUsingIQR, numResolutions, spatialMaxResolution, setSpatialMaxResolution }) })] });
|
|
@@ -261737,7 +263248,7 @@ function LoadingStatusIndicator(props) {
|
|
|
261737
263248
|
}
|
|
261738
263249
|
return jsxs(Grid$1, { container: true, px: 0.5, children: [jsx$1(Grid$1, { size: 6, alignItems: "start", children: jsx$1(Grid$1, { container: true, alignItems: "center", gap: 1, children: statusColor !== "success" ? jsx$1(StatusChip, { label: statusLabel, color: statusColor, size: "small" }) : null }) }), jsx$1(Grid$1, { size: 6, px: 1, my: 0.25, children: jsx$1(LoadingText, { bricksLoaded, currentRequestCount, totalBricksRequested, isLoading }) }), jsx$1(Grid$1, { size: 12, children: jsxs(Grid$1, { container: true, direction: "row", spacing: 2, alignItems: "center", wrap: "nowrap", children: [jsx$1(LoadingControlButton, { startIcon: jsx$1(Stop, {}), onClick: onStopLoading, disabled: noNewRequests, ariaLabel: "Stop loading data and render at highest resolution", children: "Stop Loading" }), jsx$1(LoadingControlButton, { startIcon: jsx$1(Replay, {}), onClick: onRestartLoading, disabled: !noNewRequests && !isLoading, ariaLabel: "Restart data loading", children: "Restart Loading" })] }) }), jsx$1(Grid$1, { size: 12, visibility: isLoading ? "visible" : "hidden", mt: 1, mb: 0.5, children: jsx$1(LinearProgress, { variant: "determinate", value: percentage }) })] });
|
|
261739
263250
|
}
|
|
261740
|
-
const useStyles$
|
|
263251
|
+
const useStyles$a = makeStyles()(() => ({
|
|
261741
263252
|
imageLayerButton: {
|
|
261742
263253
|
borderStyle: "dashed",
|
|
261743
263254
|
marginTop: "10px",
|
|
@@ -261880,7 +263391,7 @@ function ImageLayerController(props) {
|
|
|
261880
263391
|
}, [visible, setVisible]);
|
|
261881
263392
|
const handleOpacityChange = useCallback((e3, v) => setOpacity2(v), [setOpacity2]);
|
|
261882
263393
|
const handleOpenChange = useCallback(() => setOpen((prev2) => !prev2), []);
|
|
261883
|
-
const { classes: classes2 } = useStyles$
|
|
263394
|
+
const { classes: classes2 } = useStyles$a();
|
|
261884
263395
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
261885
263396
|
const { classes: controllerSectionClasses } = useControllerSectionStyles();
|
|
261886
263397
|
const isMultiChannel = photometricInterpretation !== "RGB";
|
|
@@ -261892,7 +263403,7 @@ function ImageLayerController(props) {
|
|
|
261892
263403
|
return jsx$1(ImageChannelController, { theme, coordinationScopesRaw, layerScope, channelScope: cScope, targetT, targetZ, targetC: channelIndex, setTargetC: setSpatialTargetC, visible: spatialChannelVisible, setVisible: setSpatialChannelVisible, opacity: spatialChannelOpacity, setOpacity: setSpatialChannelOpacity, color: spatialChannelColor, setColor: setSpatialChannelColor, window: spatialChannelWindow, setWindow: setSpatialChannelWindow, colormapOn: colormap !== null, featureIndex, image: image2, channelsSortOrder, spatialRenderingMode, numResolutions, spatialMaxResolution, setSpatialMaxResolution }, cScope);
|
|
261893
263404
|
}), jsx$1(Button, { disabled: channelScopes.length === MAX_CHANNELS$1 || channelScopes.length === imageNumChannels, onClick: handleChannelAdd, fullWidth: true, variant: "outlined", className: classes2.imageLayerButton, startIcon: jsx$1(AddIcon, {}), size: "small", "aria-label": "Add a channel to this layer", children: "Add Channel" })] }) : null, is3dMode && image2 ? jsxs(Grid$1, { container: true, direction: "column", justifyContent: "space-between", className: classes2.imageChannelControllerGrid, children: [jsx$1(Typography, { className: classes2.clippingPanesLabel, children: "Clipping planes:" }), jsx$1(Grid$1, { size: 12, className: classes2.clippingSliders, children: jsx$1(ClippingSliders, { image: image2, spatialSliceX, spatialSliceY, spatialSliceZ, setSpatialSliceX, setSpatialSliceY, setSpatialSliceZ }) }), jsx$1(LoadingStatusIndicator, { loadingProgress: volumeLoadingProgress, onStopLoading: onStopVolumeLoading, onRestartLoading: onRestartVolumeLoading, stillRef: volumeStillRef, spatialRenderingMode })] }) : null] }) });
|
|
261894
263405
|
}
|
|
261895
|
-
const useStyles$
|
|
263406
|
+
const useStyles$9 = makeStyles()((theme) => ({
|
|
261896
263407
|
dimensionsIcon: {
|
|
261897
263408
|
height: "40px",
|
|
261898
263409
|
width: "40px",
|
|
@@ -261916,7 +263427,7 @@ const useStyles$8 = makeStyles()((theme) => ({
|
|
|
261916
263427
|
function GlobalDimensionSlider(props) {
|
|
261917
263428
|
const { label: label2, targetValue, setTargetValue, min: min2 = 0, max: max2 = 0, spatialRenderingMode = null, setSpatialRenderingMode = null, enable3d = true } = props;
|
|
261918
263429
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
261919
|
-
const { classes: classes2 } = useStyles$
|
|
263430
|
+
const { classes: classes2 } = useStyles$9();
|
|
261920
263431
|
const isForZ = spatialRenderingMode !== null;
|
|
261921
263432
|
const is3dMode = spatialRenderingMode === "3D";
|
|
261922
263433
|
function handleRenderingModeChange(event2) {
|
|
@@ -261927,7 +263438,7 @@ function GlobalDimensionSlider(props) {
|
|
|
261927
263438
|
}
|
|
261928
263439
|
return jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", sx: channelRowContainerSx, children: [jsx$1(Grid$1, { size: 1, sx: channelControlCellSx, children: jsx$1(SvgDimensions, { className: classes2.dimensionsIcon }) }), jsx$1(Grid$1, { size: 1, sx: channelSelectorCellSx, children: jsx$1(Typography, { className: classes2.dimensionLabel, children: label2 }) }), jsx$1(Grid$1, { size: 8, sx: channelSliderCellSx, children: !is3dMode ? jsx$1(Slider, { value: targetValue, min: min2, max: max2, step: 1, onChange: (e3, v) => setTargetValue(v), className: classes2.dimensionSlider, valueLabelDisplay: "auto", orientation: "horizontal", disabled: spatialRenderingMode === "3D", "aria-label": `${label2}-slice slider` }) : null }), jsx$1(Grid$1, { size: 2, sx: channelControlCellSx, children: isForZ && enable3d ? jsx$1(FormGroup, { row: true, className: classes2.switchFormGroup, children: jsx$1(FormControlLabel$1, { control: jsx$1(Switch, { color: "primary", checked: spatialRenderingMode === "3D", onChange: handleRenderingModeChange, name: "is3dMode" }), label: "3D" }) }) : null })] }) }) });
|
|
261929
263440
|
}
|
|
261930
|
-
const useStyles$
|
|
263441
|
+
const useStyles$8 = makeStyles()(() => ({
|
|
261931
263442
|
layerTypeCentroidSegmentationIcon: {
|
|
261932
263443
|
height: "100%",
|
|
261933
263444
|
marginLeft: "1px",
|
|
@@ -261977,7 +263488,7 @@ function CombinedEllipsisMenu(props) {
|
|
|
261977
263488
|
}
|
|
261978
263489
|
function SegmentationCentroidsController(props) {
|
|
261979
263490
|
const { theme, segScope, segLayerCoordination, segChannelScopesByLayer, segChannelCoordination, pointScope, pointLayerCoordination } = props;
|
|
261980
|
-
const { classes: classes2 } = useStyles$
|
|
263491
|
+
const { classes: classes2 } = useStyles$8();
|
|
261981
263492
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
261982
263493
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
261983
263494
|
const channelScopes = segChannelScopesByLayer?.[segScope] ?? [];
|
|
@@ -262419,6 +263930,218 @@ function LinkControllerSubscriber(props) {
|
|
|
262419
263930
|
} = props;
|
|
262420
263931
|
return jsx$1(TitleInfo, { title: title2, closeButtonVisible, removeGridComponent, isScroll: true, theme, isReady: true, children: jsx$1(LinkController, { linkIDInit: linkID, authToken, linkEndpoint, websocketEndpoint, fileTypes, stores, coordinationTypes }) });
|
|
262421
263932
|
}
|
|
263933
|
+
const useStyles$7 = makeStyles()((theme) => ({
|
|
263934
|
+
textSection: {
|
|
263935
|
+
padding: "6px 10px"
|
|
263936
|
+
},
|
|
263937
|
+
annotationMarkdown: {
|
|
263938
|
+
"& p, details, table": {
|
|
263939
|
+
fontSize: "80%",
|
|
263940
|
+
opacity: "0.8"
|
|
263941
|
+
},
|
|
263942
|
+
"& details": {
|
|
263943
|
+
marginBottom: "6px"
|
|
263944
|
+
},
|
|
263945
|
+
"& summary": {
|
|
263946
|
+
// TODO(monorepo): lighten color by 10%
|
|
263947
|
+
borderBottom: `1px solid ${theme.palette.primaryBackground}`,
|
|
263948
|
+
cursor: "pointer"
|
|
263949
|
+
}
|
|
263950
|
+
},
|
|
263951
|
+
navigation: {
|
|
263952
|
+
display: "flex",
|
|
263953
|
+
alignItems: "center",
|
|
263954
|
+
justifyContent: "space-between",
|
|
263955
|
+
padding: "0 4px",
|
|
263956
|
+
borderTop: `1px solid ${theme.palette.primaryBackground}`,
|
|
263957
|
+
borderBottom: `1px solid ${theme.palette.primaryBackground}`
|
|
263958
|
+
}
|
|
263959
|
+
}));
|
|
263960
|
+
function AnnotationText(props) {
|
|
263961
|
+
const { text: text2, textType } = props;
|
|
263962
|
+
const { classes: classes2 } = useStyles$7();
|
|
263963
|
+
if (!text2) {
|
|
263964
|
+
return null;
|
|
263965
|
+
}
|
|
263966
|
+
return jsx$1("div", { className: classes2.annotationMarkdown, children: textType === DescriptionType.MARKDOWN ? jsx$1(Markdown, { children: text2 }) : jsx$1("p", { children: text2 }) });
|
|
263967
|
+
}
|
|
263968
|
+
function AnnotationController(props) {
|
|
263969
|
+
const { story, frameIndex, setFrameIndex } = props;
|
|
263970
|
+
const { classes: classes2 } = useStyles$7();
|
|
263971
|
+
if (!story) {
|
|
263972
|
+
return jsx$1("div", { className: classes2.textSection, children: jsx$1(Typography, { variant: "body2", children: "No annotation story has been loaded." }) });
|
|
263973
|
+
}
|
|
263974
|
+
const frames = story.frames || [];
|
|
263975
|
+
const numFrames = frames.length;
|
|
263976
|
+
const hasFrameIndex = typeof frameIndex === "number";
|
|
263977
|
+
const currentFrame = hasFrameIndex ? frames[frameIndex] : null;
|
|
263978
|
+
const canGoBack = hasFrameIndex;
|
|
263979
|
+
const canGoForward = hasFrameIndex ? frameIndex < numFrames - 1 : numFrames > 0;
|
|
263980
|
+
function goBack() {
|
|
263981
|
+
setFrameIndex(frameIndex > 0 ? frameIndex - 1 : null);
|
|
263982
|
+
}
|
|
263983
|
+
function goForward() {
|
|
263984
|
+
setFrameIndex(hasFrameIndex ? frameIndex + 1 : 0);
|
|
263985
|
+
}
|
|
263986
|
+
const frameLabel = hasFrameIndex ? `Frame ${frameIndex + 1} of ${numFrames}` : `Overview (${numFrames} frames)`;
|
|
263987
|
+
return jsxs("div", { children: [jsxs("div", { className: classes2.textSection, children: [story.title ? jsx$1(Typography, { variant: "h6", children: story.title }) : null, jsx$1(AnnotationText, { text: story.description, textType: story.descriptionType })] }), jsxs("div", { className: classes2.navigation, children: [jsx$1(Button, { size: "small", onClick: goBack, disabled: !canGoBack, startIcon: jsx$1(ArrowLeft, {}), children: "Previous" }), jsx$1(Typography, { variant: "body2", children: frameLabel }), jsx$1(Button, { size: "small", onClick: goForward, disabled: !canGoForward, endIcon: jsx$1(ArrowRight, {}), children: "Next" })] }), currentFrame ? jsxs("div", { className: classes2.textSection, children: [currentFrame.title ? jsx$1(Typography, { variant: "subtitle1", children: currentFrame.title }) : null, jsx$1(AnnotationText, { text: currentFrame.description, textType: currentFrame.descriptionType })] }) : null, jsx$1(MenuList, { dense: true, "aria-label": "Annotation frames", children: frames.map((frame2, i2) => jsx$1(MenuItem, { selected: i2 === frameIndex, onClick: () => setFrameIndex(i2), children: jsx$1(ListItemText, { primary: `${i2 + 1}. ${frame2.title || frame2.uid}` }) }, frame2.uid)) })] });
|
|
263988
|
+
}
|
|
263989
|
+
function AnnotationControllerSubscriber(props) {
|
|
263990
|
+
const {
|
|
263991
|
+
uuid: uuid2,
|
|
263992
|
+
removeGridComponent,
|
|
263993
|
+
theme,
|
|
263994
|
+
title: title2 = "Annotation",
|
|
263995
|
+
closeButtonVisible,
|
|
263996
|
+
downloadButtonVisible,
|
|
263997
|
+
helpText = ViewHelpMapping.ANNOTATION_CONTROLLER,
|
|
263998
|
+
// TODO: importable/exportable
|
|
263999
|
+
// Note: areAnnotationsEditable is a prop passed down from
|
|
264000
|
+
// the ancestor <Vitessce/> or <VitS/> component.
|
|
264001
|
+
// TODO: use areAnnotationsEditable.
|
|
264002
|
+
// eslint-disable-next-line no-unused-vars
|
|
264003
|
+
areAnnotationsEditable
|
|
264004
|
+
} = props;
|
|
264005
|
+
const loaders = useLoaders();
|
|
264006
|
+
const [
|
|
264007
|
+
// eslint-disable-next-line no-unused-vars
|
|
264008
|
+
coordinationScopes,
|
|
264009
|
+
_coordinationScopesBy,
|
|
264010
|
+
coordinationValues
|
|
264011
|
+
] = useViewMapping(uuid2);
|
|
264012
|
+
const [{ dataset, annotationStory, annotationFrameIndex }, { setAnnotationStory, setAnnotationFrameIndex }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.ANNOTATION_CONTROLLER], coordinationScopes, coordinationValues, uuid2);
|
|
264013
|
+
const [, annotationStoryStatus, annotationStoryUrls, annotationStoryError] = useAnnotationStoryData(loaders, dataset, false, { setAnnotationStory }, { annotationStory }, {});
|
|
264014
|
+
const errors = [annotationStoryError];
|
|
264015
|
+
const isReady = useReady([annotationStoryStatus]);
|
|
264016
|
+
const urls2 = useUrls([annotationStoryUrls]);
|
|
264017
|
+
return jsx$1(TitleInfo, { title: title2, theme, closeButtonVisible, downloadButtonVisible, removeGridComponent, isScroll: true, isReady, urls: urls2, errors, helpText, withPadding: false, children: jsx$1(AnnotationController, { story: annotationStory, frameIndex: annotationFrameIndex, setFrameIndex: setAnnotationFrameIndex }) });
|
|
264018
|
+
}
|
|
264019
|
+
const NUM_GRID_COLUMNS = 12;
|
|
264020
|
+
const NUM_GRID_ROWS = 12;
|
|
264021
|
+
const DEFAULT_ANNOTATION_CONTROLLER_UID = "annotation-controller";
|
|
264022
|
+
const DEFAULT_ANNOTATION_CONTROLLER_WIDTH = 3;
|
|
264023
|
+
function hasAnnotationControllerView(config3) {
|
|
264024
|
+
return (config3?.layout || []).some((view) => view.component === ViewType$1.ANNOTATION_CONTROLLER);
|
|
264025
|
+
}
|
|
264026
|
+
function getUniqueViewUid(layout, baseUid) {
|
|
264027
|
+
const usedUids = new Set(layout.map((view) => view.uid).filter(Boolean));
|
|
264028
|
+
if (!usedUids.has(baseUid)) {
|
|
264029
|
+
return baseUid;
|
|
264030
|
+
}
|
|
264031
|
+
let i2 = 1;
|
|
264032
|
+
while (usedUids.has(`${baseUid}-${i2}`)) {
|
|
264033
|
+
i2 += 1;
|
|
264034
|
+
}
|
|
264035
|
+
return `${baseUid}-${i2}`;
|
|
264036
|
+
}
|
|
264037
|
+
function getExistingScope(layout, coordinationType) {
|
|
264038
|
+
const scope = layout.map((view) => view.coordinationScopes?.[coordinationType]).find((s2) => typeof s2 === "string");
|
|
264039
|
+
return scope;
|
|
264040
|
+
}
|
|
264041
|
+
function addAnnotationControllerView(config3, options = {}) {
|
|
264042
|
+
const { width: width2 = DEFAULT_ANNOTATION_CONTROLLER_WIDTH, uid: uid2 = DEFAULT_ANNOTATION_CONTROLLER_UID } = options;
|
|
264043
|
+
if (!Number.isInteger(width2) || width2 < 1 || width2 >= NUM_GRID_COLUMNS) {
|
|
264044
|
+
throw new Error(`The annotationController width must be a whole number between 1 and ${NUM_GRID_COLUMNS - 1}.`);
|
|
264045
|
+
}
|
|
264046
|
+
const layout = config3?.layout || [];
|
|
264047
|
+
const remainingColumns = NUM_GRID_COLUMNS - width2;
|
|
264048
|
+
const scaleX2 = (value2) => Math.round(Math.min(Math.max(value2, 0), NUM_GRID_COLUMNS) * remainingColumns / NUM_GRID_COLUMNS);
|
|
264049
|
+
const newLayout = layout.map((view) => {
|
|
264050
|
+
const x2 = scaleX2(view.x);
|
|
264051
|
+
const right2 = Math.max(scaleX2(view.x + view.w), x2 + 1);
|
|
264052
|
+
return {
|
|
264053
|
+
...view,
|
|
264054
|
+
x: Math.min(x2, remainingColumns - 1),
|
|
264055
|
+
w: Math.min(right2, remainingColumns) - Math.min(x2, remainingColumns - 1)
|
|
264056
|
+
};
|
|
264057
|
+
});
|
|
264058
|
+
const coordinationScopes = Object.fromEntries([
|
|
264059
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
264060
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
264061
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE
|
|
264062
|
+
].map((coordinationType) => [coordinationType, getExistingScope(layout, coordinationType)]).filter(([, scope]) => scope !== void 0));
|
|
264063
|
+
newLayout.push({
|
|
264064
|
+
uid: getUniqueViewUid(layout, uid2),
|
|
264065
|
+
component: ViewType$1.ANNOTATION_CONTROLLER,
|
|
264066
|
+
...Object.keys(coordinationScopes).length > 0 ? { coordinationScopes } : {},
|
|
264067
|
+
x: remainingColumns,
|
|
264068
|
+
y: 0,
|
|
264069
|
+
w: width2,
|
|
264070
|
+
h: NUM_GRID_ROWS
|
|
264071
|
+
});
|
|
264072
|
+
return {
|
|
264073
|
+
...config3,
|
|
264074
|
+
layout: newLayout
|
|
264075
|
+
};
|
|
264076
|
+
}
|
|
264077
|
+
function isAnyAnnotationEditing(config3) {
|
|
264078
|
+
const type2 = CoordinationType$1.ANNOTATION_EDITABLE;
|
|
264079
|
+
const scopeValues = Object.values(config3?.coordinationSpace?.[type2] || {});
|
|
264080
|
+
const viewValues = (config3?.layout || []).map((view) => view.coordinationValues?.[type2]);
|
|
264081
|
+
return [...scopeValues, ...viewValues].some((value2) => value2 === true);
|
|
264082
|
+
}
|
|
264083
|
+
function hasScopeMapping(view, coordinationSpace, coordinationType) {
|
|
264084
|
+
if (view.coordinationScopes?.[coordinationType] !== void 0) {
|
|
264085
|
+
return true;
|
|
264086
|
+
}
|
|
264087
|
+
const metaScopes = view.coordinationScopes?.[CoordinationType$1.META_COORDINATION_SCOPES];
|
|
264088
|
+
const metaScopesArr = Array.isArray(metaScopes) ? metaScopes : [metaScopes].filter(Boolean);
|
|
264089
|
+
const metaSpace = coordinationSpace?.[CoordinationType$1.META_COORDINATION_SCOPES] || {};
|
|
264090
|
+
return metaScopesArr.some((metaScope) => metaSpace[metaScope]?.[coordinationType] !== void 0);
|
|
264091
|
+
}
|
|
264092
|
+
function getUnusedScopeName(config3, coordinationType) {
|
|
264093
|
+
const usedScopes = /* @__PURE__ */ new Set([
|
|
264094
|
+
...Object.keys(config3?.coordinationSpace?.[coordinationType] || {}),
|
|
264095
|
+
...(config3?.layout || []).map((view) => view.coordinationScopes?.[coordinationType])
|
|
264096
|
+
]);
|
|
264097
|
+
let i2 = 0;
|
|
264098
|
+
const toName = (n3) => n3 < 26 ? String.fromCharCode(65 + n3) : toName(Math.floor(n3 / 26) - 1) + String.fromCharCode(65 + n3 % 26);
|
|
264099
|
+
while (usedScopes.has(toName(i2))) {
|
|
264100
|
+
i2 += 1;
|
|
264101
|
+
}
|
|
264102
|
+
return toName(i2);
|
|
264103
|
+
}
|
|
264104
|
+
function setAnnotationEditing(config3, value2) {
|
|
264105
|
+
if (!hasAnnotationControllerView(config3)) {
|
|
264106
|
+
throw new Error("The view config does not contain an annotationController view. Call addAnnotationControllerView first.");
|
|
264107
|
+
}
|
|
264108
|
+
const type2 = CoordinationType$1.ANNOTATION_EDITABLE;
|
|
264109
|
+
const coordinationSpace = config3.coordinationSpace || {};
|
|
264110
|
+
const supportsEditable = (view) => view.component === ViewType$1.ANNOTATION_CONTROLLER || COMPONENT_COORDINATION_TYPES[view.component]?.includes(type2);
|
|
264111
|
+
const needsScope = (view) => supportsEditable(view) && view.coordinationValues?.[type2] === void 0 && !hasScopeMapping(view, coordinationSpace, type2);
|
|
264112
|
+
const existingControllerScope = config3.layout.filter((view) => view.component === ViewType$1.ANNOTATION_CONTROLLER).map((view) => view.coordinationScopes?.[type2]).find((scope) => typeof scope === "string");
|
|
264113
|
+
const newScope = config3.layout.some(needsScope) ? existingControllerScope ?? getUnusedScopeName(config3, type2) : void 0;
|
|
264114
|
+
const newLayout = config3.layout.map((view) => {
|
|
264115
|
+
if (needsScope(view)) {
|
|
264116
|
+
return {
|
|
264117
|
+
...view,
|
|
264118
|
+
coordinationScopes: { ...view.coordinationScopes, [type2]: newScope }
|
|
264119
|
+
};
|
|
264120
|
+
}
|
|
264121
|
+
if (view.coordinationValues?.[type2] !== void 0) {
|
|
264122
|
+
return {
|
|
264123
|
+
...view,
|
|
264124
|
+
coordinationValues: { ...view.coordinationValues, [type2]: value2 }
|
|
264125
|
+
};
|
|
264126
|
+
}
|
|
264127
|
+
return view;
|
|
264128
|
+
});
|
|
264129
|
+
const newScopeValues = Object.fromEntries([...Object.keys(coordinationSpace[type2] || {}), ...newScope ? [newScope] : []].map((scope) => [scope, value2]));
|
|
264130
|
+
return {
|
|
264131
|
+
...config3,
|
|
264132
|
+
coordinationSpace: {
|
|
264133
|
+
...coordinationSpace,
|
|
264134
|
+
[type2]: newScopeValues
|
|
264135
|
+
},
|
|
264136
|
+
layout: newLayout
|
|
264137
|
+
};
|
|
264138
|
+
}
|
|
264139
|
+
function enableAnnotationEditing(config3) {
|
|
264140
|
+
return setAnnotationEditing(config3, true);
|
|
264141
|
+
}
|
|
264142
|
+
function disableAnnotationEditing(config3) {
|
|
264143
|
+
return setAnnotationEditing(config3, false);
|
|
264144
|
+
}
|
|
262422
264145
|
const useStyles$6 = makeStyles()(() => ({
|
|
262423
264146
|
info: {
|
|
262424
264147
|
// details
|
|
@@ -264230,7 +265953,7 @@ function HiglassGlobalStyles(props) {
|
|
|
264230
265953
|
}
|
|
264231
265954
|
register({ dataFetcher: ZarrMultivecDataFetcher_default, config: ZarrMultivecDataFetcher_default.config }, { pluginType: "dataFetcher" });
|
|
264232
265955
|
const LazyHiGlassComponent = React__default.lazy(async () => {
|
|
264233
|
-
const { HiGlassComponent } = await import("./higlass-
|
|
265956
|
+
const { HiGlassComponent } = await import("./higlass-BzshVp46.js");
|
|
264234
265957
|
return { default: HiGlassComponent };
|
|
264235
265958
|
});
|
|
264236
265959
|
const HG_SIZE = 800;
|
|
@@ -267187,7 +268910,7 @@ function NeuroglancerGlobalStyles(props) {
|
|
|
267187
268910
|
const { classes: classes2 } = props;
|
|
267188
268911
|
return jsxs(Fragment, { children: [jsx$1(GlobalStyles$3, { styles: globalNeuroglancerCss }), jsx$1(ScopedGlobalStyles, { styles: globalNeuroglancerStyles, parentClassName: classes2.neuroglancerWrapper })] });
|
|
267189
268912
|
}
|
|
267190
|
-
const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-
|
|
268913
|
+
const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-Ch1xO_u5.js"));
|
|
267191
268914
|
function createWorker() {
|
|
267192
268915
|
const worker = new WorkerFactory$1();
|
|
267193
268916
|
worker.AsyncComputationWorker = WorkerFactory;
|
|
@@ -321504,7 +323227,7 @@ const VEGA_THEMES = {
|
|
|
321504
323227
|
};
|
|
321505
323228
|
const DATASET_NAME = "table";
|
|
321506
323229
|
function VegaGlobalStyles() {
|
|
321507
|
-
const { theme } = useStyles$
|
|
323230
|
+
const { theme } = useStyles$A();
|
|
321508
323231
|
return jsx$1(GlobalStyles$3, { styles: {
|
|
321509
323232
|
"#vg-tooltip-element.vg-tooltip.custom-theme": {
|
|
321510
323233
|
boxShadow: "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)",
|
|
@@ -321538,7 +323261,7 @@ function renderTooltipContents(tooltipText) {
|
|
|
321538
323261
|
}
|
|
321539
323262
|
function VegaPlot(props) {
|
|
321540
323263
|
const { spec: partialSpec, data: data2, getTooltipText, signalListeners, renderer = "svg", onNewView } = props;
|
|
321541
|
-
const { classes: tooltipClasses2 } = useStyles$
|
|
323264
|
+
const { classes: tooltipClasses2 } = useStyles$v();
|
|
321542
323265
|
const tooltipHandler = useMemo$1(() => {
|
|
321543
323266
|
if (typeof getTooltipText === "function") {
|
|
321544
323267
|
const tooltipConfig = {
|
|
@@ -324250,6 +325973,24 @@ class ObsSetsJsonLoader extends JsonLoader {
|
|
|
324250
325973
|
}, url, coordinationValues));
|
|
324251
325974
|
}
|
|
324252
325975
|
}
|
|
325976
|
+
class AnnotationStoryJsonLoader extends JsonLoader {
|
|
325977
|
+
constructor(dataSource, params2) {
|
|
325978
|
+
super(dataSource, params2);
|
|
325979
|
+
this.schema = annotationStoryObj;
|
|
325980
|
+
}
|
|
325981
|
+
async load() {
|
|
325982
|
+
if (this.cachedResult) {
|
|
325983
|
+
return this.cachedResult;
|
|
325984
|
+
}
|
|
325985
|
+
const payload = await super.load();
|
|
325986
|
+
const { data: annotationStory, url } = payload;
|
|
325987
|
+
const coordinationValues = {
|
|
325988
|
+
annotationStory
|
|
325989
|
+
};
|
|
325990
|
+
this.cachedResult = new LoaderResult({ annotationStory }, url, coordinationValues);
|
|
325991
|
+
return this.cachedResult;
|
|
325992
|
+
}
|
|
325993
|
+
}
|
|
324253
325994
|
class CellsJsonAsObsEmbeddingLoader extends JsonLoader {
|
|
324254
325995
|
constructor(dataSource, params2) {
|
|
324255
325996
|
super(dataSource, params2);
|
|
@@ -347039,7 +348780,8 @@ const baseViewTypes = [
|
|
|
347039
348780
|
makeViewType(ViewType$1.COMPARATIVE_HEADING, ComparativeHeadingSubscriber),
|
|
347040
348781
|
makeViewType(ViewType$1.SAMPLE_SET_PAIR_MANAGER, SampleSetPairManagerSubscriber),
|
|
347041
348782
|
makeViewType(ViewType$1.OBS_SET_COMPOSITION_BAR_PLOT, CellSetCompositionBarPlotSubscriber),
|
|
347042
|
-
makeViewType(ViewType$1.FEATURE_SET_ENRICHMENT_BAR_PLOT, FeatureSetEnrichmentBarPlotSubscriber)
|
|
348783
|
+
makeViewType(ViewType$1.FEATURE_SET_ENRICHMENT_BAR_PLOT, FeatureSetEnrichmentBarPlotSubscriber),
|
|
348784
|
+
makeViewType(ViewType$1.ANNOTATION_CONTROLLER, AnnotationControllerSubscriber)
|
|
347043
348785
|
];
|
|
347044
348786
|
const baseFileTypes = [
|
|
347045
348787
|
// All CSV file types
|
|
@@ -347056,6 +348798,7 @@ const baseFileTypes = [
|
|
|
347056
348798
|
// All JSON file types
|
|
347057
348799
|
makeFileType(FileType$1.OBS_SEGMENTATIONS_JSON, DataType$3.OBS_SEGMENTATIONS, ObsSegmentationsJsonLoader, JsonSource, z.null()),
|
|
347058
348800
|
makeFileType(FileType$1.OBS_SETS_JSON, DataType$3.OBS_SETS, ObsSetsJsonLoader, JsonSource, z.null()),
|
|
348801
|
+
makeFileType(FileType$1.ANNOTATION_STORY_JSON, DataType$3.ANNOTATION_STORY, AnnotationStoryJsonLoader, JsonSource, z.null()),
|
|
347059
348802
|
// All AnnData file types
|
|
347060
348803
|
...makeZarrFileTypes(FileType$1.OBS_SETS_ANNDATA_ZARR, DataType$3.OBS_SETS, ObsSetsAnndataLoader, AnnDataSource, obsSetsAnndataSchema),
|
|
347061
348804
|
...makeZarrFileTypes(FileType$1.OBS_EMBEDDING_ANNDATA_ZARR, DataType$3.OBS_EMBEDDING, ObsEmbeddingAnndataLoader, AnnDataSource, obsEmbeddingAnndataSchema),
|
|
@@ -347407,7 +349150,16 @@ const baseCoordinationTypes = [
|
|
|
347407
349150
|
new PluginCoordinationType(CoordinationType$1.FEATURE_POINT_SIGNIFICANCE_THRESHOLD, 0.01, z.number().nullable()),
|
|
347408
349151
|
new PluginCoordinationType(CoordinationType$1.FEATURE_LABEL_SIGNIFICANCE_THRESHOLD, 0.01, z.number().nullable()),
|
|
347409
349152
|
new PluginCoordinationType(CoordinationType$1.FEATURE_POINT_FOLD_CHANGE_THRESHOLD, 1, z.number().nullable()),
|
|
347410
|
-
new PluginCoordinationType(CoordinationType$1.FEATURE_LABEL_FOLD_CHANGE_THRESHOLD, 5, z.number().nullable())
|
|
349153
|
+
new PluginCoordinationType(CoordinationType$1.FEATURE_LABEL_FOLD_CHANGE_THRESHOLD, 5, z.number().nullable()),
|
|
349154
|
+
// Annotation frames
|
|
349155
|
+
new PluginCoordinationType(CoordinationType$1.ANNOTATION_STORY, null, annotationStoryObj.nullable()),
|
|
349156
|
+
new PluginCoordinationType(CoordinationType$1.ANNOTATION_SHAPES, null, annotationShapesArray.nullable()),
|
|
349157
|
+
new PluginCoordinationType(CoordinationType$1.ANNOTATION_FRAME_INDEX, null, z.number().nullable()),
|
|
349158
|
+
new PluginCoordinationType(CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE, true, z.boolean()),
|
|
349159
|
+
new PluginCoordinationType(CoordinationType$1.ANNOTATION_TRANSITION_DURATION, 0, z.number()),
|
|
349160
|
+
// TODO: make this non-zero by default?
|
|
349161
|
+
new PluginCoordinationType(CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM, true, z.boolean()),
|
|
349162
|
+
new PluginCoordinationType(CoordinationType$1.ANNOTATION_EDITABLE, false, z.boolean())
|
|
347411
349163
|
];
|
|
347412
349164
|
const baseAsyncFunctions = [
|
|
347413
349165
|
new PluginAsyncFunction(AsyncFunctionType.AUTOCOMPLETE_FEATURE, autocompleteFeature),
|
|
@@ -347515,6 +349267,11 @@ export {
|
|
|
347515
349267
|
PluginJointFileType as a5,
|
|
347516
349268
|
PluginAsyncFunction as a6,
|
|
347517
349269
|
z as a7,
|
|
349270
|
+
hasAnnotationControllerView as a8,
|
|
349271
|
+
addAnnotationControllerView as a9,
|
|
349272
|
+
isAnyAnnotationEditing as aa,
|
|
349273
|
+
enableAnnotationEditing as ab,
|
|
349274
|
+
disableAnnotationEditing as ac,
|
|
347518
349275
|
LercAddCompression as b,
|
|
347519
349276
|
commonjsGlobal$1 as c,
|
|
347520
349277
|
requireAssign as d,
|