@equinor/esv-intersection 3.0.1 → 3.0.4

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.
Files changed (109) hide show
  1. package/dist/index.cjs +2 -2
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.mjs +2241 -1938
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/index.umd.js +2 -2
  6. package/dist/index.umd.js.map +1 -1
  7. package/package.json +21 -22
  8. package/dist/components/axis.d.ts +0 -47
  9. package/dist/components/index.d.ts +0 -1
  10. package/dist/control/ExtendedCurveInterpolator.d.ts +0 -58
  11. package/dist/control/IntersectionReferenceSystem.d.ts +0 -96
  12. package/dist/control/LayerManager.d.ts +0 -76
  13. package/dist/control/MainController.d.ts +0 -154
  14. package/dist/control/ZoomPanHandler.d.ts +0 -158
  15. package/dist/control/index.d.ts +0 -5
  16. package/dist/control/interfaces.d.ts +0 -37
  17. package/dist/control/overlay.d.ts +0 -20
  18. package/dist/datautils/colortable.d.ts +0 -1
  19. package/dist/datautils/findsample.d.ts +0 -2
  20. package/dist/datautils/index.d.ts +0 -6
  21. package/dist/datautils/interfaces.d.ts +0 -63
  22. package/dist/datautils/picks.d.ts +0 -74
  23. package/dist/datautils/schematicShapeGenerator.d.ts +0 -59
  24. package/dist/datautils/seismicimage.d.ts +0 -45
  25. package/dist/datautils/surfacedata.d.ts +0 -10
  26. package/dist/datautils/trajectory.d.ts +0 -14
  27. package/dist/layers/CalloutCanvasLayer.d.ts +0 -60
  28. package/dist/layers/CustomDisplayObjects/ComplexRope.d.ts +0 -22
  29. package/dist/layers/CustomDisplayObjects/ComplexRopeGeometry.d.ts +0 -27
  30. package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRope.d.ts +0 -20
  31. package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.d.ts +0 -26
  32. package/dist/layers/CustomDisplayObjects/UniformTextureStretchRope.d.ts +0 -17
  33. package/dist/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.d.ts +0 -24
  34. package/dist/layers/GeomodelCanvasLayer.d.ts +0 -28
  35. package/dist/layers/GeomodelLabelsLayer.d.ts +0 -49
  36. package/dist/layers/GeomodelLayerV2.d.ts +0 -12
  37. package/dist/layers/GridLayer.d.ts +0 -29
  38. package/dist/layers/ImageCanvasLayer.d.ts +0 -20
  39. package/dist/layers/ReferenceLineLayer.d.ts +0 -29
  40. package/dist/layers/SchematicLayer.d.ts +0 -113
  41. package/dist/layers/SeismicCanvasLayer.d.ts +0 -18
  42. package/dist/layers/WellborePathLayer.d.ts +0 -17
  43. package/dist/layers/base/CanvasLayer.d.ts +0 -19
  44. package/dist/layers/base/HTMLLayer.d.ts +0 -13
  45. package/dist/layers/base/Layer.d.ts +0 -69
  46. package/dist/layers/base/PixiLayer.d.ts +0 -32
  47. package/dist/layers/base/SVGLayer.d.ts +0 -13
  48. package/dist/layers/base/index.d.ts +0 -5
  49. package/dist/layers/index.d.ts +0 -16
  50. package/dist/layers/schematicInterfaces.d.ts +0 -208
  51. package/dist/utils/arc-length.d.ts +0 -23
  52. package/dist/utils/binary-search.d.ts +0 -8
  53. package/dist/utils/color.d.ts +0 -5
  54. package/dist/utils/index.d.ts +0 -1
  55. package/dist/utils/root-finder.d.ts +0 -34
  56. package/dist/utils/text.d.ts +0 -14
  57. package/dist/utils/vectorUtils.d.ts +0 -15
  58. package/dist/vendor/pixi-dashed-line/index.d.ts +0 -57
  59. package/src/components/axis.ts +0 -247
  60. package/src/components/index.ts +0 -1
  61. package/src/control/ExtendedCurveInterpolator.ts +0 -155
  62. package/src/control/IntersectionReferenceSystem.ts +0 -391
  63. package/src/control/LayerManager.ts +0 -294
  64. package/src/control/MainController.ts +0 -296
  65. package/src/control/ZoomPanHandler.ts +0 -436
  66. package/src/control/index.ts +0 -5
  67. package/src/control/interfaces.ts +0 -42
  68. package/src/control/overlay.ts +0 -118
  69. package/src/datautils/colortable.ts +0 -14
  70. package/src/datautils/findsample.ts +0 -64
  71. package/src/datautils/index.ts +0 -6
  72. package/src/datautils/interfaces.ts +0 -68
  73. package/src/datautils/picks.ts +0 -328
  74. package/src/datautils/schematicShapeGenerator.ts +0 -1007
  75. package/src/datautils/seismicimage.ts +0 -180
  76. package/src/datautils/surfacedata.ts +0 -318
  77. package/src/datautils/trajectory.ts +0 -206
  78. package/src/layers/CalloutCanvasLayer.ts +0 -338
  79. package/src/layers/CustomDisplayObjects/ComplexRope.ts +0 -45
  80. package/src/layers/CustomDisplayObjects/ComplexRopeGeometry.ts +0 -190
  81. package/src/layers/CustomDisplayObjects/FixedWidthSimpleRope.ts +0 -41
  82. package/src/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.ts +0 -149
  83. package/src/layers/CustomDisplayObjects/UniformTextureStretchRope.ts +0 -39
  84. package/src/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.ts +0 -174
  85. package/src/layers/GeomodelCanvasLayer.ts +0 -176
  86. package/src/layers/GeomodelLabelsLayer.ts +0 -619
  87. package/src/layers/GeomodelLayerV2.ts +0 -110
  88. package/src/layers/GridLayer.ts +0 -145
  89. package/src/layers/ImageCanvasLayer.ts +0 -55
  90. package/src/layers/ReferenceLineLayer.ts +0 -185
  91. package/src/layers/SchematicLayer.ts +0 -871
  92. package/src/layers/SeismicCanvasLayer.ts +0 -46
  93. package/src/layers/WellborePathLayer.ts +0 -129
  94. package/src/layers/base/CanvasLayer.ts +0 -102
  95. package/src/layers/base/HTMLLayer.ts +0 -70
  96. package/src/layers/base/Layer.ts +0 -217
  97. package/src/layers/base/PixiLayer.ts +0 -190
  98. package/src/layers/base/SVGLayer.ts +0 -63
  99. package/src/layers/base/index.ts +0 -5
  100. package/src/layers/index.ts +0 -16
  101. package/src/layers/schematicInterfaces.ts +0 -470
  102. package/src/utils/arc-length.ts +0 -66
  103. package/src/utils/binary-search.ts +0 -26
  104. package/src/utils/color.ts +0 -22
  105. package/src/utils/index.ts +0 -1
  106. package/src/utils/root-finder.ts +0 -78
  107. package/src/utils/text.ts +0 -88
  108. package/src/utils/vectorUtils.ts +0 -67
  109. package/src/vendor/pixi-dashed-line/index.ts +0 -394
