@vitessce/scatterplot-gating 4.0.7 → 4.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{deflate-9OJa3Ewi.js → deflate-DUmHvVPz.js} +1 -1
- package/dist/{index-BUVBbXFQ.js → index-B-Adtek3.js} +1502 -97
- package/dist/index.js +1 -1
- package/dist/{jpeg-B9_avAIf.js → jpeg-DdAMSG2w.js} +1 -1
- package/dist/{lerc-BjrLoND6.js → lerc-D4PnY1mB.js} +1 -1
- package/dist/{lzw-DEJye0-W.js → lzw-BpQ8dLUH.js} +1 -1
- package/dist/{packbits-CvrWa3x_.js → packbits-Cb8CXJgl.js} +1 -1
- package/dist/{raw-BfH2zeya.js → raw-AvZwnBim.js} +1 -1
- package/dist/{webimage-CaSVfEZI.js → webimage-Di-764UM.js} +1 -1
- package/package.json +7 -7
|
@@ -2824,11 +2824,11 @@ function requireConcaveman() {
|
|
|
2824
2824
|
while (node2) {
|
|
2825
2825
|
for (var i2 = 0; i2 < node2.children.length; i2++) {
|
|
2826
2826
|
var child = node2.children[i2];
|
|
2827
|
-
var
|
|
2828
|
-
if (
|
|
2827
|
+
var dist2 = node2.leaf ? sqSegDist(child, b, c2) : sqSegBoxDist(b, c2, child);
|
|
2828
|
+
if (dist2 > maxDist) continue;
|
|
2829
2829
|
queue.push({
|
|
2830
2830
|
node: child,
|
|
2831
|
-
dist
|
|
2831
|
+
dist: dist2
|
|
2832
2832
|
});
|
|
2833
2833
|
}
|
|
2834
2834
|
while (queue.length && !queue.peek().node.children) {
|
|
@@ -6977,7 +6977,7 @@ const latestFileDefSchema = z.object({
|
|
|
6977
6977
|
options: fileOptionsSchema.optional(),
|
|
6978
6978
|
requestInit: requestInit.optional(),
|
|
6979
6979
|
// New: file def can have coordinationValues.
|
|
6980
|
-
coordinationValues: z.record(z.
|
|
6980
|
+
coordinationValues: z.record(z.any()).optional()
|
|
6981
6981
|
});
|
|
6982
6982
|
const datasetsSchema1_0_13 = z.array(z.object({
|
|
6983
6983
|
uid: z.string(),
|
|
@@ -7008,7 +7008,8 @@ const configSchema1_0_16 = configSchema1_0_13.extend({
|
|
|
7008
7008
|
h: z.number().int().optional(),
|
|
7009
7009
|
// Updates coordinationScopes and coordinationScopesBy
|
|
7010
7010
|
coordinationScopes: componentCoordinationScopes.optional(),
|
|
7011
|
-
coordinationScopesBy: componentCoordinationScopesBy.optional()
|
|
7011
|
+
coordinationScopesBy: componentCoordinationScopesBy.optional(),
|
|
7012
|
+
coordinationValues: z.record(z.any()).optional()
|
|
7012
7013
|
}))
|
|
7013
7014
|
});
|
|
7014
7015
|
const configSchema1_0_17 = configSchema1_0_16.extend({
|
|
@@ -9514,7 +9515,9 @@ const ViewType$1 = {
|
|
|
9514
9515
|
DUAL_SCATTERPLOT: "dualScatterplot",
|
|
9515
9516
|
TREEMAP: "treemap",
|
|
9516
9517
|
SAMPLE_SET_PAIR_MANAGER: "sampleSetPairManager",
|
|
9517
|
-
FEATURE_STATS_TABLE: "featureStatsTable"
|
|
9518
|
+
FEATURE_STATS_TABLE: "featureStatsTable",
|
|
9519
|
+
SINGLE_OBS_SET_SELECTOR: "singleObsSetSelector",
|
|
9520
|
+
ANNOTATION_CONTROLLER: "annotationController"
|
|
9518
9521
|
};
|
|
9519
9522
|
const DataType$2 = {
|
|
9520
9523
|
OBS_LABELS: "obsLabels",
|
|
@@ -9535,7 +9538,8 @@ const DataType$2 = {
|
|
|
9535
9538
|
COMPARISON_METADATA: "comparisonMetadata",
|
|
9536
9539
|
FEATURE_STATS: "featureStats",
|
|
9537
9540
|
FEATURE_SET_STATS: "featureSetStats",
|
|
9538
|
-
OBS_SET_STATS: "obsSetStats"
|
|
9541
|
+
OBS_SET_STATS: "obsSetStats",
|
|
9542
|
+
ANNOTATION_STORY: "annotationStory"
|
|
9539
9543
|
};
|
|
9540
9544
|
const FileType$1 = {
|
|
9541
9545
|
// Joint file types
|
|
@@ -9557,6 +9561,7 @@ const FileType$1 = {
|
|
|
9557
9561
|
OBS_SETS_CSV: "obsSets.csv",
|
|
9558
9562
|
OBS_SETS_JSON: "obsSets.json",
|
|
9559
9563
|
SAMPLE_SETS_CSV: "sampleSets.csv",
|
|
9564
|
+
ANNOTATION_STORY_JSON: "annotationStory.json",
|
|
9560
9565
|
// OME-Zarr
|
|
9561
9566
|
IMAGE_OME_ZARR: "image.ome-zarr",
|
|
9562
9567
|
OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
|
|
@@ -9841,7 +9846,15 @@ const CoordinationType$1 = {
|
|
|
9841
9846
|
FEATURE_POINT_FOLD_CHANGE_THRESHOLD: "featurePointFoldChangeThreshold",
|
|
9842
9847
|
FEATURE_LABEL_FOLD_CHANGE_THRESHOLD: "featureLabelFoldChangeThreshold",
|
|
9843
9848
|
// Treemap
|
|
9844
|
-
HIERARCHY_LEVELS: "hierarchyLevels"
|
|
9849
|
+
HIERARCHY_LEVELS: "hierarchyLevels",
|
|
9850
|
+
// Annotation frames
|
|
9851
|
+
ANNOTATION_STORY: "annotationStory",
|
|
9852
|
+
ANNOTATION_FRAME_INDEX: "annotationFrameIndex",
|
|
9853
|
+
ANNOTATION_SHAPES: "annotationShapes",
|
|
9854
|
+
ANNOTATION_OVERLAY_VISIBLE: "annotationOverlayVisible",
|
|
9855
|
+
ANNOTATION_TRANSITION_DURATION: "annotationTransitionDuration",
|
|
9856
|
+
ANNOTATION_SEMANTIC_ZOOM: "annotationSemanticZoom",
|
|
9857
|
+
ANNOTATION_EDITABLE: "annotationEditable"
|
|
9845
9858
|
};
|
|
9846
9859
|
const ViewHelpMapping = {
|
|
9847
9860
|
GATING: "The gating scatterplot displays expression data for two genes (along the X and Y axes). Users can select two genes, and the scatterplot is dynamically generated using observation-by-feature matrix data. Gating can then be performed by using the lasso or box select tools."
|
|
@@ -9860,6 +9873,7 @@ const ViewHelpMapping = {
|
|
|
9860
9873
|
[FileType$1.OBS_SEGMENTATIONS_JSON]: DataType$2.OBS_SEGMENTATIONS,
|
|
9861
9874
|
[FileType$1.OBS_SETS_CSV]: DataType$2.OBS_SETS,
|
|
9862
9875
|
[FileType$1.OBS_SETS_JSON]: DataType$2.OBS_SETS,
|
|
9876
|
+
[FileType$1.ANNOTATION_STORY_JSON]: DataType$2.ANNOTATION_STORY,
|
|
9863
9877
|
[FileType$1.IMAGE_OME_ZARR]: DataType$2.IMAGE,
|
|
9864
9878
|
[FileType$1.OBS_SEGMENTATIONS_OME_ZARR]: DataType$2.OBS_SEGMENTATIONS,
|
|
9865
9879
|
[FileType$1.OBS_FEATURE_MATRIX_ANNDATA_ZARR]: DataType$2.OBS_FEATURE_MATRIX,
|
|
@@ -9982,7 +9996,8 @@ const ViewHelpMapping = {
|
|
|
9982
9996
|
[DataType$2.OBS_SET_STATS]: [
|
|
9983
9997
|
CoordinationType$1.OBS_TYPE
|
|
9984
9998
|
// TODO: should sampleType, obsSetSelection, and/or sampleSetSelection be used here?
|
|
9985
|
-
]
|
|
9999
|
+
],
|
|
10000
|
+
[DataType$2.ANNOTATION_STORY]: []
|
|
9986
10001
|
});
|
|
9987
10002
|
({
|
|
9988
10003
|
// For AnnData:
|
|
@@ -10115,7 +10130,9 @@ const ViewHelpMapping = {
|
|
|
10115
10130
|
CoordinationType$1.SPATIAL_TARGET_Z,
|
|
10116
10131
|
CoordinationType$1.SPATIAL_AXIS_FIXED,
|
|
10117
10132
|
CoordinationType$1.SPATIAL_ORBIT_AXIS,
|
|
10118
|
-
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY
|
|
10133
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
10134
|
+
// Annotation shapes are specific to a view's coordinate system.
|
|
10135
|
+
CoordinationType$1.ANNOTATION_SHAPES
|
|
10119
10136
|
];
|
|
10120
10137
|
const COMPONENT_COORDINATION_TYPES = {
|
|
10121
10138
|
[ViewType$1.NEUROGLANCER]: [
|
|
@@ -10207,7 +10224,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10207
10224
|
CoordinationType$1.EMBEDDING_CONTOURS_FILLED,
|
|
10208
10225
|
CoordinationType$1.EMBEDDING_CONTOUR_PERCENTILES,
|
|
10209
10226
|
CoordinationType$1.CONTOUR_COLOR_ENCODING,
|
|
10210
|
-
CoordinationType$1.CONTOUR_COLOR
|
|
10227
|
+
CoordinationType$1.CONTOUR_COLOR,
|
|
10228
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10229
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10230
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10231
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10232
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10233
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10234
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10211
10235
|
],
|
|
10212
10236
|
[ViewType$1.DUAL_SCATTERPLOT]: [
|
|
10213
10237
|
CoordinationType$1.DATASET,
|
|
@@ -10323,7 +10347,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10323
10347
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
10324
10348
|
CoordinationType$1.MOLECULE_HIGHLIGHT,
|
|
10325
10349
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
10326
|
-
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
10350
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
|
|
10351
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10352
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10353
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10354
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10355
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10356
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10357
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10327
10358
|
],
|
|
10328
10359
|
[ViewType$1.SPATIAL_BETA]: [
|
|
10329
10360
|
CoordinationType$1.META_COORDINATION_SCOPES,
|
|
@@ -10401,7 +10432,27 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10401
10432
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
10402
10433
|
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
10403
10434
|
CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER,
|
|
10404
|
-
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
10435
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
|
|
10436
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10437
|
+
CoordinationType$1.ANNOTATION_SHAPES,
|
|
10438
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10439
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10440
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10441
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10442
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10443
|
+
],
|
|
10444
|
+
[ViewType$1.ANNOTATION_CONTROLLER]: [
|
|
10445
|
+
CoordinationType$1.DATASET,
|
|
10446
|
+
CoordinationType$1.ANNOTATION_STORY,
|
|
10447
|
+
CoordinationType$1.ANNOTATION_FRAME_INDEX,
|
|
10448
|
+
CoordinationType$1.ANNOTATION_OVERLAY_VISIBLE,
|
|
10449
|
+
CoordinationType$1.ANNOTATION_TRANSITION_DURATION,
|
|
10450
|
+
CoordinationType$1.ANNOTATION_EDITABLE,
|
|
10451
|
+
CoordinationType$1.ANNOTATION_SEMANTIC_ZOOM
|
|
10452
|
+
// Note: the annotation controller also needs to read the coordination state
|
|
10453
|
+
// of all other views/coordination types via the full config.
|
|
10454
|
+
// Note: we get/set the CoordinationType.ANNOTATION_SHAPES from the full config,
|
|
10455
|
+
// as this info is view-specific rather than global to the story.
|
|
10405
10456
|
],
|
|
10406
10457
|
[ViewType$1.HEATMAP]: [
|
|
10407
10458
|
CoordinationType$1.DATASET,
|
|
@@ -10711,6 +10762,11 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10711
10762
|
CoordinationType$1.FEATURE_POINT_FOLD_CHANGE_THRESHOLD,
|
|
10712
10763
|
CoordinationType$1.FEATURE_LABEL_FOLD_CHANGE_THRESHOLD
|
|
10713
10764
|
],
|
|
10765
|
+
[ViewType$1.SINGLE_OBS_SET_SELECTOR]: [
|
|
10766
|
+
CoordinationType$1.OBS_TYPE,
|
|
10767
|
+
CoordinationType$1.OBS_SET_COLOR,
|
|
10768
|
+
CoordinationType$1.OBS_SET_SELECTION
|
|
10769
|
+
],
|
|
10714
10770
|
[ViewType$1.OBS_SET_COMPOSITION_BAR_PLOT]: [
|
|
10715
10771
|
CoordinationType$1.DATASET,
|
|
10716
10772
|
CoordinationType$1.OBS_TYPE,
|
|
@@ -11414,6 +11470,124 @@ z.object({
|
|
|
11414
11470
|
radius: z.number(),
|
|
11415
11471
|
opacity: z.number()
|
|
11416
11472
|
});
|
|
11473
|
+
const shapeBaseObj = z.object({
|
|
11474
|
+
uid: z.string(),
|
|
11475
|
+
text: z.string().optional(),
|
|
11476
|
+
strokeColor: z.array(z.number()).length(3).optional(),
|
|
11477
|
+
strokeWidth: z.number().optional(),
|
|
11478
|
+
// SVG-style dash pattern, e.g. "10 5" or "10 20 30 10". "none" or omitted = solid.
|
|
11479
|
+
strokeDashArray: z.string().optional(),
|
|
11480
|
+
visible: z.boolean().optional()
|
|
11481
|
+
// TODO: define unit modes for x and y axes
|
|
11482
|
+
// ("pixels" vs "normalized" vs "physical" etc.)
|
|
11483
|
+
// TODO: a coordinate system identifier (e.g., "DeckGL" for now,
|
|
11484
|
+
// but a coordinate system from OME-NGFF/SpatialData eventually?)
|
|
11485
|
+
});
|
|
11486
|
+
const rectangleShapeObj = shapeBaseObj.extend({
|
|
11487
|
+
type: z.literal("rectangle"),
|
|
11488
|
+
// OME-XML field names verbatim (upper-left origin)
|
|
11489
|
+
x: z.number(),
|
|
11490
|
+
y: z.number(),
|
|
11491
|
+
width: z.number(),
|
|
11492
|
+
height: z.number(),
|
|
11493
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11494
|
+
fillOpacity: z.number().optional()
|
|
11495
|
+
});
|
|
11496
|
+
const lineShapeObj = shapeBaseObj.extend({
|
|
11497
|
+
type: z.literal("line"),
|
|
11498
|
+
// OME-XML field names verbatim
|
|
11499
|
+
x1: z.number(),
|
|
11500
|
+
y1: z.number(),
|
|
11501
|
+
x2: z.number(),
|
|
11502
|
+
y2: z.number(),
|
|
11503
|
+
markerStart: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11504
|
+
markerEnd: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11505
|
+
textPosition: z.enum(["start", "middle", "end"]).optional(),
|
|
11506
|
+
textBufferPx: z.number().optional()
|
|
11507
|
+
});
|
|
11508
|
+
const ellipseShapeObj = shapeBaseObj.extend({
|
|
11509
|
+
type: z.literal("ellipse"),
|
|
11510
|
+
// OME-XML field names verbatim (centre point + radii)
|
|
11511
|
+
x1: z.number(),
|
|
11512
|
+
y1: z.number(),
|
|
11513
|
+
radiusX: z.number(),
|
|
11514
|
+
radiusY: z.number(),
|
|
11515
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11516
|
+
fillOpacity: z.number().optional()
|
|
11517
|
+
});
|
|
11518
|
+
const polygonShapeObj = shapeBaseObj.extend({
|
|
11519
|
+
type: z.literal("polygon"),
|
|
11520
|
+
// OME-XML: array of [x, y] coordinate pairs, closed automatically
|
|
11521
|
+
points: z.array(z.tuple([z.number(), z.number()])),
|
|
11522
|
+
fillColor: z.array(z.number()).length(3).optional(),
|
|
11523
|
+
fillOpacity: z.number().optional()
|
|
11524
|
+
});
|
|
11525
|
+
const polylineShapeObj = shapeBaseObj.extend({
|
|
11526
|
+
type: z.literal("polyline"),
|
|
11527
|
+
// OME-XML: array of [x, y] coordinate pairs, open (not closed)
|
|
11528
|
+
points: z.array(z.tuple([z.number(), z.number()])),
|
|
11529
|
+
markerStart: z.enum(["Arrow", "Tick"]).nullable().optional(),
|
|
11530
|
+
markerEnd: z.enum(["Arrow", "Tick"]).nullable().optional()
|
|
11531
|
+
});
|
|
11532
|
+
const annotationShapeObj = z.discriminatedUnion("type", [
|
|
11533
|
+
rectangleShapeObj,
|
|
11534
|
+
lineShapeObj,
|
|
11535
|
+
ellipseShapeObj,
|
|
11536
|
+
polygonShapeObj,
|
|
11537
|
+
polylineShapeObj
|
|
11538
|
+
]);
|
|
11539
|
+
z.array(annotationShapeObj);
|
|
11540
|
+
const annotationFrameObj = z.object({
|
|
11541
|
+
uid: z.string(),
|
|
11542
|
+
title: z.string().optional(),
|
|
11543
|
+
description: z.string().optional(),
|
|
11544
|
+
descriptionType: z.enum(["text", "markdown"]).optional(),
|
|
11545
|
+
// A frame can define per-view: coordinationValues
|
|
11546
|
+
// (if the view's state should not be coordinated with other views)
|
|
11547
|
+
// or per-view coordinationScopes/coordinationScopesBy
|
|
11548
|
+
// (if at this frame, the view should be coordinated with other views).
|
|
11549
|
+
// We can also define a frame-level coordination space,
|
|
11550
|
+
// which will be merged with the global coordination space.
|
|
11551
|
+
// TODO: datasets
|
|
11552
|
+
// TODO: coordinationSpace
|
|
11553
|
+
layout: z.array(
|
|
11554
|
+
// Note: for now, we will infer view objects which have a uid
|
|
11555
|
+
// that is present in the global layout, and do NOT have x/y/w/h defined,
|
|
11556
|
+
// to mean that in this frame, the layout and set of views is unchanged
|
|
11557
|
+
// from the global layout.
|
|
11558
|
+
// This will allow each frame to omit the full list of views from the layout,
|
|
11559
|
+
// and only specify the views whose coordination state is changing in this frame.
|
|
11560
|
+
// If a frame includes a view with a uid that is not present
|
|
11561
|
+
// in the global layout, then that view will be added to the layout at this frame.
|
|
11562
|
+
// This frame should also define x/y/w/h for all views,
|
|
11563
|
+
// since it will otherwise be ambiguous how to layout the updated set of views
|
|
11564
|
+
// for this frame.
|
|
11565
|
+
z.object({
|
|
11566
|
+
// The view UID. If this view uid is not present in the global layout,
|
|
11567
|
+
// it will be added to the layout at this frame,
|
|
11568
|
+
// and will need to have its coordination values initialized to their defaults
|
|
11569
|
+
// for any that were not fully specified.
|
|
11570
|
+
uid: z.string(),
|
|
11571
|
+
coordinationValues: z.record(
|
|
11572
|
+
z.string(),
|
|
11573
|
+
// The coordination type name, e.g. "embeddingType"
|
|
11574
|
+
z.any()
|
|
11575
|
+
).optional()
|
|
11576
|
+
// TODO: support coordinationScopes/coordinationScopesBy for per-view coordination
|
|
11577
|
+
// at this frame.
|
|
11578
|
+
// TODO: view x/y/w/h once we support view layout changes per-frame.
|
|
11579
|
+
})
|
|
11580
|
+
).optional()
|
|
11581
|
+
});
|
|
11582
|
+
z.object({
|
|
11583
|
+
// TODO: schema version for the story schema?
|
|
11584
|
+
// Same as current Vitessce schema version?
|
|
11585
|
+
uid: z.string(),
|
|
11586
|
+
title: z.string().optional(),
|
|
11587
|
+
description: z.string().optional(),
|
|
11588
|
+
descriptionType: z.enum(["text", "markdown"]).optional(),
|
|
11589
|
+
frames: z.array(annotationFrameObj)
|
|
11590
|
+
});
|
|
11417
11591
|
const SETS_DATATYPE_OBS = "obs";
|
|
11418
11592
|
const HIERARCHICAL_SCHEMAS = {
|
|
11419
11593
|
latestVersion: "0.1.3"
|
|
@@ -24234,8 +24408,8 @@ class Vector extends MathArray {
|
|
|
24234
24408
|
distanceSquared(mathArray) {
|
|
24235
24409
|
let length2 = 0;
|
|
24236
24410
|
for (let i2 = 0; i2 < this.ELEMENTS; ++i2) {
|
|
24237
|
-
const
|
|
24238
|
-
length2 +=
|
|
24411
|
+
const dist2 = this[i2] - mathArray[i2];
|
|
24412
|
+
length2 += dist2 * dist2;
|
|
24239
24413
|
}
|
|
24240
24414
|
return checkNumber(length2);
|
|
24241
24415
|
}
|
|
@@ -24556,6 +24730,12 @@ function multiply$3(out, a2, b) {
|
|
|
24556
24730
|
out[2] = a2[2] * b[2];
|
|
24557
24731
|
return out;
|
|
24558
24732
|
}
|
|
24733
|
+
function distance$3(a2, b) {
|
|
24734
|
+
var x = b[0] - a2[0];
|
|
24735
|
+
var y = b[1] - a2[1];
|
|
24736
|
+
var z2 = b[2] - a2[2];
|
|
24737
|
+
return Math.hypot(x, y, z2);
|
|
24738
|
+
}
|
|
24559
24739
|
function squaredLength$2(a2) {
|
|
24560
24740
|
var x = a2[0];
|
|
24561
24741
|
var y = a2[1];
|
|
@@ -24679,6 +24859,7 @@ function angle$2(a2, b) {
|
|
|
24679
24859
|
}
|
|
24680
24860
|
var sub = subtract;
|
|
24681
24861
|
var mul = multiply$3;
|
|
24862
|
+
var dist = distance$3;
|
|
24682
24863
|
var len = length$5;
|
|
24683
24864
|
var sqrLen = squaredLength$2;
|
|
24684
24865
|
(function() {
|
|
@@ -39149,7 +39330,7 @@ function noop$4() {
|
|
|
39149
39330
|
const getCursor$1 = ({
|
|
39150
39331
|
isDragging
|
|
39151
39332
|
}) => isDragging ? "grabbing" : "grab";
|
|
39152
|
-
const defaultProps$
|
|
39333
|
+
const defaultProps$P = {
|
|
39153
39334
|
id: "",
|
|
39154
39335
|
width: "100%",
|
|
39155
39336
|
height: "100%",
|
|
@@ -39280,7 +39461,7 @@ class Deck {
|
|
|
39280
39461
|
this._lastPointerDownInfo = pickedInfo.result[0] || pickedInfo.emptyInfo;
|
|
39281
39462
|
});
|
|
39282
39463
|
this.props = {
|
|
39283
|
-
...defaultProps$
|
|
39464
|
+
...defaultProps$P,
|
|
39284
39465
|
...props
|
|
39285
39466
|
};
|
|
39286
39467
|
props = this.props;
|
|
@@ -39782,7 +39963,7 @@ class Deck {
|
|
|
39782
39963
|
metrics.gpuMemory = memoryStats.get("GPU Memory").count;
|
|
39783
39964
|
}
|
|
39784
39965
|
}
|
|
39785
|
-
_defineProperty(Deck, "defaultProps", defaultProps$
|
|
39966
|
+
_defineProperty(Deck, "defaultProps", defaultProps$P);
|
|
39786
39967
|
_defineProperty(Deck, "VERSION", deckGlobal.VERSION);
|
|
39787
39968
|
class ShaderAttribute {
|
|
39788
39969
|
constructor(dataColumn, opts) {
|
|
@@ -42537,7 +42718,7 @@ const areViewportsEqual = memoize$3(({
|
|
|
42537
42718
|
return oldViewport.equals(viewport);
|
|
42538
42719
|
});
|
|
42539
42720
|
let pickingColorCache = new Uint8ClampedArray(0);
|
|
42540
|
-
const defaultProps$
|
|
42721
|
+
const defaultProps$O = {
|
|
42541
42722
|
data: {
|
|
42542
42723
|
type: "data",
|
|
42543
42724
|
value: EMPTY_ARRAY$1,
|
|
@@ -43412,7 +43593,7 @@ class Layer extends Component {
|
|
|
43412
43593
|
this.setNeedsUpdate();
|
|
43413
43594
|
}
|
|
43414
43595
|
}
|
|
43415
|
-
_defineProperty(Layer, "defaultProps", defaultProps$
|
|
43596
|
+
_defineProperty(Layer, "defaultProps", defaultProps$O);
|
|
43416
43597
|
_defineProperty(Layer, "layerName", "Layer");
|
|
43417
43598
|
const TRACE_RENDER_LAYERS = "compositeLayer.renderLayers";
|
|
43418
43599
|
class CompositeLayer extends Layer {
|
|
@@ -44448,6 +44629,124 @@ const esm$5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
44448
44629
|
project32,
|
|
44449
44630
|
shadow
|
|
44450
44631
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
44632
|
+
const dashShaders = {
|
|
44633
|
+
inject: {
|
|
44634
|
+
"vs:#decl": "\nattribute vec2 instanceDashArrays;\nattribute float instanceDashOffsets;\nvarying vec2 vDashArray;\nvarying float vDashOffset;\n",
|
|
44635
|
+
"vs:#main-end": "\nvDashArray = instanceDashArrays;\nvDashOffset = instanceDashOffsets / width.x;\n",
|
|
44636
|
+
"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",
|
|
44637
|
+
"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"
|
|
44638
|
+
}
|
|
44639
|
+
};
|
|
44640
|
+
const offsetShaders = {
|
|
44641
|
+
inject: {
|
|
44642
|
+
"vs:#decl": "\nattribute float instanceOffsets;\n",
|
|
44643
|
+
"vs:DECKGL_FILTER_SIZE": "\n float offsetWidth = abs(instanceOffsets * 2.0) + 1.0;\n size *= offsetWidth;\n",
|
|
44644
|
+
"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",
|
|
44645
|
+
"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"
|
|
44646
|
+
}
|
|
44647
|
+
};
|
|
44648
|
+
const defaultProps$N = {
|
|
44649
|
+
getDashArray: {
|
|
44650
|
+
type: "accessor",
|
|
44651
|
+
value: [0, 0]
|
|
44652
|
+
},
|
|
44653
|
+
getOffset: {
|
|
44654
|
+
type: "accessor",
|
|
44655
|
+
value: 0
|
|
44656
|
+
},
|
|
44657
|
+
dashJustified: false,
|
|
44658
|
+
dashGapPickable: false
|
|
44659
|
+
};
|
|
44660
|
+
class PathStyleExtension extends LayerExtension {
|
|
44661
|
+
constructor({
|
|
44662
|
+
dash = false,
|
|
44663
|
+
offset: offset2 = false,
|
|
44664
|
+
highPrecisionDash = false
|
|
44665
|
+
} = {}) {
|
|
44666
|
+
super({
|
|
44667
|
+
dash: dash || highPrecisionDash,
|
|
44668
|
+
offset: offset2,
|
|
44669
|
+
highPrecisionDash
|
|
44670
|
+
});
|
|
44671
|
+
}
|
|
44672
|
+
isEnabled(layer) {
|
|
44673
|
+
return "pathTesselator" in layer.state;
|
|
44674
|
+
}
|
|
44675
|
+
getShaders(extension) {
|
|
44676
|
+
if (!extension.isEnabled(this)) {
|
|
44677
|
+
return null;
|
|
44678
|
+
}
|
|
44679
|
+
let result = {};
|
|
44680
|
+
if (extension.opts.dash) {
|
|
44681
|
+
result = mergeShaders(result, dashShaders);
|
|
44682
|
+
}
|
|
44683
|
+
if (extension.opts.offset) {
|
|
44684
|
+
result = mergeShaders(result, offsetShaders);
|
|
44685
|
+
}
|
|
44686
|
+
return result;
|
|
44687
|
+
}
|
|
44688
|
+
initializeState(context, extension) {
|
|
44689
|
+
const attributeManager = this.getAttributeManager();
|
|
44690
|
+
if (!attributeManager || !extension.isEnabled(this)) {
|
|
44691
|
+
return;
|
|
44692
|
+
}
|
|
44693
|
+
if (extension.opts.dash) {
|
|
44694
|
+
attributeManager.addInstanced({
|
|
44695
|
+
instanceDashArrays: {
|
|
44696
|
+
size: 2,
|
|
44697
|
+
accessor: "getDashArray"
|
|
44698
|
+
}
|
|
44699
|
+
});
|
|
44700
|
+
}
|
|
44701
|
+
if (extension.opts.highPrecisionDash) {
|
|
44702
|
+
attributeManager.addInstanced({
|
|
44703
|
+
instanceDashOffsets: {
|
|
44704
|
+
size: 1,
|
|
44705
|
+
accessor: "getPath",
|
|
44706
|
+
transform: extension.getDashOffsets.bind(this)
|
|
44707
|
+
}
|
|
44708
|
+
});
|
|
44709
|
+
}
|
|
44710
|
+
if (extension.opts.offset) {
|
|
44711
|
+
attributeManager.addInstanced({
|
|
44712
|
+
instanceOffsets: {
|
|
44713
|
+
size: 1,
|
|
44714
|
+
accessor: "getOffset"
|
|
44715
|
+
}
|
|
44716
|
+
});
|
|
44717
|
+
}
|
|
44718
|
+
}
|
|
44719
|
+
updateState(params, extension) {
|
|
44720
|
+
if (!extension.isEnabled(this)) {
|
|
44721
|
+
return;
|
|
44722
|
+
}
|
|
44723
|
+
const uniforms = {};
|
|
44724
|
+
if (extension.opts.dash) {
|
|
44725
|
+
uniforms.dashAlignMode = this.props.dashJustified ? 1 : 0;
|
|
44726
|
+
uniforms.dashGapPickable = Boolean(this.props.dashGapPickable);
|
|
44727
|
+
}
|
|
44728
|
+
this.state.model.setUniforms(uniforms);
|
|
44729
|
+
}
|
|
44730
|
+
getDashOffsets(path) {
|
|
44731
|
+
const result = [0];
|
|
44732
|
+
const positionSize = this.props.positionFormat === "XY" ? 2 : 3;
|
|
44733
|
+
const isNested2 = Array.isArray(path[0]);
|
|
44734
|
+
const geometrySize = isNested2 ? path.length : path.length / positionSize;
|
|
44735
|
+
let p;
|
|
44736
|
+
let prevP;
|
|
44737
|
+
for (let i2 = 0; i2 < geometrySize - 1; i2++) {
|
|
44738
|
+
p = isNested2 ? path[i2] : path.slice(i2 * positionSize, i2 * positionSize + positionSize);
|
|
44739
|
+
p = this.projectPosition(p);
|
|
44740
|
+
if (i2 > 0) {
|
|
44741
|
+
result[i2] = result[i2 - 1] + dist(prevP, p);
|
|
44742
|
+
}
|
|
44743
|
+
prevP = p;
|
|
44744
|
+
}
|
|
44745
|
+
return result;
|
|
44746
|
+
}
|
|
44747
|
+
}
|
|
44748
|
+
_defineProperty(PathStyleExtension, "defaultProps", defaultProps$N);
|
|
44749
|
+
_defineProperty(PathStyleExtension, "extensionName", "PathStyleExtension");
|
|
44451
44750
|
const defaultProps$M = {
|
|
44452
44751
|
clipBounds: [0, 0, 1, 1]
|
|
44453
44752
|
};
|
|
@@ -100535,8 +100834,8 @@ function requireJs$b() {
|
|
|
100535
100834
|
var DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi12 / 2 + Math.PI / 4));
|
|
100536
100835
|
var q = Math.abs(DeltaPsi) > 1e-11 ? DeltaPhi / DeltaPsi : Math.cos(phi12);
|
|
100537
100836
|
var delta = Math.sqrt(DeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda);
|
|
100538
|
-
var
|
|
100539
|
-
return
|
|
100837
|
+
var dist2 = delta * R;
|
|
100838
|
+
return dist2;
|
|
100540
100839
|
}
|
|
100541
100840
|
js$a.default = rhumbDistance;
|
|
100542
100841
|
return js$a;
|
|
@@ -100849,7 +101148,7 @@ function requireUtils$2() {
|
|
|
100849
101148
|
var x;
|
|
100850
101149
|
var y;
|
|
100851
101150
|
var segmentIdx;
|
|
100852
|
-
var
|
|
101151
|
+
var dist2;
|
|
100853
101152
|
if (coords.length > 1 && pointCoords.length) {
|
|
100854
101153
|
var lineCoordinates;
|
|
100855
101154
|
var pointCoordinate;
|
|
@@ -100866,17 +101165,17 @@ function requireUtils$2() {
|
|
|
100866
101165
|
if (lineCoordinates[n2][0] !== lineCoordinates[n2 - 1][0]) {
|
|
100867
101166
|
var slope = (lineCoordinates[n2][1] - lineCoordinates[n2 - 1][1]) / (lineCoordinates[n2][0] - lineCoordinates[n2 - 1][0]);
|
|
100868
101167
|
var inverseSlope = lineCoordinates[n2][1] - slope * lineCoordinates[n2][0];
|
|
100869
|
-
|
|
100870
|
-
} else
|
|
101168
|
+
dist2 = Math.abs(slope * pointCoordinate[0] + inverseSlope - pointCoordinate[1]) / Math.sqrt(slope * slope + 1);
|
|
101169
|
+
} else dist2 = Math.abs(pointCoordinate[0] - lineCoordinates[n2][0]);
|
|
100871
101170
|
var rl2 = Math.pow(lineCoordinates[n2][1] - lineCoordinates[n2 - 1][1], 2) + Math.pow(lineCoordinates[n2][0] - lineCoordinates[n2 - 1][0], 2);
|
|
100872
101171
|
var ln2 = Math.pow(lineCoordinates[n2][1] - pointCoordinate[1], 2) + Math.pow(lineCoordinates[n2][0] - pointCoordinate[0], 2);
|
|
100873
101172
|
var lnm12 = Math.pow(lineCoordinates[n2 - 1][1] - pointCoordinate[1], 2) + Math.pow(lineCoordinates[n2 - 1][0] - pointCoordinate[0], 2);
|
|
100874
|
-
var
|
|
100875
|
-
var calcrl2 = ln2 -
|
|
101173
|
+
var dist22 = Math.pow(dist2, 2);
|
|
101174
|
+
var calcrl2 = ln2 - dist22 + lnm12 - dist22;
|
|
100876
101175
|
if (calcrl2 > rl2) {
|
|
100877
|
-
|
|
101176
|
+
dist2 = Math.sqrt(Math.min(ln2, lnm12));
|
|
100878
101177
|
}
|
|
100879
|
-
if (minDist === null || minDist === void 0 || minDist >
|
|
101178
|
+
if (minDist === null || minDist === void 0 || minDist > dist2) {
|
|
100880
101179
|
if (calcrl2 > rl2) {
|
|
100881
101180
|
if (lnm12 < ln2) {
|
|
100882
101181
|
to = 0;
|
|
@@ -100886,10 +101185,10 @@ function requireUtils$2() {
|
|
|
100886
101185
|
to = 1;
|
|
100887
101186
|
}
|
|
100888
101187
|
} else {
|
|
100889
|
-
to = Math.sqrt(lnm12 -
|
|
100890
|
-
from2 = Math.sqrt(ln2 -
|
|
101188
|
+
to = Math.sqrt(lnm12 - dist22) / Math.sqrt(rl2);
|
|
101189
|
+
from2 = Math.sqrt(ln2 - dist22) / Math.sqrt(rl2);
|
|
100891
101190
|
}
|
|
100892
|
-
minDist =
|
|
101191
|
+
minDist = dist2;
|
|
100893
101192
|
segmentIdx = n2;
|
|
100894
101193
|
}
|
|
100895
101194
|
}
|
|
@@ -117220,22 +117519,22 @@ function addDecoder(cases, importFn) {
|
|
|
117220
117519
|
}
|
|
117221
117520
|
cases.forEach((c2) => registry$1.set(c2, importFn));
|
|
117222
117521
|
}
|
|
117223
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
117224
|
-
addDecoder(5, () => import("./lzw-
|
|
117522
|
+
addDecoder([void 0, 1], () => import("./raw-AvZwnBim.js").then((m2) => m2.default));
|
|
117523
|
+
addDecoder(5, () => import("./lzw-BpQ8dLUH.js").then((m2) => m2.default));
|
|
117225
117524
|
addDecoder(6, () => {
|
|
117226
117525
|
throw new Error("old style JPEG compression is not supported.");
|
|
117227
117526
|
});
|
|
117228
|
-
addDecoder(7, () => import("./jpeg-
|
|
117229
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
117230
|
-
addDecoder(32773, () => import("./packbits-
|
|
117527
|
+
addDecoder(7, () => import("./jpeg-DdAMSG2w.js").then((m2) => m2.default));
|
|
117528
|
+
addDecoder([8, 32946], () => import("./deflate-DUmHvVPz.js").then((m2) => m2.default));
|
|
117529
|
+
addDecoder(32773, () => import("./packbits-Cb8CXJgl.js").then((m2) => m2.default));
|
|
117231
117530
|
addDecoder(
|
|
117232
117531
|
34887,
|
|
117233
|
-
() => import("./lerc-
|
|
117532
|
+
() => import("./lerc-D4PnY1mB.js").then(async (m2) => {
|
|
117234
117533
|
await m2.zstd.init();
|
|
117235
117534
|
return m2;
|
|
117236
117535
|
}).then((m2) => m2.default)
|
|
117237
117536
|
);
|
|
117238
|
-
addDecoder(50001, () => import("./webimage-
|
|
117537
|
+
addDecoder(50001, () => import("./webimage-Di-764UM.js").then((m2) => m2.default));
|
|
117239
117538
|
function decodeRowAcc(row, stride) {
|
|
117240
117539
|
let length2 = row.length - stride;
|
|
117241
117540
|
let offset2 = 0;
|
|
@@ -117650,8 +117949,8 @@ function TreeDesc(dyn_tree, stat_desc) {
|
|
|
117650
117949
|
this.max_code = 0;
|
|
117651
117950
|
this.stat_desc = stat_desc;
|
|
117652
117951
|
}
|
|
117653
|
-
const d_code = (
|
|
117654
|
-
return
|
|
117952
|
+
const d_code = (dist2) => {
|
|
117953
|
+
return dist2 < 256 ? _dist_code[dist2] : _dist_code[256 + (dist2 >>> 7)];
|
|
117655
117954
|
};
|
|
117656
117955
|
const put_short = (s2, w2) => {
|
|
117657
117956
|
s2.pending_buf[s2.pending++] = w2 & 255;
|
|
@@ -117785,7 +118084,7 @@ const tr_static_init = () => {
|
|
|
117785
118084
|
let bits;
|
|
117786
118085
|
let length2;
|
|
117787
118086
|
let code;
|
|
117788
|
-
let
|
|
118087
|
+
let dist2;
|
|
117789
118088
|
const bl_count = new Array(MAX_BITS + 1);
|
|
117790
118089
|
length2 = 0;
|
|
117791
118090
|
for (code = 0; code < LENGTH_CODES - 1; code++) {
|
|
@@ -117795,18 +118094,18 @@ const tr_static_init = () => {
|
|
|
117795
118094
|
}
|
|
117796
118095
|
}
|
|
117797
118096
|
_length_code[length2 - 1] = code;
|
|
117798
|
-
|
|
118097
|
+
dist2 = 0;
|
|
117799
118098
|
for (code = 0; code < 16; code++) {
|
|
117800
|
-
base_dist[code] =
|
|
118099
|
+
base_dist[code] = dist2;
|
|
117801
118100
|
for (n2 = 0; n2 < 1 << extra_dbits[code]; n2++) {
|
|
117802
|
-
_dist_code[
|
|
118101
|
+
_dist_code[dist2++] = code;
|
|
117803
118102
|
}
|
|
117804
118103
|
}
|
|
117805
|
-
|
|
118104
|
+
dist2 >>= 7;
|
|
117806
118105
|
for (; code < D_CODES; code++) {
|
|
117807
|
-
base_dist[code] =
|
|
118106
|
+
base_dist[code] = dist2 << 7;
|
|
117808
118107
|
for (n2 = 0; n2 < 1 << extra_dbits[code] - 7; n2++) {
|
|
117809
|
-
_dist_code[256 +
|
|
118108
|
+
_dist_code[256 + dist2++] = code;
|
|
117810
118109
|
}
|
|
117811
118110
|
}
|
|
117812
118111
|
for (bits = 0; bits <= MAX_BITS; bits++) {
|
|
@@ -117897,17 +118196,17 @@ const pqdownheap = (s2, tree, k) => {
|
|
|
117897
118196
|
s2.heap[k] = v;
|
|
117898
118197
|
};
|
|
117899
118198
|
const compress_block = (s2, ltree, dtree) => {
|
|
117900
|
-
let
|
|
118199
|
+
let dist2;
|
|
117901
118200
|
let lc;
|
|
117902
118201
|
let lx = 0;
|
|
117903
118202
|
let code;
|
|
117904
118203
|
let extra;
|
|
117905
118204
|
if (s2.last_lit !== 0) {
|
|
117906
118205
|
do {
|
|
117907
|
-
|
|
118206
|
+
dist2 = s2.pending_buf[s2.d_buf + lx * 2] << 8 | s2.pending_buf[s2.d_buf + lx * 2 + 1];
|
|
117908
118207
|
lc = s2.pending_buf[s2.l_buf + lx];
|
|
117909
118208
|
lx++;
|
|
117910
|
-
if (
|
|
118209
|
+
if (dist2 === 0) {
|
|
117911
118210
|
send_code(s2, lc, ltree);
|
|
117912
118211
|
} else {
|
|
117913
118212
|
code = _length_code[lc];
|
|
@@ -117917,13 +118216,13 @@ const compress_block = (s2, ltree, dtree) => {
|
|
|
117917
118216
|
lc -= base_length[code];
|
|
117918
118217
|
send_bits(s2, lc, extra);
|
|
117919
118218
|
}
|
|
117920
|
-
|
|
117921
|
-
code = d_code(
|
|
118219
|
+
dist2--;
|
|
118220
|
+
code = d_code(dist2);
|
|
117922
118221
|
send_code(s2, code, dtree);
|
|
117923
118222
|
extra = extra_dbits[code];
|
|
117924
118223
|
if (extra !== 0) {
|
|
117925
|
-
|
|
117926
|
-
send_bits(s2,
|
|
118224
|
+
dist2 -= base_dist[code];
|
|
118225
|
+
send_bits(s2, dist2, extra);
|
|
117927
118226
|
}
|
|
117928
118227
|
}
|
|
117929
118228
|
} while (lx < s2.last_lit);
|
|
@@ -118194,18 +118493,18 @@ const _tr_flush_block = (s2, buf, stored_len, last) => {
|
|
|
118194
118493
|
bi_windup(s2);
|
|
118195
118494
|
}
|
|
118196
118495
|
};
|
|
118197
|
-
const _tr_tally = (s2,
|
|
118198
|
-
s2.pending_buf[s2.d_buf + s2.last_lit * 2] =
|
|
118199
|
-
s2.pending_buf[s2.d_buf + s2.last_lit * 2 + 1] =
|
|
118496
|
+
const _tr_tally = (s2, dist2, lc) => {
|
|
118497
|
+
s2.pending_buf[s2.d_buf + s2.last_lit * 2] = dist2 >>> 8 & 255;
|
|
118498
|
+
s2.pending_buf[s2.d_buf + s2.last_lit * 2 + 1] = dist2 & 255;
|
|
118200
118499
|
s2.pending_buf[s2.l_buf + s2.last_lit] = lc & 255;
|
|
118201
118500
|
s2.last_lit++;
|
|
118202
|
-
if (
|
|
118501
|
+
if (dist2 === 0) {
|
|
118203
118502
|
s2.dyn_ltree[lc * 2]++;
|
|
118204
118503
|
} else {
|
|
118205
118504
|
s2.matches++;
|
|
118206
|
-
|
|
118505
|
+
dist2--;
|
|
118207
118506
|
s2.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]++;
|
|
118208
|
-
s2.dyn_dtree[d_code(
|
|
118507
|
+
s2.dyn_dtree[d_code(dist2) * 2]++;
|
|
118209
118508
|
}
|
|
118210
118509
|
return s2.last_lit === s2.lit_bufsize - 1;
|
|
118211
118510
|
};
|
|
@@ -119710,7 +120009,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119710
120009
|
let here;
|
|
119711
120010
|
let op;
|
|
119712
120011
|
let len2;
|
|
119713
|
-
let
|
|
120012
|
+
let dist2;
|
|
119714
120013
|
let from2;
|
|
119715
120014
|
let from_source;
|
|
119716
120015
|
let input, output;
|
|
@@ -119776,7 +120075,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119776
120075
|
bits -= op;
|
|
119777
120076
|
op = here >>> 16 & 255;
|
|
119778
120077
|
if (op & 16) {
|
|
119779
|
-
|
|
120078
|
+
dist2 = here & 65535;
|
|
119780
120079
|
op &= 15;
|
|
119781
120080
|
if (bits < op) {
|
|
119782
120081
|
hold += input[_in++] << bits;
|
|
@@ -119786,8 +120085,8 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119786
120085
|
bits += 8;
|
|
119787
120086
|
}
|
|
119788
120087
|
}
|
|
119789
|
-
|
|
119790
|
-
if (
|
|
120088
|
+
dist2 += hold & (1 << op) - 1;
|
|
120089
|
+
if (dist2 > dmax) {
|
|
119791
120090
|
strm.msg = "invalid distance too far back";
|
|
119792
120091
|
state.mode = BAD;
|
|
119793
120092
|
break top;
|
|
@@ -119795,8 +120094,8 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119795
120094
|
hold >>>= op;
|
|
119796
120095
|
bits -= op;
|
|
119797
120096
|
op = _out - beg;
|
|
119798
|
-
if (
|
|
119799
|
-
op =
|
|
120097
|
+
if (dist2 > op) {
|
|
120098
|
+
op = dist2 - op;
|
|
119800
120099
|
if (op > whave) {
|
|
119801
120100
|
if (state.sane) {
|
|
119802
120101
|
strm.msg = "invalid distance too far back";
|
|
@@ -119813,7 +120112,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119813
120112
|
do {
|
|
119814
120113
|
output[_out++] = s_window[from2++];
|
|
119815
120114
|
} while (--op);
|
|
119816
|
-
from2 = _out -
|
|
120115
|
+
from2 = _out - dist2;
|
|
119817
120116
|
from_source = output;
|
|
119818
120117
|
}
|
|
119819
120118
|
} else if (wnext < op) {
|
|
@@ -119831,7 +120130,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119831
120130
|
do {
|
|
119832
120131
|
output[_out++] = s_window[from2++];
|
|
119833
120132
|
} while (--op);
|
|
119834
|
-
from2 = _out -
|
|
120133
|
+
from2 = _out - dist2;
|
|
119835
120134
|
from_source = output;
|
|
119836
120135
|
}
|
|
119837
120136
|
}
|
|
@@ -119842,7 +120141,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119842
120141
|
do {
|
|
119843
120142
|
output[_out++] = s_window[from2++];
|
|
119844
120143
|
} while (--op);
|
|
119845
|
-
from2 = _out -
|
|
120144
|
+
from2 = _out - dist2;
|
|
119846
120145
|
from_source = output;
|
|
119847
120146
|
}
|
|
119848
120147
|
}
|
|
@@ -119859,7 +120158,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119859
120158
|
}
|
|
119860
120159
|
}
|
|
119861
120160
|
} else {
|
|
119862
|
-
from2 = _out -
|
|
120161
|
+
from2 = _out - dist2;
|
|
119863
120162
|
do {
|
|
119864
120163
|
output[_out++] = output[from2++];
|
|
119865
120164
|
output[_out++] = output[from2++];
|
|
@@ -120417,7 +120716,7 @@ const fixedtables = (state) => {
|
|
|
120417
120716
|
state.distbits = 5;
|
|
120418
120717
|
};
|
|
120419
120718
|
const updatewindow = (strm, src, end, copy2) => {
|
|
120420
|
-
let
|
|
120719
|
+
let dist2;
|
|
120421
120720
|
const state = strm.state;
|
|
120422
120721
|
if (state.window === null) {
|
|
120423
120722
|
state.wsize = 1 << state.wbits;
|
|
@@ -120430,23 +120729,23 @@ const updatewindow = (strm, src, end, copy2) => {
|
|
|
120430
120729
|
state.wnext = 0;
|
|
120431
120730
|
state.whave = state.wsize;
|
|
120432
120731
|
} else {
|
|
120433
|
-
|
|
120434
|
-
if (
|
|
120435
|
-
|
|
120732
|
+
dist2 = state.wsize - state.wnext;
|
|
120733
|
+
if (dist2 > copy2) {
|
|
120734
|
+
dist2 = copy2;
|
|
120436
120735
|
}
|
|
120437
|
-
state.window.set(src.subarray(end - copy2, end - copy2 +
|
|
120438
|
-
copy2 -=
|
|
120736
|
+
state.window.set(src.subarray(end - copy2, end - copy2 + dist2), state.wnext);
|
|
120737
|
+
copy2 -= dist2;
|
|
120439
120738
|
if (copy2) {
|
|
120440
120739
|
state.window.set(src.subarray(end - copy2, end), 0);
|
|
120441
120740
|
state.wnext = copy2;
|
|
120442
120741
|
state.whave = state.wsize;
|
|
120443
120742
|
} else {
|
|
120444
|
-
state.wnext +=
|
|
120743
|
+
state.wnext += dist2;
|
|
120445
120744
|
if (state.wnext === state.wsize) {
|
|
120446
120745
|
state.wnext = 0;
|
|
120447
120746
|
}
|
|
120448
120747
|
if (state.whave < state.wsize) {
|
|
120449
|
-
state.whave +=
|
|
120748
|
+
state.whave += dist2;
|
|
120450
120749
|
}
|
|
120451
120750
|
}
|
|
120452
120751
|
}
|
|
@@ -124325,14 +124624,14 @@ vec4 colormap(float intensity) {
|
|
|
124325
124624
|
}
|
|
124326
124625
|
};
|
|
124327
124626
|
}
|
|
124328
|
-
const defaultProps$4$
|
|
124627
|
+
const defaultProps$4$2 = {
|
|
124329
124628
|
colormap: { type: "string", value: "viridis", compare: true },
|
|
124330
124629
|
opacity: { type: "number", value: 1, compare: true },
|
|
124331
124630
|
useTransparentColor: { type: "boolean", value: false, compare: true }
|
|
124332
124631
|
};
|
|
124333
124632
|
const AdditiveColormapExtension = class extends LayerExtension {
|
|
124334
124633
|
getShaders() {
|
|
124335
|
-
const name2 = this?.props?.colormap || defaultProps$4$
|
|
124634
|
+
const name2 = this?.props?.colormap || defaultProps$4$2.colormap.value;
|
|
124336
124635
|
const apply_cmap = cmaps[name2];
|
|
124337
124636
|
if (!apply_cmap) {
|
|
124338
124637
|
throw Error(`No colormap named ${name2} found in registry`);
|
|
@@ -124351,8 +124650,8 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
124351
124650
|
}
|
|
124352
124651
|
draw() {
|
|
124353
124652
|
const {
|
|
124354
|
-
useTransparentColor = defaultProps$4$
|
|
124355
|
-
opacity = defaultProps$4$
|
|
124653
|
+
useTransparentColor = defaultProps$4$2.useTransparentColor.value,
|
|
124654
|
+
opacity = defaultProps$4$2.opacity.value
|
|
124356
124655
|
} = this.props;
|
|
124357
124656
|
const uniforms = {
|
|
124358
124657
|
opacity,
|
|
@@ -124362,7 +124661,7 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
124362
124661
|
}
|
|
124363
124662
|
};
|
|
124364
124663
|
AdditiveColormapExtension.extensionName = "AdditiveColormapExtension";
|
|
124365
|
-
AdditiveColormapExtension.defaultProps = defaultProps$4$
|
|
124664
|
+
AdditiveColormapExtension.defaultProps = defaultProps$4$2;
|
|
124366
124665
|
const fs$1$2 = `uniform vec3 transparentColor;
|
|
124367
124666
|
uniform bool useTransparentColor;
|
|
124368
124667
|
uniform float opacity;
|
|
@@ -125655,7 +125954,7 @@ const ImageLayer = class extends CompositeLayer {
|
|
|
125655
125954
|
};
|
|
125656
125955
|
ImageLayer.layerName = "ImageLayer";
|
|
125657
125956
|
ImageLayer.defaultProps = defaultProps$5;
|
|
125658
|
-
const defaultProps$4 = {
|
|
125957
|
+
const defaultProps$4$1 = {
|
|
125659
125958
|
pickable: { type: "boolean", value: true, compare: true },
|
|
125660
125959
|
onHover: { type: "function", value: null, compare: false },
|
|
125661
125960
|
contrastLimits: { type: "array", value: [], compare: true },
|
|
@@ -125767,7 +126066,7 @@ const MultiscaleImageLayer = class extends CompositeLayer {
|
|
|
125767
126066
|
}
|
|
125768
126067
|
};
|
|
125769
126068
|
MultiscaleImageLayer.layerName = "MultiscaleImageLayer";
|
|
125770
|
-
MultiscaleImageLayer.defaultProps = defaultProps$4;
|
|
126069
|
+
MultiscaleImageLayer.defaultProps = defaultProps$4$1;
|
|
125771
126070
|
const defaultProps$3$1 = {
|
|
125772
126071
|
pickable: { type: "boolean", value: true, compare: true },
|
|
125773
126072
|
loader: {
|
|
@@ -126843,7 +127142,7 @@ function padWithDefault$1(arr, defaultValue2, padWidth) {
|
|
|
126843
127142
|
}
|
|
126844
127143
|
return newArr;
|
|
126845
127144
|
}
|
|
126846
|
-
const defaultProps$
|
|
127145
|
+
const defaultProps$4 = {
|
|
126847
127146
|
hoveredCell: { type: "number", value: null, compare: true },
|
|
126848
127147
|
// We do not want to deep-compare cellColorData,
|
|
126849
127148
|
// as it is potentially a TypedArray with millions of elements.
|
|
@@ -126960,7 +127259,7 @@ let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
|
|
|
126960
127259
|
}
|
|
126961
127260
|
};
|
|
126962
127261
|
BitmaskLayer$1.layerName = "BitmaskLayer";
|
|
126963
|
-
BitmaskLayer$1.defaultProps = defaultProps$
|
|
127262
|
+
BitmaskLayer$1.defaultProps = defaultProps$4;
|
|
126964
127263
|
const vs = `
|
|
126965
127264
|
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
126966
127265
|
|
|
@@ -127302,7 +127601,7 @@ function isEqualShallow(prevArr, nextArr) {
|
|
|
127302
127601
|
}
|
|
127303
127602
|
return prevArr === nextArr;
|
|
127304
127603
|
}
|
|
127305
|
-
const defaultProps$
|
|
127604
|
+
const defaultProps$3 = {
|
|
127306
127605
|
channelStrokeWidths: { type: "array", value: null, compare: true },
|
|
127307
127606
|
channelsFilled: { type: "array", value: null, compare: true },
|
|
127308
127607
|
channelOpacities: { type: "array", value: null, compare: true },
|
|
@@ -127566,7 +127865,7 @@ class BitmaskLayer2 extends XRLayer {
|
|
|
127566
127865
|
}
|
|
127567
127866
|
}
|
|
127568
127867
|
BitmaskLayer2.layerName = "BitmaskLayer";
|
|
127569
|
-
BitmaskLayer2.defaultProps = defaultProps$
|
|
127868
|
+
BitmaskLayer2.defaultProps = defaultProps$3;
|
|
127570
127869
|
var isNumeric$1 = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, mathceil = Math.ceil, mathfloor = Math.floor, bignumberError = "[BigNumber Error] ", tooManyDigits = bignumberError + "Number primitive has more than 15 significant digits: ", BASE = 1e14, LOG_BASE = 14, MAX_SAFE_INTEGER = 9007199254740991, POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], SQRT_BASE = 1e7, MAX = 1e9;
|
|
127571
127870
|
function clone(configObject) {
|
|
127572
127871
|
var div, convertBase, parseNumeric, P = BigNumber2.prototype = { constructor: BigNumber2, toString: null, valueOf: null }, ONE = new BigNumber2(1), DECIMAL_PLACES = 20, ROUNDING_MODE = 4, TO_EXP_NEG = -7, TO_EXP_POS = 21, MIN_EXP = -1e7, MAX_EXP = 1e7, CRYPTO = false, MODULO_MODE = 1, POW_PRECISION = 0, FORMAT = {
|
|
@@ -130509,7 +130808,7 @@ function ringArea(coords) {
|
|
|
130509
130808
|
return total * FACTOR;
|
|
130510
130809
|
}
|
|
130511
130810
|
const DEFAULT_THRESHOLD = 1;
|
|
130512
|
-
const defaultProps$
|
|
130811
|
+
const defaultProps$2 = {
|
|
130513
130812
|
// for text
|
|
130514
130813
|
obsSetPath: { type: "object" },
|
|
130515
130814
|
sampleSetPath: { type: "object" },
|
|
@@ -130604,9 +130903,9 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
130604
130903
|
const circlePoint = point(circleCoord);
|
|
130605
130904
|
polygonVertices.forEach((polyCoord) => {
|
|
130606
130905
|
const polyPoint = point(polyCoord);
|
|
130607
|
-
const
|
|
130608
|
-
if (
|
|
130609
|
-
minDist =
|
|
130906
|
+
const dist2 = distance$1(circlePoint, polyPoint);
|
|
130907
|
+
if (dist2 < minDist) {
|
|
130908
|
+
minDist = dist2;
|
|
130610
130909
|
minCirclePoint = circleCoord;
|
|
130611
130910
|
minCirclePointI = circlePointI;
|
|
130612
130911
|
minPolygonPoint = polyCoord;
|
|
@@ -130683,7 +130982,1077 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
130683
130982
|
}
|
|
130684
130983
|
}
|
|
130685
130984
|
ContourLayerWithText.layerName = "ContourLayerWithText";
|
|
130686
|
-
ContourLayerWithText.defaultProps = defaultProps$
|
|
130985
|
+
ContourLayerWithText.defaultProps = defaultProps$2;
|
|
130986
|
+
const ARROW_SCREEN_PX = 14;
|
|
130987
|
+
const LABEL_FONT_FAMILY$1 = '"Roboto", "Helvetica", "Arial", sans-serif';
|
|
130988
|
+
const LABEL_FONT_WEIGHT = "bold";
|
|
130989
|
+
const LABEL_FONT_SIZE = 14;
|
|
130990
|
+
const RATIO_CLUSTER = 0.1;
|
|
130991
|
+
const RATIO_DOT = 0.3;
|
|
130992
|
+
const RATIO_GEO_FADE = 0.55;
|
|
130993
|
+
const RATIO_TIPS = 0.7;
|
|
130994
|
+
const RATIO_LABEL = 0.55;
|
|
130995
|
+
const RATIO_LABEL_FULL = 0.75;
|
|
130996
|
+
function textBgColor(strokeColor) {
|
|
130997
|
+
const [r2, g2, b] = strokeColor;
|
|
130998
|
+
const lum = (0.299 * r2 + 0.587 * g2 + 0.114 * b) / 255;
|
|
130999
|
+
return lum > 0.45 ? [20, 20, 20, 210] : [245, 245, 245, 210];
|
|
131000
|
+
}
|
|
131001
|
+
function parseDashArray(strokeDashArray) {
|
|
131002
|
+
if (!strokeDashArray || strokeDashArray === "none")
|
|
131003
|
+
return null;
|
|
131004
|
+
const nums = strokeDashArray.trim().split(/\s+/).map(Number).filter((n2) => !Number.isNaN(n2) && n2 >= 0);
|
|
131005
|
+
return nums.length >= 2 ? [nums[0], nums[1]] : null;
|
|
131006
|
+
}
|
|
131007
|
+
function computeEllipsePolygon(cx, cy, rx, ry, numSegments = 64) {
|
|
131008
|
+
const pts = [];
|
|
131009
|
+
for (let i2 = 0; i2 < numSegments; i2++) {
|
|
131010
|
+
const angle2 = 2 * Math.PI * i2 / numSegments;
|
|
131011
|
+
pts.push([cx + rx * Math.cos(angle2), cy + ry * Math.sin(angle2)]);
|
|
131012
|
+
}
|
|
131013
|
+
return pts;
|
|
131014
|
+
}
|
|
131015
|
+
function createPreviewLayer(inProgress, hoverCoord, strokeColor = [255, 255, 0]) {
|
|
131016
|
+
if (!inProgress || inProgress.vertices.length === 0)
|
|
131017
|
+
return null;
|
|
131018
|
+
const { type, vertices } = inProgress;
|
|
131019
|
+
const base = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN };
|
|
131020
|
+
const previewColor = [...strokeColor, 160];
|
|
131021
|
+
const cursor2 = hoverCoord ?? vertices[vertices.length - 1];
|
|
131022
|
+
if (type === "rectangle" && vertices.length === 1) {
|
|
131023
|
+
const [ax, ay] = vertices[0];
|
|
131024
|
+
const [bx, by] = cursor2;
|
|
131025
|
+
const path = [[ax, ay], [bx, ay], [bx, by], [ax, by], [ax, ay]];
|
|
131026
|
+
return new PathLayer({
|
|
131027
|
+
...base,
|
|
131028
|
+
id: "annotation-preview-rectangle",
|
|
131029
|
+
data: [{ path }],
|
|
131030
|
+
getPath: (d) => d.path,
|
|
131031
|
+
getColor: previewColor,
|
|
131032
|
+
getWidth: 1,
|
|
131033
|
+
widthUnits: "pixels",
|
|
131034
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131035
|
+
getDashArray: [8, 4]
|
|
131036
|
+
});
|
|
131037
|
+
}
|
|
131038
|
+
if (type === "line" && vertices.length === 1) {
|
|
131039
|
+
const path = [vertices[0], cursor2];
|
|
131040
|
+
return new PathLayer({
|
|
131041
|
+
...base,
|
|
131042
|
+
id: "annotation-preview-line",
|
|
131043
|
+
data: [{ path }],
|
|
131044
|
+
getPath: (d) => d.path,
|
|
131045
|
+
getColor: previewColor,
|
|
131046
|
+
getWidth: 1,
|
|
131047
|
+
widthUnits: "pixels",
|
|
131048
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131049
|
+
getDashArray: [8, 4]
|
|
131050
|
+
});
|
|
131051
|
+
}
|
|
131052
|
+
if (type === "ellipse" && vertices.length === 1) {
|
|
131053
|
+
const [cx, cy] = vertices[0];
|
|
131054
|
+
const [ex, ey] = cursor2;
|
|
131055
|
+
const rx = Math.abs(ex - cx);
|
|
131056
|
+
const ry = Math.abs(ey - cy);
|
|
131057
|
+
if (rx < 1 && ry < 1)
|
|
131058
|
+
return null;
|
|
131059
|
+
const pts = computeEllipsePolygon(cx, cy, Math.max(rx, 1), Math.max(ry, 1));
|
|
131060
|
+
const path = [...pts, pts[0]];
|
|
131061
|
+
return new PathLayer({
|
|
131062
|
+
...base,
|
|
131063
|
+
id: "annotation-preview-ellipse",
|
|
131064
|
+
data: [{ path }],
|
|
131065
|
+
getPath: (d) => d.path,
|
|
131066
|
+
getColor: previewColor,
|
|
131067
|
+
getWidth: 1,
|
|
131068
|
+
widthUnits: "pixels",
|
|
131069
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131070
|
+
getDashArray: [8, 4]
|
|
131071
|
+
});
|
|
131072
|
+
}
|
|
131073
|
+
if ((type === "polygon" || type === "polyline") && vertices.length >= 1) {
|
|
131074
|
+
const path = [...vertices, cursor2];
|
|
131075
|
+
if (type === "polygon" && vertices.length >= 2)
|
|
131076
|
+
path.push(vertices[0]);
|
|
131077
|
+
return new PathLayer({
|
|
131078
|
+
...base,
|
|
131079
|
+
id: `annotation-preview-${type}`,
|
|
131080
|
+
data: [{ path }],
|
|
131081
|
+
getPath: (d) => d.path,
|
|
131082
|
+
getColor: previewColor,
|
|
131083
|
+
getWidth: 1,
|
|
131084
|
+
widthUnits: "pixels",
|
|
131085
|
+
jointRounded: true,
|
|
131086
|
+
capRounded: true,
|
|
131087
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131088
|
+
getDashArray: [8, 4]
|
|
131089
|
+
});
|
|
131090
|
+
}
|
|
131091
|
+
return null;
|
|
131092
|
+
}
|
|
131093
|
+
function computeTickCap(tipX, tipY, dirX, dirY, dataSize) {
|
|
131094
|
+
const len2 = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
131095
|
+
if (len2 === 0)
|
|
131096
|
+
return null;
|
|
131097
|
+
const ux = dirX / len2;
|
|
131098
|
+
const uy = dirY / len2;
|
|
131099
|
+
const px = -uy;
|
|
131100
|
+
const py = ux;
|
|
131101
|
+
const half = dataSize * 0.55;
|
|
131102
|
+
return [
|
|
131103
|
+
[tipX + px * half, tipY + py * half],
|
|
131104
|
+
[tipX - px * half, tipY - py * half]
|
|
131105
|
+
];
|
|
131106
|
+
}
|
|
131107
|
+
function computeArrowhead(tipX, tipY, dirX, dirY, dataSize) {
|
|
131108
|
+
const len2 = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
131109
|
+
if (len2 === 0)
|
|
131110
|
+
return null;
|
|
131111
|
+
const ux = dirX / len2;
|
|
131112
|
+
const uy = dirY / len2;
|
|
131113
|
+
const px = -uy;
|
|
131114
|
+
const py = ux;
|
|
131115
|
+
const halfBase = dataSize * 0.4;
|
|
131116
|
+
const bx = tipX - ux * dataSize;
|
|
131117
|
+
const by = tipY - uy * dataSize;
|
|
131118
|
+
return [
|
|
131119
|
+
[tipX, tipY],
|
|
131120
|
+
[bx + px * halfBase, by + py * halfBase],
|
|
131121
|
+
[bx - px * halfBase, by - py * halfBase]
|
|
131122
|
+
];
|
|
131123
|
+
}
|
|
131124
|
+
function fmtCommas(n2) {
|
|
131125
|
+
return Math.round(n2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
131126
|
+
}
|
|
131127
|
+
function getMeasurementLabel(shape2, physicalPixelSize, viewType = ViewType$1.SPATIAL) {
|
|
131128
|
+
const pps = physicalPixelSize;
|
|
131129
|
+
const px = pps?.x ?? 1;
|
|
131130
|
+
const py = pps?.y ?? 1;
|
|
131131
|
+
const unit = pps ? pps.unit ?? "" : null;
|
|
131132
|
+
const hasPhys = !!pps;
|
|
131133
|
+
const isEmbedding = viewType === ViewType$1.SCATTERPLOT;
|
|
131134
|
+
const fmtDist = (d) => {
|
|
131135
|
+
if (hasPhys)
|
|
131136
|
+
return `${d.toFixed(2)} ${unit}`;
|
|
131137
|
+
if (isEmbedding)
|
|
131138
|
+
return d.toFixed(2);
|
|
131139
|
+
return `${fmtCommas(d)} px`;
|
|
131140
|
+
};
|
|
131141
|
+
const fmtArea = (a2) => {
|
|
131142
|
+
if (hasPhys)
|
|
131143
|
+
return `${a2.toFixed(2)} ${unit}²`;
|
|
131144
|
+
if (isEmbedding)
|
|
131145
|
+
return a2.toFixed(2);
|
|
131146
|
+
return `${fmtCommas(a2)} px²`;
|
|
131147
|
+
};
|
|
131148
|
+
if (shape2.type === "line") {
|
|
131149
|
+
const dx = (shape2.x2 ?? 0) - (shape2.x1 ?? 0);
|
|
131150
|
+
const dy = (shape2.y2 ?? 0) - (shape2.y1 ?? 0);
|
|
131151
|
+
const dist2 = hasPhys ? Math.sqrt((dx * px) ** 2 + (dy * py) ** 2) : Math.sqrt(dx * dx + dy * dy);
|
|
131152
|
+
return fmtDist(dist2);
|
|
131153
|
+
}
|
|
131154
|
+
if (shape2.type === "rectangle") {
|
|
131155
|
+
return fmtArea(hasPhys ? Math.abs(shape2.width ?? 0) * px * Math.abs(shape2.height ?? 0) * py : Math.abs((shape2.width ?? 0) * (shape2.height ?? 0)));
|
|
131156
|
+
}
|
|
131157
|
+
if (shape2.type === "ellipse") {
|
|
131158
|
+
const rx = Math.abs(shape2.radiusX ?? 0);
|
|
131159
|
+
const ry = Math.abs(shape2.radiusY ?? 0);
|
|
131160
|
+
return fmtArea(hasPhys ? Math.PI * rx * px * ry * py : Math.PI * rx * ry);
|
|
131161
|
+
}
|
|
131162
|
+
if (shape2.type === "polygon" && shape2.points?.length >= 3) {
|
|
131163
|
+
const pts = shape2.points;
|
|
131164
|
+
let shoelace = 0;
|
|
131165
|
+
for (let i2 = 0; i2 < pts.length; i2++) {
|
|
131166
|
+
const [ax, ay] = pts[i2];
|
|
131167
|
+
const [bx, by] = pts[(i2 + 1) % pts.length];
|
|
131168
|
+
shoelace += (hasPhys ? ax * px : ax) * (hasPhys ? by * py : by) - (hasPhys ? bx * px : bx) * (hasPhys ? ay * py : ay);
|
|
131169
|
+
}
|
|
131170
|
+
return fmtArea(Math.abs(shoelace / 2));
|
|
131171
|
+
}
|
|
131172
|
+
if (shape2.type === "polyline" && shape2.points?.length >= 2) {
|
|
131173
|
+
let total = 0;
|
|
131174
|
+
for (let i2 = 0; i2 < shape2.points.length - 1; i2++) {
|
|
131175
|
+
const [ax, ay] = shape2.points[i2];
|
|
131176
|
+
const [bx, by] = shape2.points[i2 + 1];
|
|
131177
|
+
total += hasPhys ? Math.sqrt(((bx - ax) * px) ** 2 + ((by - ay) * py) ** 2) : Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
|
|
131178
|
+
}
|
|
131179
|
+
return fmtDist(total);
|
|
131180
|
+
}
|
|
131181
|
+
return null;
|
|
131182
|
+
}
|
|
131183
|
+
function pickBelowPerp(ux, uy) {
|
|
131184
|
+
const rp = [uy, -ux];
|
|
131185
|
+
const lp = [-uy, ux];
|
|
131186
|
+
return rp[1] > lp[1] || rp[1] === lp[1] && rp[0] > lp[0] ? rp : lp;
|
|
131187
|
+
}
|
|
131188
|
+
function readableAngle(deg) {
|
|
131189
|
+
let a2 = deg;
|
|
131190
|
+
if (a2 > 90)
|
|
131191
|
+
a2 -= 180;
|
|
131192
|
+
if (a2 < -90)
|
|
131193
|
+
a2 += 180;
|
|
131194
|
+
return a2;
|
|
131195
|
+
}
|
|
131196
|
+
function getShapeCentroid(shape2) {
|
|
131197
|
+
if (shape2.type === "rectangle") {
|
|
131198
|
+
return [(shape2.x ?? 0) + (shape2.width ?? 0) / 2, (shape2.y ?? 0) + (shape2.height ?? 0) / 2];
|
|
131199
|
+
}
|
|
131200
|
+
if (shape2.type === "line") {
|
|
131201
|
+
return [((shape2.x1 ?? 0) + (shape2.x2 ?? 0)) / 2, ((shape2.y1 ?? 0) + (shape2.y2 ?? 0)) / 2];
|
|
131202
|
+
}
|
|
131203
|
+
if (shape2.type === "ellipse") {
|
|
131204
|
+
return [shape2.x1 ?? 0, shape2.y1 ?? 0];
|
|
131205
|
+
}
|
|
131206
|
+
if ((shape2.type === "polygon" || shape2.type === "polyline") && shape2.points?.length >= 1) {
|
|
131207
|
+
const mx = shape2.points.reduce((s2, p) => s2 + p[0], 0) / shape2.points.length;
|
|
131208
|
+
const my = shape2.points.reduce((s2, p) => s2 + p[1], 0) / shape2.points.length;
|
|
131209
|
+
return [mx, my];
|
|
131210
|
+
}
|
|
131211
|
+
return [0, 0];
|
|
131212
|
+
}
|
|
131213
|
+
function computeClusters(shapeList, zoom, cellPx = 50) {
|
|
131214
|
+
const cellSize = cellPx / 2 ** Math.floor(zoom);
|
|
131215
|
+
const cells = /* @__PURE__ */ new Map();
|
|
131216
|
+
shapeList.forEach(({ shape: shape2 }) => {
|
|
131217
|
+
const [cx, cy] = getShapeCentroid(shape2);
|
|
131218
|
+
const key = `${Math.floor(cx / cellSize)},${Math.floor(cy / cellSize)}`;
|
|
131219
|
+
if (!cells.has(key)) {
|
|
131220
|
+
cells.set(key, { sumX: 0, sumY: 0, count: 0, color: shape2.strokeColor ?? [255, 255, 255] });
|
|
131221
|
+
}
|
|
131222
|
+
const c2 = cells.get(key);
|
|
131223
|
+
c2.sumX += cx;
|
|
131224
|
+
c2.sumY += cy;
|
|
131225
|
+
c2.count++;
|
|
131226
|
+
});
|
|
131227
|
+
return Array.from(cells.values()).map((c2) => ({
|
|
131228
|
+
position: [c2.sumX / c2.count, c2.sumY / c2.count, 0],
|
|
131229
|
+
count: c2.count,
|
|
131230
|
+
color: c2.color
|
|
131231
|
+
}));
|
|
131232
|
+
}
|
|
131233
|
+
function createAnnotationLayers(shapes = [], zoom = 0, selectedShapeUid = null, physicalPixelSize = null, authoredZoom = null, semanticZoom = true, viewType = ViewType$1.SPATIAL) {
|
|
131234
|
+
const selectionLayers = [];
|
|
131235
|
+
if (selectedShapeUid) {
|
|
131236
|
+
const sel = shapes.find((s2) => s2.uid === selectedShapeUid);
|
|
131237
|
+
if (sel) {
|
|
131238
|
+
const { uid: sUid, type: sType, strokeWidth: sStrokeWidth = 3 } = sel;
|
|
131239
|
+
const haloColor = [255, 220, 50, 70];
|
|
131240
|
+
const haloWidth = Math.max(sStrokeWidth + 8, 10);
|
|
131241
|
+
const base = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN };
|
|
131242
|
+
if (sType === "rectangle") {
|
|
131243
|
+
const { x, y, width: width2, height: height2 } = sel;
|
|
131244
|
+
selectionLayers.push(new PathLayer({
|
|
131245
|
+
...base,
|
|
131246
|
+
id: `annotation-select-${sUid}`,
|
|
131247
|
+
data: [{
|
|
131248
|
+
path: [
|
|
131249
|
+
[x, y],
|
|
131250
|
+
[x + width2, y],
|
|
131251
|
+
[x + width2, y + height2],
|
|
131252
|
+
[x, y + height2],
|
|
131253
|
+
[x, y]
|
|
131254
|
+
]
|
|
131255
|
+
}],
|
|
131256
|
+
getPath: (d) => d.path,
|
|
131257
|
+
getColor: haloColor,
|
|
131258
|
+
getWidth: haloWidth,
|
|
131259
|
+
widthUnits: "pixels",
|
|
131260
|
+
jointRounded: true,
|
|
131261
|
+
capRounded: true
|
|
131262
|
+
}));
|
|
131263
|
+
}
|
|
131264
|
+
if (sType === "line") {
|
|
131265
|
+
const { x1: x12, y1: y12, x2, y2 } = sel;
|
|
131266
|
+
selectionLayers.push(new PathLayer({
|
|
131267
|
+
...base,
|
|
131268
|
+
id: `annotation-select-${sUid}`,
|
|
131269
|
+
data: [{ path: [[x12, y12], [x2, y2]] }],
|
|
131270
|
+
getPath: (d) => d.path,
|
|
131271
|
+
getColor: haloColor,
|
|
131272
|
+
getWidth: haloWidth,
|
|
131273
|
+
widthUnits: "pixels",
|
|
131274
|
+
capRounded: true
|
|
131275
|
+
}));
|
|
131276
|
+
}
|
|
131277
|
+
if (sType === "ellipse") {
|
|
131278
|
+
const polygon2 = computeEllipsePolygon(sel.x1, sel.y1, sel.radiusX, sel.radiusY);
|
|
131279
|
+
selectionLayers.push(new PathLayer({
|
|
131280
|
+
...base,
|
|
131281
|
+
id: `annotation-select-${sUid}`,
|
|
131282
|
+
data: [{ path: [...polygon2, polygon2[0]] }],
|
|
131283
|
+
getPath: (d) => d.path,
|
|
131284
|
+
getColor: haloColor,
|
|
131285
|
+
getWidth: haloWidth,
|
|
131286
|
+
widthUnits: "pixels",
|
|
131287
|
+
jointRounded: true
|
|
131288
|
+
}));
|
|
131289
|
+
}
|
|
131290
|
+
if (sType === "polygon" && sel.points?.length >= 3) {
|
|
131291
|
+
selectionLayers.push(new PathLayer({
|
|
131292
|
+
...base,
|
|
131293
|
+
id: `annotation-select-${sUid}`,
|
|
131294
|
+
data: [{ path: [...sel.points, sel.points[0]] }],
|
|
131295
|
+
getPath: (d) => d.path,
|
|
131296
|
+
getColor: haloColor,
|
|
131297
|
+
getWidth: haloWidth,
|
|
131298
|
+
widthUnits: "pixels",
|
|
131299
|
+
jointRounded: true
|
|
131300
|
+
}));
|
|
131301
|
+
}
|
|
131302
|
+
if (sType === "polyline" && sel.points?.length >= 2) {
|
|
131303
|
+
selectionLayers.push(new PathLayer({
|
|
131304
|
+
...base,
|
|
131305
|
+
id: `annotation-select-${sUid}`,
|
|
131306
|
+
data: [{ path: sel.points }],
|
|
131307
|
+
getPath: (d) => d.path,
|
|
131308
|
+
getColor: haloColor,
|
|
131309
|
+
getWidth: haloWidth,
|
|
131310
|
+
widthUnits: "pixels",
|
|
131311
|
+
jointRounded: true,
|
|
131312
|
+
capRounded: true
|
|
131313
|
+
}));
|
|
131314
|
+
}
|
|
131315
|
+
}
|
|
131316
|
+
}
|
|
131317
|
+
const layers = [];
|
|
131318
|
+
const dotShapes = [];
|
|
131319
|
+
const clusterDotShapes = [];
|
|
131320
|
+
shapes.forEach((shape2, i2) => {
|
|
131321
|
+
const { uid: uid2, type, strokeColor = [255, 255, 255], strokeWidth = 3, strokeDashArray } = shape2;
|
|
131322
|
+
const isSelected = uid2 === selectedShapeUid;
|
|
131323
|
+
let shapeOpacity = 1;
|
|
131324
|
+
let tipsOpacity = 1;
|
|
131325
|
+
let labelOpacity = 0;
|
|
131326
|
+
if (isSelected || !semanticZoom || authoredZoom === null) {
|
|
131327
|
+
tipsOpacity = 1;
|
|
131328
|
+
labelOpacity = 1;
|
|
131329
|
+
} else {
|
|
131330
|
+
const zoomRatio = 2 ** (zoom - authoredZoom);
|
|
131331
|
+
if (zoomRatio < RATIO_CLUSTER) {
|
|
131332
|
+
clusterDotShapes.push({ shape: shape2 });
|
|
131333
|
+
return;
|
|
131334
|
+
}
|
|
131335
|
+
if (zoomRatio < RATIO_DOT) {
|
|
131336
|
+
dotShapes.push({ shape: shape2, alpha: 200 });
|
|
131337
|
+
return;
|
|
131338
|
+
}
|
|
131339
|
+
if (zoomRatio < RATIO_GEO_FADE) {
|
|
131340
|
+
const t = (zoomRatio - RATIO_DOT) / (RATIO_GEO_FADE - RATIO_DOT);
|
|
131341
|
+
shapeOpacity = t;
|
|
131342
|
+
dotShapes.push({ shape: shape2, alpha: Math.round((1 - t) * 200) });
|
|
131343
|
+
}
|
|
131344
|
+
tipsOpacity = zoomRatio >= RATIO_TIPS ? shapeOpacity : Math.max(0, (zoomRatio - RATIO_GEO_FADE) / (RATIO_TIPS - RATIO_GEO_FADE) * shapeOpacity);
|
|
131345
|
+
if (zoomRatio >= RATIO_LABEL_FULL) {
|
|
131346
|
+
labelOpacity = shapeOpacity;
|
|
131347
|
+
} else if (zoomRatio >= RATIO_LABEL) {
|
|
131348
|
+
labelOpacity = (zoomRatio - RATIO_LABEL) / (RATIO_LABEL_FULL - RATIO_LABEL) * shapeOpacity;
|
|
131349
|
+
}
|
|
131350
|
+
}
|
|
131351
|
+
const arrowDataSize = Math.max(ARROW_SCREEN_PX, strokeWidth * 4) / 2 ** zoom;
|
|
131352
|
+
const base = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: shapeOpacity };
|
|
131353
|
+
const tipsBase = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: tipsOpacity };
|
|
131354
|
+
const labelBase = { coordinateSystem: COORDINATE_SYSTEM.CARTESIAN, opacity: labelOpacity };
|
|
131355
|
+
const labelBgProps = shape2.labelBackground ? {
|
|
131356
|
+
background: true,
|
|
131357
|
+
getBackgroundColor: textBgColor(strokeColor),
|
|
131358
|
+
backgroundPadding: [3, 1, 3, 2]
|
|
131359
|
+
} : {};
|
|
131360
|
+
const labelProps = { ...labelBgProps };
|
|
131361
|
+
const dashArray = parseDashArray(strokeDashArray);
|
|
131362
|
+
const dashExt = [new PathStyleExtension({ dash: true })];
|
|
131363
|
+
const getDash = dashArray ?? [0, 0];
|
|
131364
|
+
if (type === "rectangle") {
|
|
131365
|
+
const { x, y, width: width2, height: height2, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
131366
|
+
const filled = fillOpacity > 0;
|
|
131367
|
+
const rectPolygon = [[x, y], [x + width2, y], [x + width2, y + height2], [x, y + height2]];
|
|
131368
|
+
layers.push(new PolygonLayer({
|
|
131369
|
+
...base,
|
|
131370
|
+
id: `annotation-rect-${uid2}-${i2}`,
|
|
131371
|
+
data: [{ polygon: rectPolygon }],
|
|
131372
|
+
getPolygon: (d) => d.polygon,
|
|
131373
|
+
filled,
|
|
131374
|
+
stroked: true,
|
|
131375
|
+
getFillColor: filled ? [...fillColor, Math.round(fillOpacity * 255)] : [0, 0, 0, 0],
|
|
131376
|
+
getLineColor: strokeColor,
|
|
131377
|
+
getLineWidth: strokeWidth,
|
|
131378
|
+
lineWidthUnits: "pixels",
|
|
131379
|
+
...dashArray ? {
|
|
131380
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131381
|
+
getDashArray: dashArray
|
|
131382
|
+
} : {}
|
|
131383
|
+
}));
|
|
131384
|
+
if (shape2.text && labelOpacity > 0) {
|
|
131385
|
+
layers.push(new TextLayer({
|
|
131386
|
+
...labelBase,
|
|
131387
|
+
...labelProps,
|
|
131388
|
+
id: `annotation-rect-text-${uid2}-${i2}`,
|
|
131389
|
+
data: [{ position: [x, y], text: shape2.text }],
|
|
131390
|
+
getPosition: (d) => d.position,
|
|
131391
|
+
getText: (d) => d.text,
|
|
131392
|
+
getColor: strokeColor,
|
|
131393
|
+
getSize: LABEL_FONT_SIZE,
|
|
131394
|
+
sizeUnits: "pixels",
|
|
131395
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131396
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131397
|
+
getPixelOffset: [3, -7],
|
|
131398
|
+
getTextAnchor: "start",
|
|
131399
|
+
getAlignmentBaseline: "bottom"
|
|
131400
|
+
}));
|
|
131401
|
+
}
|
|
131402
|
+
}
|
|
131403
|
+
if (type === "line") {
|
|
131404
|
+
const { x1: x12, y1: y12, x2, y2, markerStart, markerEnd } = shape2;
|
|
131405
|
+
const dx = x2 - x12;
|
|
131406
|
+
const dy = y2 - y12;
|
|
131407
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131408
|
+
const ux = len2 > 0 ? dx / len2 : 0;
|
|
131409
|
+
const uy = len2 > 0 ? dy / len2 : 0;
|
|
131410
|
+
const srcX = markerStart === "Arrow" ? x12 + ux * arrowDataSize : x12;
|
|
131411
|
+
const srcY = markerStart === "Arrow" ? y12 + uy * arrowDataSize : y12;
|
|
131412
|
+
const tgtX = markerEnd === "Arrow" ? x2 - ux * arrowDataSize : x2;
|
|
131413
|
+
const tgtY = markerEnd === "Arrow" ? y2 - uy * arrowDataSize : y2;
|
|
131414
|
+
layers.push(new PathLayer({
|
|
131415
|
+
...base,
|
|
131416
|
+
id: `annotation-line-${uid2}-${i2}`,
|
|
131417
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131418
|
+
getDashArray: dashArray ?? [0, 0],
|
|
131419
|
+
data: [{ path: [[srcX, srcY], [tgtX, tgtY]] }],
|
|
131420
|
+
getPath: (d) => d.path,
|
|
131421
|
+
getColor: strokeColor,
|
|
131422
|
+
getWidth: strokeWidth,
|
|
131423
|
+
widthUnits: "pixels",
|
|
131424
|
+
capRounded: true
|
|
131425
|
+
}));
|
|
131426
|
+
if (markerEnd === "Arrow" && tipsOpacity > 0) {
|
|
131427
|
+
const head = computeArrowhead(x2, y2, x2 - x12, y2 - y12, arrowDataSize);
|
|
131428
|
+
if (head) {
|
|
131429
|
+
layers.push(new PolygonLayer({
|
|
131430
|
+
...tipsBase,
|
|
131431
|
+
id: `annotation-end-arrow-${uid2}-${i2}`,
|
|
131432
|
+
data: [{ polygon: head }],
|
|
131433
|
+
getPolygon: (d) => d.polygon,
|
|
131434
|
+
filled: true,
|
|
131435
|
+
stroked: false,
|
|
131436
|
+
getFillColor: strokeColor
|
|
131437
|
+
}));
|
|
131438
|
+
}
|
|
131439
|
+
}
|
|
131440
|
+
if (markerStart === "Arrow" && tipsOpacity > 0) {
|
|
131441
|
+
const head = computeArrowhead(x12, y12, x12 - x2, y12 - y2, arrowDataSize);
|
|
131442
|
+
if (head) {
|
|
131443
|
+
layers.push(new PolygonLayer({
|
|
131444
|
+
...tipsBase,
|
|
131445
|
+
id: `annotation-start-arrow-${uid2}-${i2}`,
|
|
131446
|
+
data: [{ polygon: head }],
|
|
131447
|
+
getPolygon: (d) => d.polygon,
|
|
131448
|
+
filled: true,
|
|
131449
|
+
stroked: false,
|
|
131450
|
+
getFillColor: strokeColor
|
|
131451
|
+
}));
|
|
131452
|
+
}
|
|
131453
|
+
}
|
|
131454
|
+
if (markerEnd === "Tick" && tipsOpacity > 0) {
|
|
131455
|
+
const tick = computeTickCap(x2, y2, x2 - x12, y2 - y12, arrowDataSize);
|
|
131456
|
+
if (tick) {
|
|
131457
|
+
layers.push(new PathLayer({
|
|
131458
|
+
...tipsBase,
|
|
131459
|
+
id: `annotation-end-tick-${uid2}-${i2}`,
|
|
131460
|
+
data: [{ path: tick }],
|
|
131461
|
+
getPath: (d) => d.path,
|
|
131462
|
+
getColor: strokeColor,
|
|
131463
|
+
getWidth: strokeWidth,
|
|
131464
|
+
widthUnits: "pixels",
|
|
131465
|
+
capRounded: true
|
|
131466
|
+
}));
|
|
131467
|
+
}
|
|
131468
|
+
}
|
|
131469
|
+
if (markerStart === "Tick" && tipsOpacity > 0) {
|
|
131470
|
+
const tick = computeTickCap(x12, y12, x12 - x2, y12 - y2, arrowDataSize);
|
|
131471
|
+
if (tick) {
|
|
131472
|
+
layers.push(new PathLayer({
|
|
131473
|
+
...tipsBase,
|
|
131474
|
+
id: `annotation-start-tick-${uid2}-${i2}`,
|
|
131475
|
+
data: [{ path: tick }],
|
|
131476
|
+
getPath: (d) => d.path,
|
|
131477
|
+
getColor: strokeColor,
|
|
131478
|
+
getWidth: strokeWidth,
|
|
131479
|
+
widthUnits: "pixels",
|
|
131480
|
+
capRounded: true
|
|
131481
|
+
}));
|
|
131482
|
+
}
|
|
131483
|
+
}
|
|
131484
|
+
if (shape2.text) {
|
|
131485
|
+
const pos = shape2.textPosition ?? "start";
|
|
131486
|
+
let textX;
|
|
131487
|
+
let textY;
|
|
131488
|
+
if (pos === "start") {
|
|
131489
|
+
textX = x12;
|
|
131490
|
+
textY = y12;
|
|
131491
|
+
} else if (pos === "end") {
|
|
131492
|
+
textX = x2;
|
|
131493
|
+
textY = y2;
|
|
131494
|
+
} else {
|
|
131495
|
+
textX = (x12 + x2) / 2;
|
|
131496
|
+
textY = (y12 + y2) / 2;
|
|
131497
|
+
}
|
|
131498
|
+
let pixelOffset = [0, 0];
|
|
131499
|
+
let textAnchor = "middle";
|
|
131500
|
+
let alignmentBaseline = "center";
|
|
131501
|
+
if (pos !== "middle") {
|
|
131502
|
+
const dxT = x2 - x12;
|
|
131503
|
+
const dyT = y2 - y12;
|
|
131504
|
+
const lenT = Math.sqrt(dxT * dxT + dyT * dyT);
|
|
131505
|
+
if (lenT > 0) {
|
|
131506
|
+
const uxT = dxT / lenT;
|
|
131507
|
+
const uyT = dyT / lenT;
|
|
131508
|
+
const sign2 = pos === "start" ? -1 : 1;
|
|
131509
|
+
const bufferPx = shape2.textBufferPx ?? 8;
|
|
131510
|
+
const offsetX = sign2 * uxT * bufferPx;
|
|
131511
|
+
const offsetY = sign2 * uyT * bufferPx;
|
|
131512
|
+
pixelOffset = [offsetX, offsetY];
|
|
131513
|
+
const absX = Math.abs(offsetX);
|
|
131514
|
+
const absY = Math.abs(offsetY);
|
|
131515
|
+
if (absX >= absY) {
|
|
131516
|
+
textAnchor = offsetX > 0 ? "start" : "end";
|
|
131517
|
+
}
|
|
131518
|
+
if (absY >= absX) {
|
|
131519
|
+
alignmentBaseline = offsetY > 0 ? "top" : "bottom";
|
|
131520
|
+
}
|
|
131521
|
+
}
|
|
131522
|
+
} else if (len2 > 0) {
|
|
131523
|
+
const belowPerp = pickBelowPerp(ux, uy);
|
|
131524
|
+
const bufferPx = shape2.textBufferPx ?? 14;
|
|
131525
|
+
pixelOffset = [-belowPerp[0] * bufferPx, -belowPerp[1] * bufferPx];
|
|
131526
|
+
textAnchor = "middle";
|
|
131527
|
+
alignmentBaseline = "center";
|
|
131528
|
+
}
|
|
131529
|
+
const middleAngle = pos === "middle" && len2 > 0 ? -readableAngle(Math.atan2(dy, dx) * 180 / Math.PI) : null;
|
|
131530
|
+
if (labelOpacity <= 0)
|
|
131531
|
+
return;
|
|
131532
|
+
layers.push(new TextLayer({
|
|
131533
|
+
...labelBase,
|
|
131534
|
+
...labelProps,
|
|
131535
|
+
id: `annotation-line-text-${uid2}-${i2}`,
|
|
131536
|
+
data: [{ position: [textX, textY], text: shape2.text }],
|
|
131537
|
+
getPosition: (d) => d.position,
|
|
131538
|
+
getText: (d) => d.text,
|
|
131539
|
+
getColor: strokeColor,
|
|
131540
|
+
getSize: LABEL_FONT_SIZE,
|
|
131541
|
+
sizeUnits: "pixels",
|
|
131542
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131543
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131544
|
+
getPixelOffset: pixelOffset,
|
|
131545
|
+
getTextAnchor: textAnchor,
|
|
131546
|
+
getAlignmentBaseline: alignmentBaseline,
|
|
131547
|
+
...middleAngle !== null && { getAngle: middleAngle }
|
|
131548
|
+
}));
|
|
131549
|
+
}
|
|
131550
|
+
}
|
|
131551
|
+
if (type === "ellipse") {
|
|
131552
|
+
const { x1: x12, y1: y12, radiusX, radiusY, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
131553
|
+
const polygon2 = computeEllipsePolygon(x12, y12, radiusX, radiusY);
|
|
131554
|
+
const filled = fillOpacity > 0;
|
|
131555
|
+
layers.push(new PolygonLayer({
|
|
131556
|
+
...base,
|
|
131557
|
+
id: `annotation-ellipse-${uid2}-${i2}`,
|
|
131558
|
+
data: [{ polygon: polygon2 }],
|
|
131559
|
+
getPolygon: (d) => d.polygon,
|
|
131560
|
+
filled,
|
|
131561
|
+
stroked: true,
|
|
131562
|
+
getFillColor: filled ? [...fillColor, Math.round(fillOpacity * 255)] : [0, 0, 0, 0],
|
|
131563
|
+
getLineColor: strokeColor,
|
|
131564
|
+
getLineWidth: strokeWidth,
|
|
131565
|
+
lineWidthUnits: "pixels",
|
|
131566
|
+
...dashArray ? {
|
|
131567
|
+
extensions: [new PathStyleExtension({ dash: true })],
|
|
131568
|
+
getDashArray: dashArray
|
|
131569
|
+
} : {}
|
|
131570
|
+
}));
|
|
131571
|
+
if (shape2.text && labelOpacity > 0) {
|
|
131572
|
+
layers.push(new TextLayer({
|
|
131573
|
+
...labelBase,
|
|
131574
|
+
...labelProps,
|
|
131575
|
+
id: `annotation-ellipse-text-${uid2}-${i2}`,
|
|
131576
|
+
data: [{ position: [x12, y12 - radiusY], text: shape2.text }],
|
|
131577
|
+
getPosition: (d) => d.position,
|
|
131578
|
+
getText: (d) => d.text,
|
|
131579
|
+
getColor: strokeColor,
|
|
131580
|
+
getSize: LABEL_FONT_SIZE,
|
|
131581
|
+
sizeUnits: "pixels",
|
|
131582
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131583
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131584
|
+
getPixelOffset: [0, -4],
|
|
131585
|
+
getTextAnchor: "middle",
|
|
131586
|
+
getAlignmentBaseline: "bottom"
|
|
131587
|
+
}));
|
|
131588
|
+
}
|
|
131589
|
+
}
|
|
131590
|
+
if (type === "polygon") {
|
|
131591
|
+
const { points, fillColor = strokeColor, fillOpacity = 0 } = shape2;
|
|
131592
|
+
if (!points || points.length < 3)
|
|
131593
|
+
return;
|
|
131594
|
+
const closedPath = [...points, points[0]];
|
|
131595
|
+
if (fillOpacity > 0) {
|
|
131596
|
+
layers.push(new PolygonLayer({
|
|
131597
|
+
...base,
|
|
131598
|
+
id: `annotation-polygon-fill-${uid2}-${i2}`,
|
|
131599
|
+
data: [{ polygon: points }],
|
|
131600
|
+
getPolygon: (d) => d.polygon,
|
|
131601
|
+
stroked: false,
|
|
131602
|
+
filled: true,
|
|
131603
|
+
getFillColor: [...fillColor, Math.round(fillOpacity * 255)]
|
|
131604
|
+
}));
|
|
131605
|
+
}
|
|
131606
|
+
layers.push(new PathLayer({
|
|
131607
|
+
...base,
|
|
131608
|
+
id: `annotation-polygon-${uid2}-${i2}`,
|
|
131609
|
+
extensions: dashExt,
|
|
131610
|
+
getDashArray: getDash,
|
|
131611
|
+
data: [{ path: closedPath }],
|
|
131612
|
+
getPath: (d) => d.path,
|
|
131613
|
+
getColor: strokeColor,
|
|
131614
|
+
getWidth: strokeWidth,
|
|
131615
|
+
widthUnits: "pixels",
|
|
131616
|
+
jointRounded: true
|
|
131617
|
+
}));
|
|
131618
|
+
if (shape2.text && labelOpacity > 0) {
|
|
131619
|
+
const minX = Math.min(...points.map((p) => p[0]));
|
|
131620
|
+
const maxX = Math.max(...points.map((p) => p[0]));
|
|
131621
|
+
const minY = Math.min(...points.map((p) => p[1]));
|
|
131622
|
+
const topCenterX = (minX + maxX) / 2;
|
|
131623
|
+
layers.push(new TextLayer({
|
|
131624
|
+
...labelBase,
|
|
131625
|
+
...labelProps,
|
|
131626
|
+
id: `annotation-polygon-text-${uid2}-${i2}`,
|
|
131627
|
+
data: [{ position: [topCenterX, minY], text: shape2.text }],
|
|
131628
|
+
getPosition: (d) => d.position,
|
|
131629
|
+
getText: (d) => d.text,
|
|
131630
|
+
getColor: strokeColor,
|
|
131631
|
+
getSize: LABEL_FONT_SIZE,
|
|
131632
|
+
sizeUnits: "pixels",
|
|
131633
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131634
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131635
|
+
getPixelOffset: [0, -4],
|
|
131636
|
+
getTextAnchor: "middle",
|
|
131637
|
+
getAlignmentBaseline: "bottom"
|
|
131638
|
+
}));
|
|
131639
|
+
}
|
|
131640
|
+
}
|
|
131641
|
+
if (type === "polyline") {
|
|
131642
|
+
const { points, markerStart, markerEnd } = shape2;
|
|
131643
|
+
if (!points || points.length < 2)
|
|
131644
|
+
return;
|
|
131645
|
+
let pathPoints = points;
|
|
131646
|
+
if (markerStart === "Arrow") {
|
|
131647
|
+
const [x02, y02] = points[0];
|
|
131648
|
+
const [x12, y12] = points[1];
|
|
131649
|
+
const dx = x02 - x12;
|
|
131650
|
+
const dy = y02 - y12;
|
|
131651
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131652
|
+
if (len2 > 0) {
|
|
131653
|
+
const ux = dx / len2;
|
|
131654
|
+
const uy = dy / len2;
|
|
131655
|
+
pathPoints = [[x02 - ux * arrowDataSize, y02 - uy * arrowDataSize], ...pathPoints.slice(1)];
|
|
131656
|
+
}
|
|
131657
|
+
}
|
|
131658
|
+
if (markerEnd === "Arrow") {
|
|
131659
|
+
const last = pathPoints[pathPoints.length - 1];
|
|
131660
|
+
const prev2 = pathPoints[pathPoints.length - 2];
|
|
131661
|
+
const dx = last[0] - prev2[0];
|
|
131662
|
+
const dy = last[1] - prev2[1];
|
|
131663
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131664
|
+
if (len2 > 0) {
|
|
131665
|
+
const ux = dx / len2;
|
|
131666
|
+
const uy = dy / len2;
|
|
131667
|
+
const shortened = [last[0] - ux * arrowDataSize, last[1] - uy * arrowDataSize];
|
|
131668
|
+
pathPoints = [...pathPoints.slice(0, -1), shortened];
|
|
131669
|
+
}
|
|
131670
|
+
}
|
|
131671
|
+
layers.push(new PathLayer({
|
|
131672
|
+
...base,
|
|
131673
|
+
id: `annotation-polyline-${uid2}-${i2}`,
|
|
131674
|
+
extensions: dashExt,
|
|
131675
|
+
getDashArray: getDash,
|
|
131676
|
+
data: [{ path: pathPoints }],
|
|
131677
|
+
getPath: (d) => d.path,
|
|
131678
|
+
getColor: strokeColor,
|
|
131679
|
+
getWidth: strokeWidth,
|
|
131680
|
+
widthUnits: "pixels",
|
|
131681
|
+
jointRounded: true,
|
|
131682
|
+
capRounded: true
|
|
131683
|
+
}));
|
|
131684
|
+
if (markerStart === "Arrow" && tipsOpacity > 0) {
|
|
131685
|
+
const [x02, y02] = points[0];
|
|
131686
|
+
const [x12, y12] = points[1];
|
|
131687
|
+
const head = computeArrowhead(x02, y02, x02 - x12, y02 - y12, arrowDataSize);
|
|
131688
|
+
if (head) {
|
|
131689
|
+
layers.push(new PolygonLayer({
|
|
131690
|
+
...tipsBase,
|
|
131691
|
+
id: `annotation-polyline-start-arrow-${uid2}-${i2}`,
|
|
131692
|
+
data: [{ polygon: head }],
|
|
131693
|
+
getPolygon: (d) => d.polygon,
|
|
131694
|
+
filled: true,
|
|
131695
|
+
stroked: false,
|
|
131696
|
+
getFillColor: strokeColor
|
|
131697
|
+
}));
|
|
131698
|
+
}
|
|
131699
|
+
}
|
|
131700
|
+
if (markerEnd === "Arrow" && tipsOpacity > 0) {
|
|
131701
|
+
const last = points[points.length - 1];
|
|
131702
|
+
const prev2 = points[points.length - 2];
|
|
131703
|
+
const dxArrow = last[0] - prev2[0];
|
|
131704
|
+
const dyArrow = last[1] - prev2[1];
|
|
131705
|
+
const head = computeArrowhead(last[0], last[1], dxArrow, dyArrow, arrowDataSize);
|
|
131706
|
+
if (head) {
|
|
131707
|
+
layers.push(new PolygonLayer({
|
|
131708
|
+
...tipsBase,
|
|
131709
|
+
id: `annotation-polyline-end-arrow-${uid2}-${i2}`,
|
|
131710
|
+
data: [{ polygon: head }],
|
|
131711
|
+
getPolygon: (d) => d.polygon,
|
|
131712
|
+
filled: true,
|
|
131713
|
+
stroked: false,
|
|
131714
|
+
getFillColor: strokeColor
|
|
131715
|
+
}));
|
|
131716
|
+
}
|
|
131717
|
+
}
|
|
131718
|
+
if (markerStart === "Tick" && tipsOpacity > 0) {
|
|
131719
|
+
const [x02, y02] = points[0];
|
|
131720
|
+
const [x12, y12] = points[1];
|
|
131721
|
+
const tick = computeTickCap(x02, y02, x02 - x12, y02 - y12, arrowDataSize);
|
|
131722
|
+
if (tick) {
|
|
131723
|
+
layers.push(new PathLayer({
|
|
131724
|
+
...tipsBase,
|
|
131725
|
+
id: `annotation-polyline-start-tick-${uid2}-${i2}`,
|
|
131726
|
+
data: [{ path: tick }],
|
|
131727
|
+
getPath: (d) => d.path,
|
|
131728
|
+
getColor: strokeColor,
|
|
131729
|
+
getWidth: strokeWidth,
|
|
131730
|
+
widthUnits: "pixels",
|
|
131731
|
+
capRounded: true
|
|
131732
|
+
}));
|
|
131733
|
+
}
|
|
131734
|
+
}
|
|
131735
|
+
if (markerEnd === "Tick" && tipsOpacity > 0) {
|
|
131736
|
+
const last = points[points.length - 1];
|
|
131737
|
+
const prev2 = points[points.length - 2];
|
|
131738
|
+
const dxTick = last[0] - prev2[0];
|
|
131739
|
+
const dyTick = last[1] - prev2[1];
|
|
131740
|
+
const tick = computeTickCap(last[0], last[1], dxTick, dyTick, arrowDataSize);
|
|
131741
|
+
if (tick) {
|
|
131742
|
+
layers.push(new PathLayer({
|
|
131743
|
+
...tipsBase,
|
|
131744
|
+
id: `annotation-polyline-end-tick-${uid2}-${i2}`,
|
|
131745
|
+
data: [{ path: tick }],
|
|
131746
|
+
getPath: (d) => d.path,
|
|
131747
|
+
getColor: strokeColor,
|
|
131748
|
+
getWidth: strokeWidth,
|
|
131749
|
+
widthUnits: "pixels",
|
|
131750
|
+
capRounded: true
|
|
131751
|
+
}));
|
|
131752
|
+
}
|
|
131753
|
+
}
|
|
131754
|
+
if (shape2.text) {
|
|
131755
|
+
const pos = shape2.textPosition ?? "start";
|
|
131756
|
+
const bufferPx = shape2.textBufferPx ?? 8;
|
|
131757
|
+
let textPt;
|
|
131758
|
+
let dirX;
|
|
131759
|
+
let dirY;
|
|
131760
|
+
if (pos === "end") {
|
|
131761
|
+
const last = points[points.length - 1];
|
|
131762
|
+
const prev2 = points[points.length - 2];
|
|
131763
|
+
textPt = last;
|
|
131764
|
+
dirX = last[0] - prev2[0];
|
|
131765
|
+
dirY = last[1] - prev2[1];
|
|
131766
|
+
} else if (pos === "middle") {
|
|
131767
|
+
const mx = points.reduce((s2, p) => s2 + p[0], 0) / points.length;
|
|
131768
|
+
const my = points.reduce((s2, p) => s2 + p[1], 0) / points.length;
|
|
131769
|
+
textPt = [mx, my];
|
|
131770
|
+
dirX = 0;
|
|
131771
|
+
dirY = 0;
|
|
131772
|
+
} else {
|
|
131773
|
+
[textPt] = points;
|
|
131774
|
+
dirX = points[0][0] - points[1][0];
|
|
131775
|
+
dirY = points[0][1] - points[1][1];
|
|
131776
|
+
}
|
|
131777
|
+
const [textX, textY] = textPt;
|
|
131778
|
+
const lenT = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
131779
|
+
let polylinePixelOffset = [0, 0];
|
|
131780
|
+
let polylineTextAnchor = "middle";
|
|
131781
|
+
let polylineAlignmentBaseline = pos === "middle" ? "center" : "bottom";
|
|
131782
|
+
if (lenT > 0) {
|
|
131783
|
+
const uxT = dirX / lenT;
|
|
131784
|
+
const uyT = dirY / lenT;
|
|
131785
|
+
const offX = uxT * bufferPx;
|
|
131786
|
+
const offY = uyT * bufferPx;
|
|
131787
|
+
polylinePixelOffset = [offX, offY];
|
|
131788
|
+
if (Math.abs(offX) >= Math.abs(offY)) {
|
|
131789
|
+
polylineTextAnchor = offX > 0 ? "start" : "end";
|
|
131790
|
+
}
|
|
131791
|
+
if (Math.abs(offY) >= Math.abs(offX)) {
|
|
131792
|
+
polylineAlignmentBaseline = offY > 0 ? "top" : "bottom";
|
|
131793
|
+
}
|
|
131794
|
+
}
|
|
131795
|
+
if (labelOpacity <= 0)
|
|
131796
|
+
return;
|
|
131797
|
+
layers.push(new TextLayer({
|
|
131798
|
+
...labelBase,
|
|
131799
|
+
...labelProps,
|
|
131800
|
+
id: `annotation-polyline-text-${uid2}-${i2}`,
|
|
131801
|
+
data: [{ position: [textX, textY], text: shape2.text }],
|
|
131802
|
+
getPosition: (d) => d.position,
|
|
131803
|
+
getText: (d) => d.text,
|
|
131804
|
+
getColor: strokeColor,
|
|
131805
|
+
getSize: LABEL_FONT_SIZE,
|
|
131806
|
+
sizeUnits: "pixels",
|
|
131807
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131808
|
+
fontWeight: LABEL_FONT_WEIGHT,
|
|
131809
|
+
getPixelOffset: polylinePixelOffset,
|
|
131810
|
+
getTextAnchor: polylineTextAnchor,
|
|
131811
|
+
getAlignmentBaseline: polylineAlignmentBaseline
|
|
131812
|
+
}));
|
|
131813
|
+
}
|
|
131814
|
+
}
|
|
131815
|
+
});
|
|
131816
|
+
if (dotShapes.length > 0) {
|
|
131817
|
+
layers.push(new ScatterplotLayer({
|
|
131818
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
131819
|
+
id: "annotation-dots",
|
|
131820
|
+
data: dotShapes.map(({ shape: s2, alpha: alpha2 }) => ({
|
|
131821
|
+
position: getShapeCentroid(s2),
|
|
131822
|
+
color: [...s2.strokeColor ?? [255, 255, 255], alpha2]
|
|
131823
|
+
})),
|
|
131824
|
+
getPosition: (d) => d.position,
|
|
131825
|
+
getFillColor: (d) => d.color,
|
|
131826
|
+
getRadius: 4,
|
|
131827
|
+
radiusUnits: "pixels",
|
|
131828
|
+
filled: true,
|
|
131829
|
+
stroked: false
|
|
131830
|
+
}));
|
|
131831
|
+
}
|
|
131832
|
+
if (clusterDotShapes.length > 0) {
|
|
131833
|
+
const clusters = computeClusters(clusterDotShapes, zoom);
|
|
131834
|
+
layers.push(new ScatterplotLayer({
|
|
131835
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
131836
|
+
id: "annotation-clusters",
|
|
131837
|
+
data: clusters,
|
|
131838
|
+
getPosition: (d) => d.position,
|
|
131839
|
+
getFillColor: (d) => [...d.color, 180],
|
|
131840
|
+
getRadius: (d) => Math.max(6, 4 + Math.sqrt(d.count) * 2),
|
|
131841
|
+
radiusUnits: "pixels",
|
|
131842
|
+
filled: true,
|
|
131843
|
+
stroked: true,
|
|
131844
|
+
getLineColor: (d) => [...d.color, 220],
|
|
131845
|
+
lineWidthMinPixels: 1.5
|
|
131846
|
+
}));
|
|
131847
|
+
const multiClusters = clusters.filter((c2) => c2.count > 1);
|
|
131848
|
+
if (multiClusters.length > 0) {
|
|
131849
|
+
layers.push(new TextLayer({
|
|
131850
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
131851
|
+
id: "annotation-cluster-counts",
|
|
131852
|
+
data: multiClusters,
|
|
131853
|
+
getPosition: (d) => d.position,
|
|
131854
|
+
getText: (d) => String(d.count),
|
|
131855
|
+
getColor: [255, 255, 255],
|
|
131856
|
+
getSize: 10,
|
|
131857
|
+
sizeUnits: "pixels",
|
|
131858
|
+
fontWeight: "bold",
|
|
131859
|
+
getTextAnchor: "middle",
|
|
131860
|
+
getAlignmentBaseline: "center"
|
|
131861
|
+
}));
|
|
131862
|
+
}
|
|
131863
|
+
}
|
|
131864
|
+
const measureLayers = [];
|
|
131865
|
+
shapes.forEach((shape2) => {
|
|
131866
|
+
if (!shape2.showMeasure)
|
|
131867
|
+
return;
|
|
131868
|
+
const mIsSelected = shape2.uid === selectedShapeUid;
|
|
131869
|
+
const label = getMeasurementLabel(shape2, physicalPixelSize, viewType);
|
|
131870
|
+
if (!label)
|
|
131871
|
+
return;
|
|
131872
|
+
const color2 = shape2.strokeColor ?? [255, 255, 255];
|
|
131873
|
+
let mShapeOpacity = 1;
|
|
131874
|
+
let mLabelFactor = 0;
|
|
131875
|
+
if (mIsSelected || !semanticZoom || authoredZoom === null) {
|
|
131876
|
+
mLabelFactor = 1;
|
|
131877
|
+
} else {
|
|
131878
|
+
const mZoomRatio = 2 ** (zoom - authoredZoom);
|
|
131879
|
+
if (mZoomRatio < RATIO_DOT)
|
|
131880
|
+
return;
|
|
131881
|
+
if (mZoomRatio < RATIO_GEO_FADE) {
|
|
131882
|
+
mShapeOpacity = (mZoomRatio - RATIO_DOT) / (RATIO_GEO_FADE - RATIO_DOT);
|
|
131883
|
+
}
|
|
131884
|
+
if (mZoomRatio >= RATIO_LABEL_FULL) {
|
|
131885
|
+
mLabelFactor = 1;
|
|
131886
|
+
} else if (mZoomRatio >= RATIO_LABEL) {
|
|
131887
|
+
mLabelFactor = (mZoomRatio - RATIO_LABEL) / (RATIO_LABEL_FULL - RATIO_LABEL);
|
|
131888
|
+
}
|
|
131889
|
+
}
|
|
131890
|
+
const measureOpacity = mShapeOpacity * mLabelFactor;
|
|
131891
|
+
if (measureOpacity <= 0)
|
|
131892
|
+
return;
|
|
131893
|
+
const base = {
|
|
131894
|
+
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
131895
|
+
opacity: measureOpacity,
|
|
131896
|
+
getText: (d) => d.text,
|
|
131897
|
+
getPosition: (d) => d.position,
|
|
131898
|
+
getColor: color2,
|
|
131899
|
+
getSize: 13,
|
|
131900
|
+
sizeUnits: "pixels",
|
|
131901
|
+
fontFamily: LABEL_FONT_FAMILY$1,
|
|
131902
|
+
fontWeight: "bold",
|
|
131903
|
+
// 'auto' builds the font atlas from the actual rendered characters (e.g. µ, ²)
|
|
131904
|
+
// instead of deck.gl's default ASCII-only atlas.
|
|
131905
|
+
characterSet: "auto",
|
|
131906
|
+
...shape2.measureBackground ? {
|
|
131907
|
+
background: true,
|
|
131908
|
+
getBackgroundColor: textBgColor(color2),
|
|
131909
|
+
backgroundPadding: [3, 1, 3, 2]
|
|
131910
|
+
} : {}
|
|
131911
|
+
};
|
|
131912
|
+
if (shape2.type === "line") {
|
|
131913
|
+
const mx = ((shape2.x1 ?? 0) + (shape2.x2 ?? 0)) / 2;
|
|
131914
|
+
const my = ((shape2.y1 ?? 0) + (shape2.y2 ?? 0)) / 2;
|
|
131915
|
+
const dx = (shape2.x2 ?? 0) - (shape2.x1 ?? 0);
|
|
131916
|
+
const dy = (shape2.y2 ?? 0) - (shape2.y1 ?? 0);
|
|
131917
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131918
|
+
if (len2 === 0)
|
|
131919
|
+
return;
|
|
131920
|
+
const perp = pickBelowPerp(dx / len2, dy / len2);
|
|
131921
|
+
const angle2 = readableAngle(Math.atan2(dy, dx) * 180 / Math.PI);
|
|
131922
|
+
measureLayers.push(new TextLayer({
|
|
131923
|
+
...base,
|
|
131924
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
131925
|
+
data: [{ position: [mx, my], text: label }],
|
|
131926
|
+
getAngle: -angle2,
|
|
131927
|
+
getTextAnchor: "middle",
|
|
131928
|
+
getAlignmentBaseline: "center",
|
|
131929
|
+
getPixelOffset: [perp[0] * 16, perp[1] * 16]
|
|
131930
|
+
}));
|
|
131931
|
+
} else if (shape2.type === "polyline" && shape2.points?.length >= 2) {
|
|
131932
|
+
const pts = shape2.points;
|
|
131933
|
+
const mi = Math.floor((pts.length - 1) / 2);
|
|
131934
|
+
const [ax, ay] = pts[mi];
|
|
131935
|
+
const [bx, by] = pts[mi + 1];
|
|
131936
|
+
const dx = bx - ax;
|
|
131937
|
+
const dy = by - ay;
|
|
131938
|
+
const len2 = Math.sqrt(dx * dx + dy * dy);
|
|
131939
|
+
if (len2 === 0)
|
|
131940
|
+
return;
|
|
131941
|
+
const perp = pickBelowPerp(dx / len2, dy / len2);
|
|
131942
|
+
const angle2 = readableAngle(Math.atan2(dy, dx) * 180 / Math.PI);
|
|
131943
|
+
measureLayers.push(new TextLayer({
|
|
131944
|
+
...base,
|
|
131945
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
131946
|
+
data: [{ position: [(ax + bx) / 2, (ay + by) / 2], text: label }],
|
|
131947
|
+
getAngle: -angle2,
|
|
131948
|
+
getTextAnchor: "middle",
|
|
131949
|
+
getAlignmentBaseline: "center",
|
|
131950
|
+
getPixelOffset: [perp[0] * 16, perp[1] * 16]
|
|
131951
|
+
}));
|
|
131952
|
+
} else if (shape2.type === "rectangle") {
|
|
131953
|
+
const x02 = shape2.x ?? 0;
|
|
131954
|
+
const y02 = shape2.y ?? 0;
|
|
131955
|
+
const w2 = shape2.width ?? 0;
|
|
131956
|
+
const h = shape2.height ?? 0;
|
|
131957
|
+
const rx = x02 + (w2 >= 0 ? w2 : 0);
|
|
131958
|
+
const ry = y02 + (h >= 0 ? h : 0);
|
|
131959
|
+
measureLayers.push(new TextLayer({
|
|
131960
|
+
...base,
|
|
131961
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
131962
|
+
data: [{ position: [rx, ry], text: label }],
|
|
131963
|
+
getTextAnchor: "end",
|
|
131964
|
+
getAlignmentBaseline: "bottom",
|
|
131965
|
+
getPixelOffset: [-6, -6]
|
|
131966
|
+
}));
|
|
131967
|
+
} else if (shape2.type === "ellipse") {
|
|
131968
|
+
const cx = shape2.x1 ?? 0;
|
|
131969
|
+
const cy = shape2.y1 ?? 0;
|
|
131970
|
+
const ry = Math.abs(shape2.radiusY ?? 0);
|
|
131971
|
+
measureLayers.push(new TextLayer({
|
|
131972
|
+
...base,
|
|
131973
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
131974
|
+
data: [{ position: [cx, cy + ry], text: label }],
|
|
131975
|
+
getTextAnchor: "middle",
|
|
131976
|
+
getAlignmentBaseline: "top",
|
|
131977
|
+
getPixelOffset: [0, 8]
|
|
131978
|
+
}));
|
|
131979
|
+
} else if (shape2.type === "polygon" && shape2.points?.length >= 3) {
|
|
131980
|
+
const xs = shape2.points.map((p) => p[0]);
|
|
131981
|
+
const ys = shape2.points.map((p) => p[1]);
|
|
131982
|
+
const cx = (Math.min(...xs) + Math.max(...xs)) / 2;
|
|
131983
|
+
const maxY = Math.max(...ys);
|
|
131984
|
+
measureLayers.push(new TextLayer({
|
|
131985
|
+
...base,
|
|
131986
|
+
id: `annotation-measure-${shape2.uid}`,
|
|
131987
|
+
data: [{ position: [cx, maxY], text: label }],
|
|
131988
|
+
getTextAnchor: "middle",
|
|
131989
|
+
getAlignmentBaseline: "top",
|
|
131990
|
+
getPixelOffset: [0, 8]
|
|
131991
|
+
}));
|
|
131992
|
+
}
|
|
131993
|
+
});
|
|
131994
|
+
return [...selectionLayers, ...layers, ...measureLayers];
|
|
131995
|
+
}
|
|
131996
|
+
const defaultProps$1 = {
|
|
131997
|
+
// Array of annotation shape objects (see annotationShapeObj in @vitessce/schemas).
|
|
131998
|
+
data: { type: "object", value: [], compare: true },
|
|
131999
|
+
// UID of the shape to highlight with a selection halo.
|
|
132000
|
+
selectedShapeUid: { type: "string", value: null },
|
|
132001
|
+
// { x, y, unit } used to format measurement labels in physical units.
|
|
132002
|
+
physicalPixelSize: { type: "object", value: null, compare: true },
|
|
132003
|
+
// The zoom level at which the shapes were authored (reference for semantic zoom).
|
|
132004
|
+
authoredZoom: { type: "number", value: null },
|
|
132005
|
+
// Whether to apply semantic zoom (level-of-detail) based on authoredZoom.
|
|
132006
|
+
semanticZoom: { type: "boolean", value: true },
|
|
132007
|
+
// The view type in which the layer is rendered (affects measurement label formatting).
|
|
132008
|
+
viewType: { type: "string", value: ViewType$1.SPATIAL },
|
|
132009
|
+
// In-progress shape being drawn, as { type, vertices }.
|
|
132010
|
+
inProgressShape: { type: "object", value: null, compare: true },
|
|
132011
|
+
// Current mouse position (in data coordinates) while drawing.
|
|
132012
|
+
hoverCoord: { type: "array", value: null, compare: true },
|
|
132013
|
+
// Stroke color [r, g, b] of the in-progress shape preview.
|
|
132014
|
+
previewStrokeColor: { type: "color", value: [255, 255, 0] }
|
|
132015
|
+
};
|
|
132016
|
+
class AnnotationLayer extends CompositeLayer {
|
|
132017
|
+
// The semantic zoom and arrowhead sizes depend on the current zoom level,
|
|
132018
|
+
// so the sublayers must also be re-rendered when the viewport changes.
|
|
132019
|
+
// eslint-disable-next-line class-methods-use-this
|
|
132020
|
+
shouldUpdateState({ changeFlags }) {
|
|
132021
|
+
return changeFlags.propsOrDataChanged || changeFlags.viewportChanged;
|
|
132022
|
+
}
|
|
132023
|
+
/**
|
|
132024
|
+
* Prefix the sublayer ID with this layer's ID (so that multiple
|
|
132025
|
+
* AnnotationLayers can co-exist), and combine this layer's
|
|
132026
|
+
* opacity with the per-shape opacity of the sublayer.
|
|
132027
|
+
* Note: we avoid getSubLayerProps here, since it would
|
|
132028
|
+
* overwrite the sublayer extensions (e.g., PathStyleExtension)
|
|
132029
|
+
* and opacity values.
|
|
132030
|
+
* @param {object} layer A DeckGL layer instance.
|
|
132031
|
+
* @returns {object} The cloned layer instance.
|
|
132032
|
+
*/
|
|
132033
|
+
wrapSubLayer(layer) {
|
|
132034
|
+
const { id, opacity, pickable, visible } = this.props;
|
|
132035
|
+
return layer.clone({
|
|
132036
|
+
id: `${id}-${layer.id}`,
|
|
132037
|
+
opacity: layer.props.opacity * opacity,
|
|
132038
|
+
pickable,
|
|
132039
|
+
visible
|
|
132040
|
+
});
|
|
132041
|
+
}
|
|
132042
|
+
renderLayers() {
|
|
132043
|
+
const { data, selectedShapeUid, physicalPixelSize, authoredZoom, semanticZoom, viewType, inProgressShape, hoverCoord, previewStrokeColor } = this.props;
|
|
132044
|
+
const zoom = this.context.viewport?.zoom ?? 0;
|
|
132045
|
+
const visibleShapes = (data ?? []).filter((shape2) => shape2.visible !== false);
|
|
132046
|
+
const annotationLayers = createAnnotationLayers(visibleShapes, zoom, selectedShapeUid, physicalPixelSize, authoredZoom, semanticZoom, viewType);
|
|
132047
|
+
const previewLayer = createPreviewLayer(inProgressShape, hoverCoord, previewStrokeColor.slice(0, 3));
|
|
132048
|
+
return [
|
|
132049
|
+
...annotationLayers,
|
|
132050
|
+
...previewLayer ? [previewLayer] : []
|
|
132051
|
+
].map((layer) => this.wrapSubLayer(layer));
|
|
132052
|
+
}
|
|
132053
|
+
}
|
|
132054
|
+
AnnotationLayer.layerName = "AnnotationLayer";
|
|
132055
|
+
AnnotationLayer.defaultProps = defaultProps$1;
|
|
130687
132056
|
function r$1(e2) {
|
|
130688
132057
|
var t, f2, n2 = "";
|
|
130689
132058
|
if ("string" == typeof e2 || "number" == typeof e2) n2 += e2;
|
|
@@ -153601,11 +154970,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153601
154970
|
this.cellSetsLabelPrevZoom = null;
|
|
153602
154971
|
this.cellSetsLayers = [];
|
|
153603
154972
|
this.contourLayers = [];
|
|
154973
|
+
this.annotationLayer = null;
|
|
153604
154974
|
this.onUpdateCellsData();
|
|
153605
154975
|
this.onUpdateCellsLayer();
|
|
153606
154976
|
this.onUpdateCellSetsLayers();
|
|
153607
154977
|
this.onUpdateStratifiedData();
|
|
153608
154978
|
this.onUpdateContourLayers();
|
|
154979
|
+
this.onUpdateAnnotationLayer();
|
|
153609
154980
|
}
|
|
153610
154981
|
// Want to support multiple types of contour layers
|
|
153611
154982
|
// - One layer for all data points (no filtering)
|
|
@@ -153669,6 +155040,21 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153669
155040
|
}));
|
|
153670
155041
|
return layers;
|
|
153671
155042
|
}
|
|
155043
|
+
createAnnotationLayer() {
|
|
155044
|
+
const { annotationShapes, annotationOverlayVisible, annotationSemanticZoom, annotationShapeSelection } = this.props;
|
|
155045
|
+
return new AnnotationLayer({
|
|
155046
|
+
data: annotationShapes,
|
|
155047
|
+
visible: annotationOverlayVisible,
|
|
155048
|
+
semanticZoom: annotationSemanticZoom,
|
|
155049
|
+
selectedShapeUid: annotationShapeSelection,
|
|
155050
|
+
viewType: ViewType$1.SCATTERPLOT
|
|
155051
|
+
// TODO: is this needed?
|
|
155052
|
+
// TODO: these are view-level properties, rather than layer-level.
|
|
155053
|
+
// annotationTransitionDuration,
|
|
155054
|
+
// annotationEditable,
|
|
155055
|
+
// Other coordination types related to editing...
|
|
155056
|
+
});
|
|
155057
|
+
}
|
|
153672
155058
|
createCellsLayer() {
|
|
153673
155059
|
const {
|
|
153674
155060
|
obsEmbeddingIndex: obsIndex,
|
|
@@ -153802,12 +155188,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153802
155188
|
], flipYTooltip, this.props.onSelectionBusy);
|
|
153803
155189
|
}
|
|
153804
155190
|
getLayers() {
|
|
153805
|
-
const { cellsLayer, cellSetsLayers, contourLayers } = this;
|
|
155191
|
+
const { cellsLayer, cellSetsLayers, contourLayers, annotationLayer } = this;
|
|
153806
155192
|
return [
|
|
153807
155193
|
cellsLayer,
|
|
153808
155194
|
...contourLayers,
|
|
153809
155195
|
...cellSetsLayers,
|
|
153810
|
-
this.createSelectionLayer()
|
|
155196
|
+
this.createSelectionLayer(),
|
|
155197
|
+
annotationLayer
|
|
153811
155198
|
];
|
|
153812
155199
|
}
|
|
153813
155200
|
/**
|
|
@@ -153844,6 +155231,14 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153844
155231
|
this.cellsLayer = null;
|
|
153845
155232
|
}
|
|
153846
155233
|
}
|
|
155234
|
+
onUpdateAnnotationLayer() {
|
|
155235
|
+
const { annotationShapes } = this.props;
|
|
155236
|
+
if (annotationShapes) {
|
|
155237
|
+
this.annotationLayer = this.createAnnotationLayer();
|
|
155238
|
+
} else {
|
|
155239
|
+
this.annotationLayer = null;
|
|
155240
|
+
}
|
|
155241
|
+
}
|
|
153847
155242
|
onUpdateStratifiedData() {
|
|
153848
155243
|
const { stratifiedData } = this.props;
|
|
153849
155244
|
if (stratifiedData) {
|
|
@@ -153959,6 +155354,16 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153959
155354
|
this.onUpdateCellSetsLayers(true);
|
|
153960
155355
|
forceUpdate = true;
|
|
153961
155356
|
}
|
|
155357
|
+
if ([
|
|
155358
|
+
"annotationShapes",
|
|
155359
|
+
"annotationOverlayVisible",
|
|
155360
|
+
"annotationSemanticZoom",
|
|
155361
|
+
"annotationTransitionDuration",
|
|
155362
|
+
"annotationEditable"
|
|
155363
|
+
].some(shallowDiff)) {
|
|
155364
|
+
this.onUpdateAnnotationLayer();
|
|
155365
|
+
forceUpdate = true;
|
|
155366
|
+
}
|
|
153962
155367
|
if (forceUpdate) {
|
|
153963
155368
|
this.forceUpdate();
|
|
153964
155369
|
}
|