@vitessce/scatterplot-gating 4.0.8 → 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-LSUUttUX.js → deflate-DUmHvVPz.js} +1 -1
- package/dist/{index-Cz4-3Q5N.js → index-B-Adtek3.js} +1496 -97
- package/dist/index.js +1 -1
- package/dist/{jpeg-CT7-gAJ7.js → jpeg-DdAMSG2w.js} +1 -1
- package/dist/{lerc-CVzJtTuz.js → lerc-D4PnY1mB.js} +1 -1
- package/dist/{lzw-DFW6fqhq.js → lzw-BpQ8dLUH.js} +1 -1
- package/dist/{packbits-D_9HcbKf.js → packbits-Cb8CXJgl.js} +1 -1
- package/dist/{raw-DrK5oUaJ.js → raw-AvZwnBim.js} +1 -1
- package/dist/{webimage-D2nsaIi_.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({
|
|
@@ -9515,7 +9516,8 @@ const ViewType$1 = {
|
|
|
9515
9516
|
TREEMAP: "treemap",
|
|
9516
9517
|
SAMPLE_SET_PAIR_MANAGER: "sampleSetPairManager",
|
|
9517
9518
|
FEATURE_STATS_TABLE: "featureStatsTable",
|
|
9518
|
-
SINGLE_OBS_SET_SELECTOR: "singleObsSetSelector"
|
|
9519
|
+
SINGLE_OBS_SET_SELECTOR: "singleObsSetSelector",
|
|
9520
|
+
ANNOTATION_CONTROLLER: "annotationController"
|
|
9519
9521
|
};
|
|
9520
9522
|
const DataType$2 = {
|
|
9521
9523
|
OBS_LABELS: "obsLabels",
|
|
@@ -9536,7 +9538,8 @@ const DataType$2 = {
|
|
|
9536
9538
|
COMPARISON_METADATA: "comparisonMetadata",
|
|
9537
9539
|
FEATURE_STATS: "featureStats",
|
|
9538
9540
|
FEATURE_SET_STATS: "featureSetStats",
|
|
9539
|
-
OBS_SET_STATS: "obsSetStats"
|
|
9541
|
+
OBS_SET_STATS: "obsSetStats",
|
|
9542
|
+
ANNOTATION_STORY: "annotationStory"
|
|
9540
9543
|
};
|
|
9541
9544
|
const FileType$1 = {
|
|
9542
9545
|
// Joint file types
|
|
@@ -9558,6 +9561,7 @@ const FileType$1 = {
|
|
|
9558
9561
|
OBS_SETS_CSV: "obsSets.csv",
|
|
9559
9562
|
OBS_SETS_JSON: "obsSets.json",
|
|
9560
9563
|
SAMPLE_SETS_CSV: "sampleSets.csv",
|
|
9564
|
+
ANNOTATION_STORY_JSON: "annotationStory.json",
|
|
9561
9565
|
// OME-Zarr
|
|
9562
9566
|
IMAGE_OME_ZARR: "image.ome-zarr",
|
|
9563
9567
|
OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
|
|
@@ -9842,7 +9846,15 @@ const CoordinationType$1 = {
|
|
|
9842
9846
|
FEATURE_POINT_FOLD_CHANGE_THRESHOLD: "featurePointFoldChangeThreshold",
|
|
9843
9847
|
FEATURE_LABEL_FOLD_CHANGE_THRESHOLD: "featureLabelFoldChangeThreshold",
|
|
9844
9848
|
// Treemap
|
|
9845
|
-
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"
|
|
9846
9858
|
};
|
|
9847
9859
|
const ViewHelpMapping = {
|
|
9848
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."
|
|
@@ -9861,6 +9873,7 @@ const ViewHelpMapping = {
|
|
|
9861
9873
|
[FileType$1.OBS_SEGMENTATIONS_JSON]: DataType$2.OBS_SEGMENTATIONS,
|
|
9862
9874
|
[FileType$1.OBS_SETS_CSV]: DataType$2.OBS_SETS,
|
|
9863
9875
|
[FileType$1.OBS_SETS_JSON]: DataType$2.OBS_SETS,
|
|
9876
|
+
[FileType$1.ANNOTATION_STORY_JSON]: DataType$2.ANNOTATION_STORY,
|
|
9864
9877
|
[FileType$1.IMAGE_OME_ZARR]: DataType$2.IMAGE,
|
|
9865
9878
|
[FileType$1.OBS_SEGMENTATIONS_OME_ZARR]: DataType$2.OBS_SEGMENTATIONS,
|
|
9866
9879
|
[FileType$1.OBS_FEATURE_MATRIX_ANNDATA_ZARR]: DataType$2.OBS_FEATURE_MATRIX,
|
|
@@ -9983,7 +9996,8 @@ const ViewHelpMapping = {
|
|
|
9983
9996
|
[DataType$2.OBS_SET_STATS]: [
|
|
9984
9997
|
CoordinationType$1.OBS_TYPE
|
|
9985
9998
|
// TODO: should sampleType, obsSetSelection, and/or sampleSetSelection be used here?
|
|
9986
|
-
]
|
|
9999
|
+
],
|
|
10000
|
+
[DataType$2.ANNOTATION_STORY]: []
|
|
9987
10001
|
});
|
|
9988
10002
|
({
|
|
9989
10003
|
// For AnnData:
|
|
@@ -10116,7 +10130,9 @@ const ViewHelpMapping = {
|
|
|
10116
10130
|
CoordinationType$1.SPATIAL_TARGET_Z,
|
|
10117
10131
|
CoordinationType$1.SPATIAL_AXIS_FIXED,
|
|
10118
10132
|
CoordinationType$1.SPATIAL_ORBIT_AXIS,
|
|
10119
|
-
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
|
|
10120
10136
|
];
|
|
10121
10137
|
const COMPONENT_COORDINATION_TYPES = {
|
|
10122
10138
|
[ViewType$1.NEUROGLANCER]: [
|
|
@@ -10208,7 +10224,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10208
10224
|
CoordinationType$1.EMBEDDING_CONTOURS_FILLED,
|
|
10209
10225
|
CoordinationType$1.EMBEDDING_CONTOUR_PERCENTILES,
|
|
10210
10226
|
CoordinationType$1.CONTOUR_COLOR_ENCODING,
|
|
10211
|
-
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
|
|
10212
10235
|
],
|
|
10213
10236
|
[ViewType$1.DUAL_SCATTERPLOT]: [
|
|
10214
10237
|
CoordinationType$1.DATASET,
|
|
@@ -10324,7 +10347,14 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10324
10347
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
10325
10348
|
CoordinationType$1.MOLECULE_HIGHLIGHT,
|
|
10326
10349
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
10327
|
-
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
|
|
10328
10358
|
],
|
|
10329
10359
|
[ViewType$1.SPATIAL_BETA]: [
|
|
10330
10360
|
CoordinationType$1.META_COORDINATION_SCOPES,
|
|
@@ -10402,7 +10432,27 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10402
10432
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
10403
10433
|
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
10404
10434
|
CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER,
|
|
10405
|
-
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.
|
|
10406
10456
|
],
|
|
10407
10457
|
[ViewType$1.HEATMAP]: [
|
|
10408
10458
|
CoordinationType$1.DATASET,
|
|
@@ -11420,6 +11470,124 @@ z.object({
|
|
|
11420
11470
|
radius: z.number(),
|
|
11421
11471
|
opacity: z.number()
|
|
11422
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
|
+
});
|
|
11423
11591
|
const SETS_DATATYPE_OBS = "obs";
|
|
11424
11592
|
const HIERARCHICAL_SCHEMAS = {
|
|
11425
11593
|
latestVersion: "0.1.3"
|
|
@@ -24240,8 +24408,8 @@ class Vector extends MathArray {
|
|
|
24240
24408
|
distanceSquared(mathArray) {
|
|
24241
24409
|
let length2 = 0;
|
|
24242
24410
|
for (let i2 = 0; i2 < this.ELEMENTS; ++i2) {
|
|
24243
|
-
const
|
|
24244
|
-
length2 +=
|
|
24411
|
+
const dist2 = this[i2] - mathArray[i2];
|
|
24412
|
+
length2 += dist2 * dist2;
|
|
24245
24413
|
}
|
|
24246
24414
|
return checkNumber(length2);
|
|
24247
24415
|
}
|
|
@@ -24562,6 +24730,12 @@ function multiply$3(out, a2, b) {
|
|
|
24562
24730
|
out[2] = a2[2] * b[2];
|
|
24563
24731
|
return out;
|
|
24564
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
|
+
}
|
|
24565
24739
|
function squaredLength$2(a2) {
|
|
24566
24740
|
var x = a2[0];
|
|
24567
24741
|
var y = a2[1];
|
|
@@ -24685,6 +24859,7 @@ function angle$2(a2, b) {
|
|
|
24685
24859
|
}
|
|
24686
24860
|
var sub = subtract;
|
|
24687
24861
|
var mul = multiply$3;
|
|
24862
|
+
var dist = distance$3;
|
|
24688
24863
|
var len = length$5;
|
|
24689
24864
|
var sqrLen = squaredLength$2;
|
|
24690
24865
|
(function() {
|
|
@@ -39155,7 +39330,7 @@ function noop$4() {
|
|
|
39155
39330
|
const getCursor$1 = ({
|
|
39156
39331
|
isDragging
|
|
39157
39332
|
}) => isDragging ? "grabbing" : "grab";
|
|
39158
|
-
const defaultProps$
|
|
39333
|
+
const defaultProps$P = {
|
|
39159
39334
|
id: "",
|
|
39160
39335
|
width: "100%",
|
|
39161
39336
|
height: "100%",
|
|
@@ -39286,7 +39461,7 @@ class Deck {
|
|
|
39286
39461
|
this._lastPointerDownInfo = pickedInfo.result[0] || pickedInfo.emptyInfo;
|
|
39287
39462
|
});
|
|
39288
39463
|
this.props = {
|
|
39289
|
-
...defaultProps$
|
|
39464
|
+
...defaultProps$P,
|
|
39290
39465
|
...props
|
|
39291
39466
|
};
|
|
39292
39467
|
props = this.props;
|
|
@@ -39788,7 +39963,7 @@ class Deck {
|
|
|
39788
39963
|
metrics.gpuMemory = memoryStats.get("GPU Memory").count;
|
|
39789
39964
|
}
|
|
39790
39965
|
}
|
|
39791
|
-
_defineProperty(Deck, "defaultProps", defaultProps$
|
|
39966
|
+
_defineProperty(Deck, "defaultProps", defaultProps$P);
|
|
39792
39967
|
_defineProperty(Deck, "VERSION", deckGlobal.VERSION);
|
|
39793
39968
|
class ShaderAttribute {
|
|
39794
39969
|
constructor(dataColumn, opts) {
|
|
@@ -42543,7 +42718,7 @@ const areViewportsEqual = memoize$3(({
|
|
|
42543
42718
|
return oldViewport.equals(viewport);
|
|
42544
42719
|
});
|
|
42545
42720
|
let pickingColorCache = new Uint8ClampedArray(0);
|
|
42546
|
-
const defaultProps$
|
|
42721
|
+
const defaultProps$O = {
|
|
42547
42722
|
data: {
|
|
42548
42723
|
type: "data",
|
|
42549
42724
|
value: EMPTY_ARRAY$1,
|
|
@@ -43418,7 +43593,7 @@ class Layer extends Component {
|
|
|
43418
43593
|
this.setNeedsUpdate();
|
|
43419
43594
|
}
|
|
43420
43595
|
}
|
|
43421
|
-
_defineProperty(Layer, "defaultProps", defaultProps$
|
|
43596
|
+
_defineProperty(Layer, "defaultProps", defaultProps$O);
|
|
43422
43597
|
_defineProperty(Layer, "layerName", "Layer");
|
|
43423
43598
|
const TRACE_RENDER_LAYERS = "compositeLayer.renderLayers";
|
|
43424
43599
|
class CompositeLayer extends Layer {
|
|
@@ -44454,6 +44629,124 @@ const esm$5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
44454
44629
|
project32,
|
|
44455
44630
|
shadow
|
|
44456
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");
|
|
44457
44750
|
const defaultProps$M = {
|
|
44458
44751
|
clipBounds: [0, 0, 1, 1]
|
|
44459
44752
|
};
|
|
@@ -100541,8 +100834,8 @@ function requireJs$b() {
|
|
|
100541
100834
|
var DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi12 / 2 + Math.PI / 4));
|
|
100542
100835
|
var q = Math.abs(DeltaPsi) > 1e-11 ? DeltaPhi / DeltaPsi : Math.cos(phi12);
|
|
100543
100836
|
var delta = Math.sqrt(DeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda);
|
|
100544
|
-
var
|
|
100545
|
-
return
|
|
100837
|
+
var dist2 = delta * R;
|
|
100838
|
+
return dist2;
|
|
100546
100839
|
}
|
|
100547
100840
|
js$a.default = rhumbDistance;
|
|
100548
100841
|
return js$a;
|
|
@@ -100855,7 +101148,7 @@ function requireUtils$2() {
|
|
|
100855
101148
|
var x;
|
|
100856
101149
|
var y;
|
|
100857
101150
|
var segmentIdx;
|
|
100858
|
-
var
|
|
101151
|
+
var dist2;
|
|
100859
101152
|
if (coords.length > 1 && pointCoords.length) {
|
|
100860
101153
|
var lineCoordinates;
|
|
100861
101154
|
var pointCoordinate;
|
|
@@ -100872,17 +101165,17 @@ function requireUtils$2() {
|
|
|
100872
101165
|
if (lineCoordinates[n2][0] !== lineCoordinates[n2 - 1][0]) {
|
|
100873
101166
|
var slope = (lineCoordinates[n2][1] - lineCoordinates[n2 - 1][1]) / (lineCoordinates[n2][0] - lineCoordinates[n2 - 1][0]);
|
|
100874
101167
|
var inverseSlope = lineCoordinates[n2][1] - slope * lineCoordinates[n2][0];
|
|
100875
|
-
|
|
100876
|
-
} 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]);
|
|
100877
101170
|
var rl2 = Math.pow(lineCoordinates[n2][1] - lineCoordinates[n2 - 1][1], 2) + Math.pow(lineCoordinates[n2][0] - lineCoordinates[n2 - 1][0], 2);
|
|
100878
101171
|
var ln2 = Math.pow(lineCoordinates[n2][1] - pointCoordinate[1], 2) + Math.pow(lineCoordinates[n2][0] - pointCoordinate[0], 2);
|
|
100879
101172
|
var lnm12 = Math.pow(lineCoordinates[n2 - 1][1] - pointCoordinate[1], 2) + Math.pow(lineCoordinates[n2 - 1][0] - pointCoordinate[0], 2);
|
|
100880
|
-
var
|
|
100881
|
-
var calcrl2 = ln2 -
|
|
101173
|
+
var dist22 = Math.pow(dist2, 2);
|
|
101174
|
+
var calcrl2 = ln2 - dist22 + lnm12 - dist22;
|
|
100882
101175
|
if (calcrl2 > rl2) {
|
|
100883
|
-
|
|
101176
|
+
dist2 = Math.sqrt(Math.min(ln2, lnm12));
|
|
100884
101177
|
}
|
|
100885
|
-
if (minDist === null || minDist === void 0 || minDist >
|
|
101178
|
+
if (minDist === null || minDist === void 0 || minDist > dist2) {
|
|
100886
101179
|
if (calcrl2 > rl2) {
|
|
100887
101180
|
if (lnm12 < ln2) {
|
|
100888
101181
|
to = 0;
|
|
@@ -100892,10 +101185,10 @@ function requireUtils$2() {
|
|
|
100892
101185
|
to = 1;
|
|
100893
101186
|
}
|
|
100894
101187
|
} else {
|
|
100895
|
-
to = Math.sqrt(lnm12 -
|
|
100896
|
-
from2 = Math.sqrt(ln2 -
|
|
101188
|
+
to = Math.sqrt(lnm12 - dist22) / Math.sqrt(rl2);
|
|
101189
|
+
from2 = Math.sqrt(ln2 - dist22) / Math.sqrt(rl2);
|
|
100897
101190
|
}
|
|
100898
|
-
minDist =
|
|
101191
|
+
minDist = dist2;
|
|
100899
101192
|
segmentIdx = n2;
|
|
100900
101193
|
}
|
|
100901
101194
|
}
|
|
@@ -117226,22 +117519,22 @@ function addDecoder(cases, importFn) {
|
|
|
117226
117519
|
}
|
|
117227
117520
|
cases.forEach((c2) => registry$1.set(c2, importFn));
|
|
117228
117521
|
}
|
|
117229
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
117230
|
-
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));
|
|
117231
117524
|
addDecoder(6, () => {
|
|
117232
117525
|
throw new Error("old style JPEG compression is not supported.");
|
|
117233
117526
|
});
|
|
117234
|
-
addDecoder(7, () => import("./jpeg-
|
|
117235
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
117236
|
-
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));
|
|
117237
117530
|
addDecoder(
|
|
117238
117531
|
34887,
|
|
117239
|
-
() => import("./lerc-
|
|
117532
|
+
() => import("./lerc-D4PnY1mB.js").then(async (m2) => {
|
|
117240
117533
|
await m2.zstd.init();
|
|
117241
117534
|
return m2;
|
|
117242
117535
|
}).then((m2) => m2.default)
|
|
117243
117536
|
);
|
|
117244
|
-
addDecoder(50001, () => import("./webimage-
|
|
117537
|
+
addDecoder(50001, () => import("./webimage-Di-764UM.js").then((m2) => m2.default));
|
|
117245
117538
|
function decodeRowAcc(row, stride) {
|
|
117246
117539
|
let length2 = row.length - stride;
|
|
117247
117540
|
let offset2 = 0;
|
|
@@ -117656,8 +117949,8 @@ function TreeDesc(dyn_tree, stat_desc) {
|
|
|
117656
117949
|
this.max_code = 0;
|
|
117657
117950
|
this.stat_desc = stat_desc;
|
|
117658
117951
|
}
|
|
117659
|
-
const d_code = (
|
|
117660
|
-
return
|
|
117952
|
+
const d_code = (dist2) => {
|
|
117953
|
+
return dist2 < 256 ? _dist_code[dist2] : _dist_code[256 + (dist2 >>> 7)];
|
|
117661
117954
|
};
|
|
117662
117955
|
const put_short = (s2, w2) => {
|
|
117663
117956
|
s2.pending_buf[s2.pending++] = w2 & 255;
|
|
@@ -117791,7 +118084,7 @@ const tr_static_init = () => {
|
|
|
117791
118084
|
let bits;
|
|
117792
118085
|
let length2;
|
|
117793
118086
|
let code;
|
|
117794
|
-
let
|
|
118087
|
+
let dist2;
|
|
117795
118088
|
const bl_count = new Array(MAX_BITS + 1);
|
|
117796
118089
|
length2 = 0;
|
|
117797
118090
|
for (code = 0; code < LENGTH_CODES - 1; code++) {
|
|
@@ -117801,18 +118094,18 @@ const tr_static_init = () => {
|
|
|
117801
118094
|
}
|
|
117802
118095
|
}
|
|
117803
118096
|
_length_code[length2 - 1] = code;
|
|
117804
|
-
|
|
118097
|
+
dist2 = 0;
|
|
117805
118098
|
for (code = 0; code < 16; code++) {
|
|
117806
|
-
base_dist[code] =
|
|
118099
|
+
base_dist[code] = dist2;
|
|
117807
118100
|
for (n2 = 0; n2 < 1 << extra_dbits[code]; n2++) {
|
|
117808
|
-
_dist_code[
|
|
118101
|
+
_dist_code[dist2++] = code;
|
|
117809
118102
|
}
|
|
117810
118103
|
}
|
|
117811
|
-
|
|
118104
|
+
dist2 >>= 7;
|
|
117812
118105
|
for (; code < D_CODES; code++) {
|
|
117813
|
-
base_dist[code] =
|
|
118106
|
+
base_dist[code] = dist2 << 7;
|
|
117814
118107
|
for (n2 = 0; n2 < 1 << extra_dbits[code] - 7; n2++) {
|
|
117815
|
-
_dist_code[256 +
|
|
118108
|
+
_dist_code[256 + dist2++] = code;
|
|
117816
118109
|
}
|
|
117817
118110
|
}
|
|
117818
118111
|
for (bits = 0; bits <= MAX_BITS; bits++) {
|
|
@@ -117903,17 +118196,17 @@ const pqdownheap = (s2, tree, k) => {
|
|
|
117903
118196
|
s2.heap[k] = v;
|
|
117904
118197
|
};
|
|
117905
118198
|
const compress_block = (s2, ltree, dtree) => {
|
|
117906
|
-
let
|
|
118199
|
+
let dist2;
|
|
117907
118200
|
let lc;
|
|
117908
118201
|
let lx = 0;
|
|
117909
118202
|
let code;
|
|
117910
118203
|
let extra;
|
|
117911
118204
|
if (s2.last_lit !== 0) {
|
|
117912
118205
|
do {
|
|
117913
|
-
|
|
118206
|
+
dist2 = s2.pending_buf[s2.d_buf + lx * 2] << 8 | s2.pending_buf[s2.d_buf + lx * 2 + 1];
|
|
117914
118207
|
lc = s2.pending_buf[s2.l_buf + lx];
|
|
117915
118208
|
lx++;
|
|
117916
|
-
if (
|
|
118209
|
+
if (dist2 === 0) {
|
|
117917
118210
|
send_code(s2, lc, ltree);
|
|
117918
118211
|
} else {
|
|
117919
118212
|
code = _length_code[lc];
|
|
@@ -117923,13 +118216,13 @@ const compress_block = (s2, ltree, dtree) => {
|
|
|
117923
118216
|
lc -= base_length[code];
|
|
117924
118217
|
send_bits(s2, lc, extra);
|
|
117925
118218
|
}
|
|
117926
|
-
|
|
117927
|
-
code = d_code(
|
|
118219
|
+
dist2--;
|
|
118220
|
+
code = d_code(dist2);
|
|
117928
118221
|
send_code(s2, code, dtree);
|
|
117929
118222
|
extra = extra_dbits[code];
|
|
117930
118223
|
if (extra !== 0) {
|
|
117931
|
-
|
|
117932
|
-
send_bits(s2,
|
|
118224
|
+
dist2 -= base_dist[code];
|
|
118225
|
+
send_bits(s2, dist2, extra);
|
|
117933
118226
|
}
|
|
117934
118227
|
}
|
|
117935
118228
|
} while (lx < s2.last_lit);
|
|
@@ -118200,18 +118493,18 @@ const _tr_flush_block = (s2, buf, stored_len, last) => {
|
|
|
118200
118493
|
bi_windup(s2);
|
|
118201
118494
|
}
|
|
118202
118495
|
};
|
|
118203
|
-
const _tr_tally = (s2,
|
|
118204
|
-
s2.pending_buf[s2.d_buf + s2.last_lit * 2] =
|
|
118205
|
-
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;
|
|
118206
118499
|
s2.pending_buf[s2.l_buf + s2.last_lit] = lc & 255;
|
|
118207
118500
|
s2.last_lit++;
|
|
118208
|
-
if (
|
|
118501
|
+
if (dist2 === 0) {
|
|
118209
118502
|
s2.dyn_ltree[lc * 2]++;
|
|
118210
118503
|
} else {
|
|
118211
118504
|
s2.matches++;
|
|
118212
|
-
|
|
118505
|
+
dist2--;
|
|
118213
118506
|
s2.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]++;
|
|
118214
|
-
s2.dyn_dtree[d_code(
|
|
118507
|
+
s2.dyn_dtree[d_code(dist2) * 2]++;
|
|
118215
118508
|
}
|
|
118216
118509
|
return s2.last_lit === s2.lit_bufsize - 1;
|
|
118217
118510
|
};
|
|
@@ -119716,7 +120009,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119716
120009
|
let here;
|
|
119717
120010
|
let op;
|
|
119718
120011
|
let len2;
|
|
119719
|
-
let
|
|
120012
|
+
let dist2;
|
|
119720
120013
|
let from2;
|
|
119721
120014
|
let from_source;
|
|
119722
120015
|
let input, output;
|
|
@@ -119782,7 +120075,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119782
120075
|
bits -= op;
|
|
119783
120076
|
op = here >>> 16 & 255;
|
|
119784
120077
|
if (op & 16) {
|
|
119785
|
-
|
|
120078
|
+
dist2 = here & 65535;
|
|
119786
120079
|
op &= 15;
|
|
119787
120080
|
if (bits < op) {
|
|
119788
120081
|
hold += input[_in++] << bits;
|
|
@@ -119792,8 +120085,8 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119792
120085
|
bits += 8;
|
|
119793
120086
|
}
|
|
119794
120087
|
}
|
|
119795
|
-
|
|
119796
|
-
if (
|
|
120088
|
+
dist2 += hold & (1 << op) - 1;
|
|
120089
|
+
if (dist2 > dmax) {
|
|
119797
120090
|
strm.msg = "invalid distance too far back";
|
|
119798
120091
|
state.mode = BAD;
|
|
119799
120092
|
break top;
|
|
@@ -119801,8 +120094,8 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119801
120094
|
hold >>>= op;
|
|
119802
120095
|
bits -= op;
|
|
119803
120096
|
op = _out - beg;
|
|
119804
|
-
if (
|
|
119805
|
-
op =
|
|
120097
|
+
if (dist2 > op) {
|
|
120098
|
+
op = dist2 - op;
|
|
119806
120099
|
if (op > whave) {
|
|
119807
120100
|
if (state.sane) {
|
|
119808
120101
|
strm.msg = "invalid distance too far back";
|
|
@@ -119819,7 +120112,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119819
120112
|
do {
|
|
119820
120113
|
output[_out++] = s_window[from2++];
|
|
119821
120114
|
} while (--op);
|
|
119822
|
-
from2 = _out -
|
|
120115
|
+
from2 = _out - dist2;
|
|
119823
120116
|
from_source = output;
|
|
119824
120117
|
}
|
|
119825
120118
|
} else if (wnext < op) {
|
|
@@ -119837,7 +120130,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119837
120130
|
do {
|
|
119838
120131
|
output[_out++] = s_window[from2++];
|
|
119839
120132
|
} while (--op);
|
|
119840
|
-
from2 = _out -
|
|
120133
|
+
from2 = _out - dist2;
|
|
119841
120134
|
from_source = output;
|
|
119842
120135
|
}
|
|
119843
120136
|
}
|
|
@@ -119848,7 +120141,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119848
120141
|
do {
|
|
119849
120142
|
output[_out++] = s_window[from2++];
|
|
119850
120143
|
} while (--op);
|
|
119851
|
-
from2 = _out -
|
|
120144
|
+
from2 = _out - dist2;
|
|
119852
120145
|
from_source = output;
|
|
119853
120146
|
}
|
|
119854
120147
|
}
|
|
@@ -119865,7 +120158,7 @@ var inffast = function inflate_fast(strm, start) {
|
|
|
119865
120158
|
}
|
|
119866
120159
|
}
|
|
119867
120160
|
} else {
|
|
119868
|
-
from2 = _out -
|
|
120161
|
+
from2 = _out - dist2;
|
|
119869
120162
|
do {
|
|
119870
120163
|
output[_out++] = output[from2++];
|
|
119871
120164
|
output[_out++] = output[from2++];
|
|
@@ -120423,7 +120716,7 @@ const fixedtables = (state) => {
|
|
|
120423
120716
|
state.distbits = 5;
|
|
120424
120717
|
};
|
|
120425
120718
|
const updatewindow = (strm, src, end, copy2) => {
|
|
120426
|
-
let
|
|
120719
|
+
let dist2;
|
|
120427
120720
|
const state = strm.state;
|
|
120428
120721
|
if (state.window === null) {
|
|
120429
120722
|
state.wsize = 1 << state.wbits;
|
|
@@ -120436,23 +120729,23 @@ const updatewindow = (strm, src, end, copy2) => {
|
|
|
120436
120729
|
state.wnext = 0;
|
|
120437
120730
|
state.whave = state.wsize;
|
|
120438
120731
|
} else {
|
|
120439
|
-
|
|
120440
|
-
if (
|
|
120441
|
-
|
|
120732
|
+
dist2 = state.wsize - state.wnext;
|
|
120733
|
+
if (dist2 > copy2) {
|
|
120734
|
+
dist2 = copy2;
|
|
120442
120735
|
}
|
|
120443
|
-
state.window.set(src.subarray(end - copy2, end - copy2 +
|
|
120444
|
-
copy2 -=
|
|
120736
|
+
state.window.set(src.subarray(end - copy2, end - copy2 + dist2), state.wnext);
|
|
120737
|
+
copy2 -= dist2;
|
|
120445
120738
|
if (copy2) {
|
|
120446
120739
|
state.window.set(src.subarray(end - copy2, end), 0);
|
|
120447
120740
|
state.wnext = copy2;
|
|
120448
120741
|
state.whave = state.wsize;
|
|
120449
120742
|
} else {
|
|
120450
|
-
state.wnext +=
|
|
120743
|
+
state.wnext += dist2;
|
|
120451
120744
|
if (state.wnext === state.wsize) {
|
|
120452
120745
|
state.wnext = 0;
|
|
120453
120746
|
}
|
|
120454
120747
|
if (state.whave < state.wsize) {
|
|
120455
|
-
state.whave +=
|
|
120748
|
+
state.whave += dist2;
|
|
120456
120749
|
}
|
|
120457
120750
|
}
|
|
120458
120751
|
}
|
|
@@ -124331,14 +124624,14 @@ vec4 colormap(float intensity) {
|
|
|
124331
124624
|
}
|
|
124332
124625
|
};
|
|
124333
124626
|
}
|
|
124334
|
-
const defaultProps$4$
|
|
124627
|
+
const defaultProps$4$2 = {
|
|
124335
124628
|
colormap: { type: "string", value: "viridis", compare: true },
|
|
124336
124629
|
opacity: { type: "number", value: 1, compare: true },
|
|
124337
124630
|
useTransparentColor: { type: "boolean", value: false, compare: true }
|
|
124338
124631
|
};
|
|
124339
124632
|
const AdditiveColormapExtension = class extends LayerExtension {
|
|
124340
124633
|
getShaders() {
|
|
124341
|
-
const name2 = this?.props?.colormap || defaultProps$4$
|
|
124634
|
+
const name2 = this?.props?.colormap || defaultProps$4$2.colormap.value;
|
|
124342
124635
|
const apply_cmap = cmaps[name2];
|
|
124343
124636
|
if (!apply_cmap) {
|
|
124344
124637
|
throw Error(`No colormap named ${name2} found in registry`);
|
|
@@ -124357,8 +124650,8 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
124357
124650
|
}
|
|
124358
124651
|
draw() {
|
|
124359
124652
|
const {
|
|
124360
|
-
useTransparentColor = defaultProps$4$
|
|
124361
|
-
opacity = defaultProps$4$
|
|
124653
|
+
useTransparentColor = defaultProps$4$2.useTransparentColor.value,
|
|
124654
|
+
opacity = defaultProps$4$2.opacity.value
|
|
124362
124655
|
} = this.props;
|
|
124363
124656
|
const uniforms = {
|
|
124364
124657
|
opacity,
|
|
@@ -124368,7 +124661,7 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
124368
124661
|
}
|
|
124369
124662
|
};
|
|
124370
124663
|
AdditiveColormapExtension.extensionName = "AdditiveColormapExtension";
|
|
124371
|
-
AdditiveColormapExtension.defaultProps = defaultProps$4$
|
|
124664
|
+
AdditiveColormapExtension.defaultProps = defaultProps$4$2;
|
|
124372
124665
|
const fs$1$2 = `uniform vec3 transparentColor;
|
|
124373
124666
|
uniform bool useTransparentColor;
|
|
124374
124667
|
uniform float opacity;
|
|
@@ -125661,7 +125954,7 @@ const ImageLayer = class extends CompositeLayer {
|
|
|
125661
125954
|
};
|
|
125662
125955
|
ImageLayer.layerName = "ImageLayer";
|
|
125663
125956
|
ImageLayer.defaultProps = defaultProps$5;
|
|
125664
|
-
const defaultProps$4 = {
|
|
125957
|
+
const defaultProps$4$1 = {
|
|
125665
125958
|
pickable: { type: "boolean", value: true, compare: true },
|
|
125666
125959
|
onHover: { type: "function", value: null, compare: false },
|
|
125667
125960
|
contrastLimits: { type: "array", value: [], compare: true },
|
|
@@ -125773,7 +126066,7 @@ const MultiscaleImageLayer = class extends CompositeLayer {
|
|
|
125773
126066
|
}
|
|
125774
126067
|
};
|
|
125775
126068
|
MultiscaleImageLayer.layerName = "MultiscaleImageLayer";
|
|
125776
|
-
MultiscaleImageLayer.defaultProps = defaultProps$4;
|
|
126069
|
+
MultiscaleImageLayer.defaultProps = defaultProps$4$1;
|
|
125777
126070
|
const defaultProps$3$1 = {
|
|
125778
126071
|
pickable: { type: "boolean", value: true, compare: true },
|
|
125779
126072
|
loader: {
|
|
@@ -126849,7 +127142,7 @@ function padWithDefault$1(arr, defaultValue2, padWidth) {
|
|
|
126849
127142
|
}
|
|
126850
127143
|
return newArr;
|
|
126851
127144
|
}
|
|
126852
|
-
const defaultProps$
|
|
127145
|
+
const defaultProps$4 = {
|
|
126853
127146
|
hoveredCell: { type: "number", value: null, compare: true },
|
|
126854
127147
|
// We do not want to deep-compare cellColorData,
|
|
126855
127148
|
// as it is potentially a TypedArray with millions of elements.
|
|
@@ -126966,7 +127259,7 @@ let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
|
|
|
126966
127259
|
}
|
|
126967
127260
|
};
|
|
126968
127261
|
BitmaskLayer$1.layerName = "BitmaskLayer";
|
|
126969
|
-
BitmaskLayer$1.defaultProps = defaultProps$
|
|
127262
|
+
BitmaskLayer$1.defaultProps = defaultProps$4;
|
|
126970
127263
|
const vs = `
|
|
126971
127264
|
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
126972
127265
|
|
|
@@ -127308,7 +127601,7 @@ function isEqualShallow(prevArr, nextArr) {
|
|
|
127308
127601
|
}
|
|
127309
127602
|
return prevArr === nextArr;
|
|
127310
127603
|
}
|
|
127311
|
-
const defaultProps$
|
|
127604
|
+
const defaultProps$3 = {
|
|
127312
127605
|
channelStrokeWidths: { type: "array", value: null, compare: true },
|
|
127313
127606
|
channelsFilled: { type: "array", value: null, compare: true },
|
|
127314
127607
|
channelOpacities: { type: "array", value: null, compare: true },
|
|
@@ -127572,7 +127865,7 @@ class BitmaskLayer2 extends XRLayer {
|
|
|
127572
127865
|
}
|
|
127573
127866
|
}
|
|
127574
127867
|
BitmaskLayer2.layerName = "BitmaskLayer";
|
|
127575
|
-
BitmaskLayer2.defaultProps = defaultProps$
|
|
127868
|
+
BitmaskLayer2.defaultProps = defaultProps$3;
|
|
127576
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;
|
|
127577
127870
|
function clone(configObject) {
|
|
127578
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 = {
|
|
@@ -130515,7 +130808,7 @@ function ringArea(coords) {
|
|
|
130515
130808
|
return total * FACTOR;
|
|
130516
130809
|
}
|
|
130517
130810
|
const DEFAULT_THRESHOLD = 1;
|
|
130518
|
-
const defaultProps$
|
|
130811
|
+
const defaultProps$2 = {
|
|
130519
130812
|
// for text
|
|
130520
130813
|
obsSetPath: { type: "object" },
|
|
130521
130814
|
sampleSetPath: { type: "object" },
|
|
@@ -130610,9 +130903,9 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
130610
130903
|
const circlePoint = point(circleCoord);
|
|
130611
130904
|
polygonVertices.forEach((polyCoord) => {
|
|
130612
130905
|
const polyPoint = point(polyCoord);
|
|
130613
|
-
const
|
|
130614
|
-
if (
|
|
130615
|
-
minDist =
|
|
130906
|
+
const dist2 = distance$1(circlePoint, polyPoint);
|
|
130907
|
+
if (dist2 < minDist) {
|
|
130908
|
+
minDist = dist2;
|
|
130616
130909
|
minCirclePoint = circleCoord;
|
|
130617
130910
|
minCirclePointI = circlePointI;
|
|
130618
130911
|
minPolygonPoint = polyCoord;
|
|
@@ -130689,7 +130982,1077 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
130689
130982
|
}
|
|
130690
130983
|
}
|
|
130691
130984
|
ContourLayerWithText.layerName = "ContourLayerWithText";
|
|
130692
|
-
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;
|
|
130693
132056
|
function r$1(e2) {
|
|
130694
132057
|
var t, f2, n2 = "";
|
|
130695
132058
|
if ("string" == typeof e2 || "number" == typeof e2) n2 += e2;
|
|
@@ -153607,11 +154970,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153607
154970
|
this.cellSetsLabelPrevZoom = null;
|
|
153608
154971
|
this.cellSetsLayers = [];
|
|
153609
154972
|
this.contourLayers = [];
|
|
154973
|
+
this.annotationLayer = null;
|
|
153610
154974
|
this.onUpdateCellsData();
|
|
153611
154975
|
this.onUpdateCellsLayer();
|
|
153612
154976
|
this.onUpdateCellSetsLayers();
|
|
153613
154977
|
this.onUpdateStratifiedData();
|
|
153614
154978
|
this.onUpdateContourLayers();
|
|
154979
|
+
this.onUpdateAnnotationLayer();
|
|
153615
154980
|
}
|
|
153616
154981
|
// Want to support multiple types of contour layers
|
|
153617
154982
|
// - One layer for all data points (no filtering)
|
|
@@ -153675,6 +155040,21 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153675
155040
|
}));
|
|
153676
155041
|
return layers;
|
|
153677
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
|
+
}
|
|
153678
155058
|
createCellsLayer() {
|
|
153679
155059
|
const {
|
|
153680
155060
|
obsEmbeddingIndex: obsIndex,
|
|
@@ -153808,12 +155188,13 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153808
155188
|
], flipYTooltip, this.props.onSelectionBusy);
|
|
153809
155189
|
}
|
|
153810
155190
|
getLayers() {
|
|
153811
|
-
const { cellsLayer, cellSetsLayers, contourLayers } = this;
|
|
155191
|
+
const { cellsLayer, cellSetsLayers, contourLayers, annotationLayer } = this;
|
|
153812
155192
|
return [
|
|
153813
155193
|
cellsLayer,
|
|
153814
155194
|
...contourLayers,
|
|
153815
155195
|
...cellSetsLayers,
|
|
153816
|
-
this.createSelectionLayer()
|
|
155196
|
+
this.createSelectionLayer(),
|
|
155197
|
+
annotationLayer
|
|
153817
155198
|
];
|
|
153818
155199
|
}
|
|
153819
155200
|
/**
|
|
@@ -153850,6 +155231,14 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153850
155231
|
this.cellsLayer = null;
|
|
153851
155232
|
}
|
|
153852
155233
|
}
|
|
155234
|
+
onUpdateAnnotationLayer() {
|
|
155235
|
+
const { annotationShapes } = this.props;
|
|
155236
|
+
if (annotationShapes) {
|
|
155237
|
+
this.annotationLayer = this.createAnnotationLayer();
|
|
155238
|
+
} else {
|
|
155239
|
+
this.annotationLayer = null;
|
|
155240
|
+
}
|
|
155241
|
+
}
|
|
153853
155242
|
onUpdateStratifiedData() {
|
|
153854
155243
|
const { stratifiedData } = this.props;
|
|
153855
155244
|
if (stratifiedData) {
|
|
@@ -153965,6 +155354,16 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
153965
155354
|
this.onUpdateCellSetsLayers(true);
|
|
153966
155355
|
forceUpdate = true;
|
|
153967
155356
|
}
|
|
155357
|
+
if ([
|
|
155358
|
+
"annotationShapes",
|
|
155359
|
+
"annotationOverlayVisible",
|
|
155360
|
+
"annotationSemanticZoom",
|
|
155361
|
+
"annotationTransitionDuration",
|
|
155362
|
+
"annotationEditable"
|
|
155363
|
+
].some(shallowDiff)) {
|
|
155364
|
+
this.onUpdateAnnotationLayer();
|
|
155365
|
+
forceUpdate = true;
|
|
155366
|
+
}
|
|
153968
155367
|
if (forceUpdate) {
|
|
153969
155368
|
this.forceUpdate();
|
|
153970
155369
|
}
|