@@ -1,391 +0,0 @@
1
- import Vector2 from '@equinor/videx-vector2';
2
- import { clamp, radians } from '@equinor/videx-math';
3
- import { CurveInterpolator, normalize } from 'curve-interpolator';
4
-
5
- import { Interpolators, Trajectory, MDPoint } from '../interfaces';
6
- import { ExtendedCurveInterpolator } from './ExtendedCurveInterpolator';
7
-
8
- // determines how curvy the curve is
9
- const TENSION = 0.75;
10
- // determines how many segments to split the curve into
11
- const ARC_DIVISIONS = 5000;
12
- // specifies amount of steps (in the range [0,1]) to work back from the end of the curve
13
- const THRESHOLD_DIRECTION_DISTANCE = 0.001;
14
-
15
- const DEFAULT_START_EXTEND_LENGTH = 1000.0;
16
- const DEFAULT_END_EXTEND_LENGTH = 1000.0;
17
-
18
- const CURTAIN_SAMPLING_ANGLE_THRESHOLD = 0.0005;
19
- const CURTAIN_SAMPLING_INTERVAL = 0.1;
20
-
21
- const defaultOptions = {
22
- approxT: true,
23
- };
24
-
25
- export interface ReferenceSystemOptions {
26
- normalizedLength?: number;
27
- arcDivisions?: number;
28
- tension?: number;
29
- trajectoryAngle?: number;
30
- calculateDisplacementFromBottom?: boolean;
31
- curveInterpolator?: ExtendedCurveInterpolator;
32
- trajectoryInterpolator?: ExtendedCurveInterpolator;
33
- curtainInterpolator?: ExtendedCurveInterpolator;
34
- approxT?: boolean;
35
- quickT?: boolean;
36
- }
37
-
38
- export class IntersectionReferenceSystem {
39
- options: ReferenceSystemOptions;
40
-
41
- path: number[][] = [];
42
-
43
- projectedPath: number[][] = [];
44
-
45
- projectedTrajectory: number[][];
46
-
47
- private _offset: number = 0;
48
-
49
- displacement: number;
50
-
51
- depthReference: number;
52
-
53
- wellboreId: number;
54
-
55
- trajectoryOffset: number;
56
-
57
- interpolators: Interpolators;
58
-
59
- startVector: number[];
60
-
61
- endVector: number[];
62
-
63
- _curtainPathCache: MDPoint[];
64
-
65
- /**
66
- * Creates a common reference system that layers and other components can use
67
- * @param path (required) array of 3d coordinates: [x, y, z]
68
- * @param options (optional)
69
- * @param options.trajectoryAngle (optional) - trajectory angle in degrees, overrides the calculated value
70
- * @param options.calculateDisplacementFromBottom - (optional) specify if the path is passed from bottom up
71
- */
72
- constructor(path: number[][], options?: ReferenceSystemOptions) {
73
- if (path.length < 1) {
74
- throw new Error('Missing coordinates');
75
- }
76
- if (path[0] && path[0].length !== 3) {
77
- throw new Error('Coordinates should be in 3d');
78
- }
79
- this.setPath(path, options);
80
-
81
- this.project = this.project.bind(this);
82
- this.unproject = this.unproject.bind(this);
83
- this.getPosition = this.getPosition.bind(this);
84
- this.getProjectedLength = this.getProjectedLength.bind(this);
85
- this.getTrajectory = this.getTrajectory.bind(this);
86
- }
87
-
88
- private setPath(path: number[][], options: ReferenceSystemOptions = {}): void {
89
- this.options = { ...defaultOptions, ...options };
90
- const { arcDivisions, tension, calculateDisplacementFromBottom } = this.options;
91
-
92
- this.path = path;
93
-
94
- this.projectedPath = IntersectionReferenceSystem.toDisplacement(path);
95
-
96
- const [displacement] = this.projectedPath[this.projectedPath.length - 1];
97
- this.displacement = displacement;
98
-
99
- this.interpolators = {
100
- curve: options.curveInterpolator || new ExtendedCurveInterpolator(path),
101
- trajectory:
102
- options.trajectoryInterpolator ||
103
- new ExtendedCurveInterpolator(
104
- path.map((d: number[]) => [d[0], d[1]]),
105
- { tension: tension || TENSION, arcDivisions: arcDivisions || ARC_DIVISIONS },
106
- ),
107
- curtain:
108
- options.curtainInterpolator ||
109
- new ExtendedCurveInterpolator(this.projectedPath, { tension: tension || TENSION, arcDivisions: arcDivisions || ARC_DIVISIONS }),
110
- };
111
-
112
- const trajVector = this.getTrajectoryVector();
113
- const negativeTrajVector = trajVector.map((d: number) => d * -1);
114
-
115
- if (calculateDisplacementFromBottom) {
116
- this.endVector = negativeTrajVector;
117
- this.startVector = trajVector;
118
- } else {
119
- this.endVector = trajVector;
120
- this.startVector = negativeTrajVector;
121
- }
122
-
123
- this._curtainPathCache = undefined;
124
- }
125
-
126
- /**
127
- * Map a length along the curve to intersection coordinates
128
- * @param length length along the curve
129
- */
130
- project(length: number): number[] {
131
- const { curtain } = this.interpolators;
132
- const { calculateDisplacementFromBottom } = this.options;
133
- const cl = clamp(calculateDisplacementFromBottom ? this.length - (length - this._offset) : length - this._offset, 0, this.length);
134
- const p = curtain.getPointAtArcLength(cl, this.options);
135
- return p as number[];
136
- }
137
-
138
- curtainTangent(length: number): number[] {
139
- const { curtain } = this.interpolators;
140
- const l = length - this._offset;
141
- const t = curtain.findTForArcLength(l, this.options);
142
- const tangent = t && curtain.getTangentAt(t);
143
- return tangent as number[];
144
- }
145
-
146
- /**
147
- * Returns as resampled version of the projected path between start and end
148
- * Samples are picked from the beginning of the path at every CURTAIN_SAMPLING_INTERVAL meters
149
- * If the angle between two consecutive segments is close to 180 degrees depending on CURTAIN_SAMPLING_ANGLE_THRESHOLD,
150
- * a sample in between is discarded.
151
- *
152
- * The start and the end are not guaranteed to be part of the returned set of points
153
- * @param startMd in MD
154
- * @param endMd in MD
155
- * @param includeStartEnd guarantee to include the starting and end points
156
- */
157
- getCurtainPath(startMd: number, endMd: number, includeStartEnd = false): MDPoint[] {
158
- if (!this._curtainPathCache) {
159
- const points: MDPoint[] = [];
160
- let prevAngle = Math.PI * 2; // Always add first point
161
- for (let i = this._offset; i <= this.length + this._offset; i += CURTAIN_SAMPLING_INTERVAL) {
162
- const point = this.project(i);
163
- const angle = Math.atan2(point[1], point[0]);
164
-
165
- // Reduce number of points on a straight line by angle since last point
166
- if (Math.abs(angle - prevAngle) > CURTAIN_SAMPLING_ANGLE_THRESHOLD) {
167
- points.push({ point, md: i });
168
- prevAngle = angle;
169
- }
170
- }
171
- this._curtainPathCache = points;
172
- }
173
-
174
- if (includeStartEnd) {
175
- const startPoint = { point: this.project(startMd), md: startMd };
176
- const pointsBetween = this._curtainPathCache.filter((p) => p.md > startMd && p.md < endMd);
177
- const endPoint = { point: this.project(endMd), md: endMd };
178
- return [startPoint, ...pointsBetween, endPoint];
179
- }
180
- return this._curtainPathCache.filter((p) => p.md >= startMd && p.md <= endMd);
181
- }
182
-
183
- /**
184
- * Map a displacement back to length along the curve
185
- */
186
- unproject(displacement: number): number {
187
- const { normalizedLength, calculateDisplacementFromBottom } = this.options;
188
- const displacementFromStart = calculateDisplacementFromBottom ? this.displacement - displacement : displacement;
189
- const length = normalizedLength || this.length;
190
-
191
- if (displacementFromStart < 0) {
192
- return displacementFromStart;
193
- }
194
- if (displacementFromStart > this.displacement) {
195
- return length + (displacementFromStart - this.displacement);
196
- }
197
-
198
- const ls = this.interpolators.curtain.lookupPositions(displacementFromStart, 0, 1);
199
- if (ls && ls.length) {
200
- return ls[0] * length + this._offset;
201
- }
202
- return null;
203
- }
204
-
205
- /**
206
- * Get the normalized displacement [0 - 1] of a specific length along the curve
207
- */
208
- getProjectedLength(length: number): number {
209
- const { curtain } = this.interpolators;
210
- const pl = this.project(length);
211
- const l = pl[0] / curtain.maxX;
212
- return Number.isFinite(l) ? clamp(l, 0, 1) : 0;
213
- }
214
-
215
- /**
216
- * Get the trajectory position at a length along the curve
217
- */
218
- getPosition(length: number): number[] {
219
- const { trajectory } = this.interpolators;
220
- const t = this.getProjectedLength(length);
221
- const p = trajectory.getPointAt(t) as number[];
222
- return p;
223
- }
224
-
225
- /**
226
- * Generate a set of coordinates along the trajectory of the curve
227
- */
228
- getTrajectory(steps: number, from = 0, to = 1): Trajectory {
229
- const extensionStart = from < 0 ? -from : 0;
230
- const extensionEnd = to > 1 ? to - 1 : 0;
231
-
232
- const refStart = this.interpolators.trajectory.getPointAt(0) as number[];
233
- const refEnd = this.interpolators.trajectory.getPointAt(1) as number[];
234
-
235
- let p0;
236
- let p3;
237
- let offset = 0;
238
- const t0 = Math.max(0, from);
239
- const t1 = Math.min(1, to);
240
- const p1 = this.interpolators.trajectory.getPointAt(t0) as number[];
241
- const p2 = this.interpolators.trajectory.getPointAt(t1) as number[];
242
-
243
- if (extensionStart) {
244
- p0 = [
245
- refStart[0] + this.startVector[0] * extensionStart * this.displacement,
246
- refStart[1] + this.startVector[1] * extensionStart * this.displacement,
247
- ];
248
- offset = -Vector2.distance(p0, refStart);
249
- } else if (from > 0) {
250
- offset = Vector2.distance(p1, refStart);
251
- }
252
-
253
- if (extensionEnd) {
254
- p3 = [refEnd[0] + this.endVector[0] * extensionEnd * this.displacement, refEnd[1] + this.endVector[1] * extensionEnd * this.displacement];
255
- }
256
- const points = [];
257
- const tl = to - from;
258
- const preSteps = Math.floor((extensionStart / tl) * steps);
259
- const curveSteps = Math.ceil(((t1 - t0) / tl) * steps);
260
- const postSteps = steps - curveSteps - preSteps;
261
-
262
- if (p0) {
263
- points.push(p0);
264
- for (let i = 1; i < preSteps; i++) {
265
- const f = (i / preSteps) * extensionStart * this.displacement;
266
- points.push([p0[0] - this.startVector[0] * f, p0[1] - this.startVector[1] * f]);
267
- }
268
- }
269
- const curvePoints = this.interpolators.trajectory.getPoints(curveSteps - 1, null, t0, t1) as number[][]; // returns steps + 1 points
270
- points.push(...curvePoints);
271
- if (p3) {
272
- for (let i = 1; i < postSteps - 1; i++) {
273
- const f = (i / postSteps) * extensionEnd * this.displacement;
274
- points.push([p2[0] + this.endVector[0] * f, p2[1] + this.endVector[1] * f]);
275
- }
276
- points.push(p3);
277
- }
278
- return { points, offset };
279
- }
280
-
281
- /**
282
- * Generate a set of coordinates along the trajectory of the curve
283
- */
284
- getExtendedTrajectory(
285
- numPoints: number,
286
- startExtensionLength = DEFAULT_START_EXTEND_LENGTH,
287
- endExtensionLength = DEFAULT_END_EXTEND_LENGTH,
288
- ): Trajectory {
289
- if (!isFinite(startExtensionLength) || startExtensionLength < 0.0) {
290
- throw new Error('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive startExtensionLength parameter');
291
- }
292
- if (!isFinite(endExtensionLength) || endExtensionLength < 0.0) {
293
- throw new Error('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive endExtensionLength parameter');
294
- }
295
-
296
- const totalLength = this.displacement + startExtensionLength + endExtensionLength;
297
- const startExtensionNumPoints = Math.floor((startExtensionLength / totalLength) * numPoints);
298
- const curveSteps = Math.max(Math.ceil((this.displacement / totalLength) * numPoints), 1);
299
- const endExtensionNumPoints = numPoints - curveSteps - startExtensionNumPoints;
300
-
301
- const points = [];
302
-
303
- const refStart = new Vector2(this.interpolators.trajectory.getPointAt(0.0) as number[]);
304
- const startVec = new Vector2(this.startVector);
305
- const startExtensionStepLength = startExtensionLength / startExtensionNumPoints;
306
- for (let i = startExtensionNumPoints; i > 0; i--) {
307
- const f = i * startExtensionStepLength;
308
- const point = refStart.add(startVec.scale(f));
309
- points.push(point.toArray());
310
- }
311
-
312
- const curveStepPoints = this.interpolators.trajectory.getPoints(curveSteps, null, 0.0, 1.0) as number[][];
313
- points.push(...curveStepPoints);
314
-
315
- const refEnd = new Vector2(this.interpolators.trajectory.getPointAt(1.0) as number[]);
316
- const endVec = new Vector2(this.endVector);
317
- const endExtensionStepLength = endExtensionLength / (endExtensionNumPoints - 1); // -1 so last point is at end of extension
318
- for (let i = 1; i < endExtensionNumPoints; i++) {
319
- const f = i * endExtensionStepLength;
320
- const point = refEnd.add(endVec.scale(f));
321
- points.push(point.toArray());
322
- }
323
-
324
- const offset = -startExtensionLength;
325
-
326
- const trajectory = { points, offset };
327
- return trajectory;
328
- }
329
-
330
- getTrajectoryVector(): number[] {
331
- const { trajectoryAngle, calculateDisplacementFromBottom } = this.options;
332
-
333
- if (isFinite(trajectoryAngle)) {
334
- const angleInRad = radians(trajectoryAngle);
335
- return new Vector2(Math.cos(angleInRad), Math.sin(angleInRad)).toArray();
336
- }
337
-
338
- const trajectoryVec = IntersectionReferenceSystem.getDirectionVector(
339
- this.interpolators.trajectory,
340
- calculateDisplacementFromBottom ? THRESHOLD_DIRECTION_DISTANCE : 1 - THRESHOLD_DIRECTION_DISTANCE,
341
- calculateDisplacementFromBottom ? 0 : 1,
342
- );
343
- return trajectoryVec;
344
- }
345
-
346
- /**
347
- * Perform a curtain projection on a set of points in 3D
348
- * @param points
349
- * @param origin
350
- * @param offset
351
- * @returns {array}
352
- */
353
- static toDisplacement(points: number[][], offset = 0): number[][] {
354
- let p0: number[] = points[0];
355
- let l = 0;
356
- const projected = points.map((p1: number[]) => {
357
- const dx = p1[0] - p0[0];
358
- const dy = p1[1] - p0[1];
359
- l += Math.sqrt(dx ** 2 + dy ** 2);
360
- p0 = p1;
361
- return [offset > 0 ? offset - l : l, p1[2] || 0];
362
- });
363
- return projected;
364
- }
365
-
366
- /**
367
- * returns a normalized vector
368
- * @param interpolator interpolated curve
369
- * @param from number between 0 and 1
370
- * @param to number between 0 and 1
371
- */
372
- static getDirectionVector(interpolator: CurveInterpolator, from: number, to: number): number[] {
373
- const p1 = interpolator.getPointAt(to);
374
- const p2 = interpolator.getPointAt(from);
375
-
376
- return normalize([p1[0] - p2[0], p1[1] - p2[1]]) as number[];
377
- }
378
-
379
- get length(): number {
380
- return this.interpolators.curve.length;
381
- }
382
-
383
- get offset(): number {
384
- return this._offset;
385
- }
386
-
387
- set offset(offset: number) {
388
- this._curtainPathCache = undefined;
389
- this._offset = offset;
390
- }
391
- }
@@ -1,294 +0,0 @@
1
- import { select, Selection } from 'd3-selection';
2
- import { ZoomPanHandler } from './ZoomPanHandler';
3
- import { Layer, GridLayer, LayerOptions } from '../layers';
4
- import { ScaleOptions, OnMountEvent, OnRescaleEvent } from '../interfaces';
5
- import { Axis } from '../components';
6
- import { IntersectionReferenceSystem } from './IntersectionReferenceSystem';
7
- import { HORIZONTAL_AXIS_MARGIN, VERTICAL_AXIS_MARGIN } from '../constants';
8
- import { AxisOptions } from './interfaces';
9
-
10
- export class LayerManager {
11
- private container: HTMLElement;
12
-
13
- private layerContainer: HTMLElement;
14
-
15
- private _zoomPanHandler: ZoomPanHandler;
16
-
17
- private layers: Layer<unknown>[] = [];
18
-
19
- private _axis: Axis;
20
- private _svgContainer: Selection<HTMLElement, unknown, null, undefined>;
21
-
22
- /**
23
- * Handles layers and axis also holds a zoom and pan handler object
24
- * @param container root container
25
- * @param scaleOptions
26
- * @param axisOptions
27
- */
28
- constructor(container: HTMLElement, scaleOptions?: ScaleOptions, axisOptions?: AxisOptions) {
29
- this.container = container;
30
- this.layerContainer = document.createElement('div');
31
- this.layerContainer.className = 'layer-container';
32
- this.container.appendChild(this.layerContainer);
33
- this.adjustToSize(+this.container.getAttribute('width'), +this.container.getAttribute('height'));
34
- this._zoomPanHandler = new ZoomPanHandler(container, (event) => this.rescale(event));
35
- if (scaleOptions) {
36
- const { xMin, xMax, yMin, yMax, xBounds, yBounds } = scaleOptions;
37
- if (xMin !== undefined && xMax !== undefined && yMin !== undefined && yMax !== undefined) {
38
- this._zoomPanHandler.setBounds([xMin, xMax], [yMin, yMax]);
39
- }
40
- if (xBounds && yBounds) {
41
- this._zoomPanHandler.setBounds(xBounds, yBounds);
42
- }
43
- } else {
44
- this._zoomPanHandler.setBounds([0, 1], [0, 1]);
45
- }
46
-
47
- if (axisOptions) {
48
- this._axis = this.createAxis(axisOptions);
49
- }
50
-
51
- this.rescale = this.rescale.bind(this);
52
- }
53
-
54
- /**
55
- * Adds and mounts an array of layers
56
- * @param layers array of layers
57
- */
58
- addLayers(layers: Layer<unknown>[]): LayerManager {
59
- layers.forEach((layer) => this.addLayer(layer));
60
- return this;
61
- }
62
-
63
- /**
64
- * Gets all layers currently mounted
65
- */
66
- getLayers(): Layer<unknown>[] {
67
- return this.layers;
68
- }
69
-
70
- /**
71
- * Clears data from all mounted layers
72
- * @param includeReferenceSystem - (optional) if true also removes reference system, default is true
73
- */
74
- clearAllData(includeReferenceSystem: boolean = true): LayerManager {
75
- this.layers.forEach((l) => l.clearData(includeReferenceSystem));
76
- return this;
77
- }
78
-
79
- /**
80
- * Adds the layer to the manager, and mounts it
81
- * @param layer Layer
82
- * @param params extra params to pass to the onUpdate method
83
- */
84
- addLayer(layer: Layer<unknown>, params?: LayerOptions<unknown>): LayerManager {
85
- this.layers.push(layer);
86
- this.initLayer(layer, params);
87
-
88
- return this;
89
- }
90
-
91
- /**
92
- * Remove and unmount layer from manager
93
- * @param layerId name of layer
94
- */
95
- removeLayer(layerId: string): LayerManager {
96
- const layer = this.layers.find((l) => l.id === layerId);
97
- if (layer) {
98
- layer.onUnmount();
99
- this.layers = this.layers.filter((l) => l.id !== layerId);
100
- }
101
-
102
- return this;
103
- }
104
-
105
- /**
106
- * Remove and unmount all layers from manager
107
- */
108
- removeAllLayers(): LayerManager {
109
- const { layers } = this;
110
- layers.forEach((layer) => {
111
- this.removeLayer(layer.id);
112
- });
113
- return this;
114
- }
115
-
116
- getLayer(layerId: string): Layer<unknown> {
117
- return this.layers.find((l) => l.id === layerId || l.getInternalLayerIds().includes(layerId));
118
- }
119
-
120
- initLayer(layer: Layer<unknown>, params?: LayerOptions<unknown>): LayerManager {
121
- const event: OnMountEvent = {
122
- elm: this.layerContainer,
123
- };
124
- layer.onMount(event);
125
- const rescaleEvent = this.zoomPanHandler.currentStateAsEvent();
126
- layer.onUpdate({ ...rescaleEvent, ...params });
127
- layer.onRescale(rescaleEvent);
128
-
129
- if (this._svgContainer) {
130
- const highestZIndex = this.layers.length > 0 ? this.layers.reduce((max, layers) => (max.order > layers.order ? max : layers)).order : 1;
131
- this._svgContainer.style('z-index', `${highestZIndex + 1}`);
132
- }
133
-
134
- return this;
135
- }
136
-
137
- showLayer(layerId: string): LayerManager {
138
- const layer = this.getLayer(layerId);
139
- if (!layer) {
140
- return this;
141
- }
142
- layer.setVisibility(true, layerId);
143
- layer.onRescale(this.zoomPanHandler.currentStateAsEvent());
144
- return this;
145
- }
146
-
147
- hideLayer(layerId: string): LayerManager {
148
- const layer = this.getLayer(layerId);
149
- if (!layer) {
150
- return this;
151
- }
152
- layer.setVisibility(false, layerId);
153
- layer.onRescale(this.zoomPanHandler.currentStateAsEvent());
154
- return this;
155
- }
156
-
157
- /**
158
- * Adjust layers, axis, and zoom according to inputted dimensions
159
- * @param width (required)
160
- * @param height (required)
161
- */
162
- adjustToSize(width: number, height: number): void {
163
- const layersWidth = Math.max(this._axis ? width - HORIZONTAL_AXIS_MARGIN : width, 0);
164
- const layersHeight = Math.max(this._axis ? height - VERTICAL_AXIS_MARGIN : height, 0);
165
-
166
- if (this._axis) {
167
- const resizeEvent = { width, height };
168
- this._axis.onResize(resizeEvent);
169
- }
170
- if (this.layers) {
171
- const resizeEvent = { width: layersWidth, height: layersHeight };
172
- this.layers.forEach((layer) => layer.onResize(resizeEvent));
173
- }
174
- if (this._zoomPanHandler) {
175
- this._zoomPanHandler.adjustToSize(layersWidth, layersHeight, true);
176
- }
177
- }
178
-
179
- setReferenceSystem(irs: IntersectionReferenceSystem): void {
180
- this.layers.forEach((layer) => (layer.referenceSystem = irs));
181
- }
182
-
183
- showAxis(): LayerManager {
184
- this._axis.show();
185
- return this;
186
- }
187
-
188
- hideAxis(): LayerManager {
189
- this._axis.hide();
190
- return this;
191
- }
192
-
193
- showAxisLabels(): LayerManager {
194
- this._axis.showLabels();
195
- return this;
196
- }
197
-
198
- hideAxisLabels(): LayerManager {
199
- this._axis.hideLabels();
200
- return this;
201
- }
202
-
203
- setAxisOffset(x: number, y: number): LayerManager {
204
- this._axis.offsetX = x;
205
- this._axis.offsetY = y;
206
- const gridLayers = this.layers.filter((l: Layer<unknown>) => l instanceof GridLayer<unknown>);
207
- gridLayers.forEach((l: GridLayer<unknown>) => {
208
- l.offsetX = x;
209
- l.offsetY = y;
210
- });
211
- return this;
212
- }
213
-
214
- setXAxisOffset(x: number): LayerManager {
215
- this._axis.offsetX = x;
216
- const gridLayers = this.layers.filter((l: Layer<unknown>) => l instanceof GridLayer<unknown>);
217
- gridLayers.forEach((l: GridLayer<unknown>) => {
218
- l.offsetX = x;
219
- });
220
- return this;
221
- }
222
-
223
- setYAxisOffset(y: number): LayerManager {
224
- this._axis.offsetY = y;
225
- const gridLayers = this.layers.filter((l: Layer<unknown>) => l instanceof GridLayer<unknown>);
226
- gridLayers.forEach((l: GridLayer<unknown>) => {
227
- l.offsetY = y;
228
- });
229
- return this;
230
- }
231
-
232
- setZoomLevelBoundary(zoomlevels: [number, number]): LayerManager {
233
- this._zoomPanHandler.setZoomLevelBoundary(zoomlevels);
234
- return this;
235
- }
236
-
237
- setMaxZoomLevel(zoomlevel: number): LayerManager {
238
- this._zoomPanHandler.setMaxZoomLevel(zoomlevel);
239
- return this;
240
- }
241
-
242
- setMinZoomLevel(zoomlevel: number): LayerManager {
243
- this._zoomPanHandler.setMinZoomLevel(zoomlevel);
244
- return this;
245
- }
246
-
247
- destroy(): LayerManager {
248
- this.removeAllLayers();
249
- this.layerContainer.remove();
250
- this.layerContainer = undefined;
251
- this.container = undefined;
252
- this.layers = undefined;
253
- this._zoomPanHandler = undefined;
254
- this._axis = undefined;
255
- this._svgContainer = undefined;
256
-
257
- return this;
258
- }
259
-
260
- get zoomPanHandler(): ZoomPanHandler {
261
- return this._zoomPanHandler;
262
- }
263
-
264
- get axis(): Axis {
265
- return this._axis;
266
- }
267
-
268
- private rescale(event: OnRescaleEvent): void {
269
- if (this._axis) {
270
- this._axis.onRescale(event);
271
- }
272
- if (this.layers) {
273
- this.layers.forEach((layer) => (layer.isVisible === true ? layer.onRescale(event) : {}));
274
- }
275
- }
276
-
277
- private createAxis = (options: AxisOptions): Axis => {
278
- const { container } = this;
279
- this._svgContainer = select(container)
280
- .append('div')
281
- .attr('class', 'axis')
282
- .style('position', 'absolute')
283
- .style('z-index', '10')
284
- .style('pointer-events', 'none');
285
-
286
- const svg = this._svgContainer.append('svg').attr('height', `${container.offsetHeight}px`).attr('width', `${container.offsetWidth}px`);
287
-
288
- const showLabels = true;
289
-
290
- const axis = new Axis(svg, showLabels, options.xLabel, options.yLabel, options.unitOfMeasure);
291
-
292
- return axis;
293
- };
294
- }