@welldot/render 0.3.0 → 0.4.1
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/README.md +91 -14
- package/dist/chunk-ODRL222Y.js +10 -0
- package/dist/chunk-ODRL222Y.js.map +1 -0
- package/dist/index.cjs +1404 -336
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +313 -33
- package/dist/index.d.ts +313 -33
- package/dist/index.js +1413 -342
- package/dist/index.js.map +1 -1
- package/dist/textures.cjs +339 -0
- package/dist/textures.cjs.map +1 -0
- package/dist/textures.d.cts +9 -0
- package/dist/textures.d.ts +9 -0
- package/dist/textures.js +7 -0
- package/dist/textures.js.map +1 -0
- package/package.json +11 -4
package/dist/index.cjs
CHANGED
|
@@ -330,10 +330,13 @@ __export(index_exports, {
|
|
|
330
330
|
WellRenderer: () => WellRenderer,
|
|
331
331
|
applyRenderLocale: () => applyRenderLocale,
|
|
332
332
|
drawWellLegend: () => drawWellLegend,
|
|
333
|
+
drawWellLegendSymbol: () => drawWellLegendSymbol,
|
|
333
334
|
formatDiameter: () => formatDiameter,
|
|
334
335
|
formatLength: () => formatLength,
|
|
335
336
|
getDiameterUnit: () => getDiameterUnit,
|
|
336
337
|
getLengthUnit: () => getLengthUnit,
|
|
338
|
+
getProfileTopDepth: () => getProfileTopDepth,
|
|
339
|
+
getWellLegendItems: () => getWellLegendItems,
|
|
337
340
|
importFgdcTextures: () => importFgdcTextures,
|
|
338
341
|
resolveRenderLabel: () => resolveRenderLabel
|
|
339
342
|
});
|
|
@@ -343,6 +346,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
343
346
|
var import_d3 = require("d3");
|
|
344
347
|
|
|
345
348
|
// src/utils/format.utils.ts
|
|
349
|
+
var import_core = require("@welldot/core");
|
|
346
350
|
var import_utils = require("@welldot/utils");
|
|
347
351
|
var MM_TO_INCHES = 0.0393701;
|
|
348
352
|
var M_TO_FT = 3.28084;
|
|
@@ -360,8 +364,7 @@ function getDiameterUnit(units, locale) {
|
|
|
360
364
|
return locale === "en" ? "in." : '"';
|
|
361
365
|
}
|
|
362
366
|
function resolveRenderLabel(value, locale) {
|
|
363
|
-
|
|
364
|
-
return locale === "en" && value.en ? value.en : value.pt;
|
|
367
|
+
return (0, import_core.resolveLanguageText)(value, locale, "pt");
|
|
365
368
|
}
|
|
366
369
|
|
|
367
370
|
// src/configs/render.configs.ts
|
|
@@ -387,6 +390,7 @@ var RENDER_LABELS = {
|
|
|
387
390
|
wellScreen: { pt: "Filtro", en: "Screen" },
|
|
388
391
|
reduction: { pt: "Redu\xE7\xE3o", en: "Reduction" },
|
|
389
392
|
centralizer: { pt: "Centralizador", en: "Centralizer" },
|
|
393
|
+
pump: { pt: "Bomba e edutor", en: "Pump and riser" },
|
|
390
394
|
cementPad: { pt: "Laje de cimento", en: "Cement pad" },
|
|
391
395
|
conflict: { pt: "Conflito", en: "Conflict" }
|
|
392
396
|
}
|
|
@@ -410,7 +414,9 @@ var RENDER_LABELS = {
|
|
|
410
414
|
wellCase: { title: { pt: "REVESTIMENTO", en: "CASING" } },
|
|
411
415
|
wellScreen: {
|
|
412
416
|
title: { pt: "FILTROS", en: "SCREENS" },
|
|
413
|
-
slot: { pt: "Ranhura:", en: "Slot:" }
|
|
417
|
+
slot: { pt: "Ranhura:", en: "Slot:" },
|
|
418
|
+
material: { pt: "Material:", en: "Material:" },
|
|
419
|
+
slotType: { pt: "Tipo:", en: "Type:" }
|
|
414
420
|
},
|
|
415
421
|
reduction: { title: { pt: "REDU\xC7\xC3O", en: "REDUCTION" } },
|
|
416
422
|
centralizer: {
|
|
@@ -418,6 +424,28 @@ var RENDER_LABELS = {
|
|
|
418
424
|
depth: { pt: "Profundidade:", en: "Depth:" },
|
|
419
425
|
spacing: { pt: "Espa\xE7amento:", en: "Spacing:" }
|
|
420
426
|
},
|
|
427
|
+
pump: {
|
|
428
|
+
title: { pt: "BOMBA", en: "PUMP" },
|
|
429
|
+
intakeDepth: { pt: "Profundidade do crivo:", en: "Intake depth:" },
|
|
430
|
+
model: { pt: "Modelo:", en: "Model:" },
|
|
431
|
+
power: { pt: "Pot\xEAncia:", en: "Power:" },
|
|
432
|
+
riser: { pt: "Edutor:", en: "Riser:" },
|
|
433
|
+
type_submersible: { pt: "Bomba submersa", en: "Submersible pump" },
|
|
434
|
+
type_vertical_turbine: {
|
|
435
|
+
pt: "Bomba de eixo vertical",
|
|
436
|
+
en: "Vertical turbine pump"
|
|
437
|
+
},
|
|
438
|
+
type_jet: { pt: "Bomba injetora", en: "Jet pump" },
|
|
439
|
+
type_progressive_cavity: {
|
|
440
|
+
pt: "Bomba helicoidal",
|
|
441
|
+
en: "Progressive cavity pump"
|
|
442
|
+
},
|
|
443
|
+
type_hand_pump: { pt: "Bomba manual", en: "Hand pump" },
|
|
444
|
+
type_compressor_airlift: {
|
|
445
|
+
pt: "Compressor (air-lift)",
|
|
446
|
+
en: "Compressor (air-lift)"
|
|
447
|
+
}
|
|
448
|
+
},
|
|
421
449
|
conflict: { title: { pt: "CONFLITO", en: "CONFLICT" } },
|
|
422
450
|
fracture: {
|
|
423
451
|
title: { pt: "FRATURA", en: "FRACTURE" },
|
|
@@ -443,6 +471,19 @@ var RENDER_LABELS = {
|
|
|
443
471
|
fractureWater: { pt: "fratura aberta", en: "open fracture" },
|
|
444
472
|
cave: { pt: "caverna", en: "cave" },
|
|
445
473
|
caveWater: { pt: "caverna \xFAmida", en: "wet cave" }
|
|
474
|
+
},
|
|
475
|
+
columnHeaders: {
|
|
476
|
+
depth: { pt: "PROF.", en: "DEPTH" },
|
|
477
|
+
lithology: { pt: "LIT.", en: "LITH." },
|
|
478
|
+
construction: { pt: "CONSTRU\xC7\xC3O", en: "CONSTRUCTION" },
|
|
479
|
+
description: { pt: "DESCRI\xC7\xC3O GEOL\xD3GICA", en: "GEOLOGICAL DESCRIPTION" }
|
|
480
|
+
},
|
|
481
|
+
continuation: { prefix: { pt: "continua\xE7\xE3o", en: "continued" } },
|
|
482
|
+
overlap: {
|
|
483
|
+
label: {
|
|
484
|
+
pt: "{range} repetido da p\xE1g. anterior",
|
|
485
|
+
en: "{range} repeated from previous page"
|
|
486
|
+
}
|
|
446
487
|
}
|
|
447
488
|
};
|
|
448
489
|
function resolveGroup(group, locale) {
|
|
@@ -464,6 +505,7 @@ function resolveTooltipLabels(locale) {
|
|
|
464
505
|
wellScreen: resolveGroup(t.wellScreen, locale),
|
|
465
506
|
reduction: resolveGroup(t.reduction, locale),
|
|
466
507
|
centralizer: resolveGroup(t.centralizer, locale),
|
|
508
|
+
pump: resolveGroup(t.pump, locale),
|
|
467
509
|
conflict: resolveGroup(t.conflict, locale),
|
|
468
510
|
fracture: resolveGroup(t.fracture, locale),
|
|
469
511
|
cementPad: resolveGroup(t.cementPad, locale),
|
|
@@ -485,7 +527,19 @@ function applyRenderLocale(config, locale) {
|
|
|
485
527
|
tooltipLabels: resolveTooltipLabels(locale),
|
|
486
528
|
labels: {
|
|
487
529
|
...config.labels,
|
|
488
|
-
typeLabels: resolveGroup(RENDER_LABELS.typeLabels, locale)
|
|
530
|
+
typeLabels: resolveGroup(RENDER_LABELS.typeLabels, locale),
|
|
531
|
+
continuation: {
|
|
532
|
+
...config.labels.continuation,
|
|
533
|
+
prefix: resolveRenderLabel(RENDER_LABELS.continuation.prefix, locale)
|
|
534
|
+
}
|
|
535
|
+
},
|
|
536
|
+
columnHeaders: {
|
|
537
|
+
...config.columnHeaders,
|
|
538
|
+
labels: resolveGroup(RENDER_LABELS.columnHeaders, locale)
|
|
539
|
+
},
|
|
540
|
+
overlap: {
|
|
541
|
+
...config.overlap,
|
|
542
|
+
label: resolveRenderLabel(RENDER_LABELS.overlap.label, locale)
|
|
489
543
|
}
|
|
490
544
|
};
|
|
491
545
|
}
|
|
@@ -511,7 +565,7 @@ var DEFAULT_WELL_THEME = {
|
|
|
511
565
|
crackStrokeWidth: 0.7
|
|
512
566
|
}
|
|
513
567
|
},
|
|
514
|
-
cementPad: { stroke: "#303030", strokeWidth:
|
|
568
|
+
cementPad: { stroke: "#303030", strokeWidth: 1 },
|
|
515
569
|
boreHole: {
|
|
516
570
|
fill: "#ffffff",
|
|
517
571
|
stroke: "#191919",
|
|
@@ -520,11 +574,24 @@ var DEFAULT_WELL_THEME = {
|
|
|
520
574
|
strokeWidth: 1.2
|
|
521
575
|
},
|
|
522
576
|
surfaceCase: { stroke: "#000000", strokeWidth: 4 },
|
|
523
|
-
holeFill: { stroke: "#303030", strokeWidth: 2 },
|
|
577
|
+
holeFill: { stroke: "#303030", strokeWidth: 1.2 },
|
|
524
578
|
wellCase: { fill: "#ffffff", stroke: "#303030", strokeWidth: 2 },
|
|
525
|
-
wellScreen: {
|
|
579
|
+
wellScreen: {
|
|
580
|
+
stroke: "#303030",
|
|
581
|
+
strokeWidth: 2,
|
|
582
|
+
endStrokeWidth: 0.75,
|
|
583
|
+
endDasharray: "3, 2"
|
|
584
|
+
},
|
|
526
585
|
reduction: { fill: "#ffffff", stroke: "#303030", strokeWidth: 2 },
|
|
527
586
|
centralizer: { fill: "none", stroke: "#303030", strokeWidth: 1.4 },
|
|
587
|
+
pump: {
|
|
588
|
+
fill: "#5b6b7a",
|
|
589
|
+
stroke: "#202020",
|
|
590
|
+
strokeWidth: 1.2,
|
|
591
|
+
riserFill: "#a3adb7",
|
|
592
|
+
riserStroke: "#2f3a44",
|
|
593
|
+
riserStrokeWidth: 1
|
|
594
|
+
},
|
|
528
595
|
conflict: { stroke: "#e52117", strokeWidth: 4 },
|
|
529
596
|
unitLabels: {
|
|
530
597
|
geologicFill: "#f0f0f0",
|
|
@@ -560,6 +627,39 @@ var DEFAULT_WELL_THEME = {
|
|
|
560
627
|
headerFontWeight: 600,
|
|
561
628
|
bodyFontWeight: 400
|
|
562
629
|
},
|
|
630
|
+
overview: {
|
|
631
|
+
stroke: "#303030",
|
|
632
|
+
strokeWidth: 0.5,
|
|
633
|
+
emptyFill: "#d9d9d9",
|
|
634
|
+
windowStroke: "#c0392b",
|
|
635
|
+
windowStrokeWidth: 1.2
|
|
636
|
+
},
|
|
637
|
+
columnHeaders: {
|
|
638
|
+
fontSize: 6.5,
|
|
639
|
+
color: "#303030",
|
|
640
|
+
fontFamily: "sans-serif",
|
|
641
|
+
fontWeight: 600,
|
|
642
|
+
ruleStroke: "#101010",
|
|
643
|
+
ruleStrokeWidth: 1
|
|
644
|
+
},
|
|
645
|
+
markers: {
|
|
646
|
+
fill: "#ffffff",
|
|
647
|
+
stroke: "#101010",
|
|
648
|
+
strokeWidth: 0.6,
|
|
649
|
+
color: "#101010",
|
|
650
|
+
fontSize: 6,
|
|
651
|
+
fontFamily: "sans-serif",
|
|
652
|
+
fontWeight: 600
|
|
653
|
+
},
|
|
654
|
+
overlap: {
|
|
655
|
+
stroke: "#9a9a9a",
|
|
656
|
+
strokeWidth: 0.6,
|
|
657
|
+
size: 6,
|
|
658
|
+
ruleStroke: "#9a9a9a",
|
|
659
|
+
labelColor: "#555555",
|
|
660
|
+
fontSize: 6.5,
|
|
661
|
+
fontFamily: "monospace"
|
|
662
|
+
},
|
|
563
663
|
legend: {
|
|
564
664
|
borderStrokeWidth: 0.8,
|
|
565
665
|
fractureStrokeWidth: 1.5,
|
|
@@ -617,9 +717,17 @@ var STATIC_RENDER_CONFIG = {
|
|
|
617
717
|
}
|
|
618
718
|
},
|
|
619
719
|
construction: {
|
|
620
|
-
cementPad: {
|
|
720
|
+
cementPad: { widthRatio: 1.4, height: 6 },
|
|
721
|
+
casingShoe: { active: true, size: 4 },
|
|
722
|
+
screenEnds: { active: true },
|
|
621
723
|
surfaceCase: { diameterPaddingRatio: 0.1 },
|
|
622
|
-
centralizer: { markerHalfHeight: 4 }
|
|
724
|
+
centralizer: { markerHalfHeight: 4 },
|
|
725
|
+
pump: {
|
|
726
|
+
active: true,
|
|
727
|
+
bodyHeight: 22,
|
|
728
|
+
bodyWidthRatio: 0.6,
|
|
729
|
+
riserWidthRatio: 0.3
|
|
730
|
+
}
|
|
623
731
|
},
|
|
624
732
|
tooltipLabels: resolveTooltipLabels("pt"),
|
|
625
733
|
labels: {
|
|
@@ -632,7 +740,11 @@ var STATIC_RENDER_CONFIG = {
|
|
|
632
740
|
stackingLineHeight: 10,
|
|
633
741
|
stackingGap: 0,
|
|
634
742
|
fractureLabelLeaderGap: 5,
|
|
635
|
-
lithology: true
|
|
743
|
+
lithology: true,
|
|
744
|
+
continuation: {
|
|
745
|
+
active: false,
|
|
746
|
+
prefix: resolveRenderLabel(RENDER_LABELS.continuation.prefix, "pt")
|
|
747
|
+
}
|
|
636
748
|
},
|
|
637
749
|
unitLabels: {
|
|
638
750
|
active: true,
|
|
@@ -691,10 +803,21 @@ var STATIC_RENDER_CONFIG = {
|
|
|
691
803
|
wellScreen: "Filtro",
|
|
692
804
|
reduction: "Redu\xE7\xE3o",
|
|
693
805
|
centralizer: "Centralizador",
|
|
806
|
+
pump: "Bomba e edutor",
|
|
694
807
|
cementPad: "Laje de cimento",
|
|
695
808
|
conflict: "Conflito"
|
|
696
809
|
}
|
|
697
810
|
},
|
|
811
|
+
overview: { active: false, x: 4, width: 8, height: 200 },
|
|
812
|
+
columnHeaders: {
|
|
813
|
+
active: false,
|
|
814
|
+
height: 14,
|
|
815
|
+
labels: resolveGroup(RENDER_LABELS.columnHeaders, "pt")
|
|
816
|
+
},
|
|
817
|
+
markers: { lithology: false, fractures: false, radius: 4.5 },
|
|
818
|
+
overlap: {
|
|
819
|
+
label: resolveRenderLabel(RENDER_LABELS.overlap.label, "pt")
|
|
820
|
+
},
|
|
698
821
|
highlights: DEFAULT_HIGHLIGHT_CONFIG
|
|
699
822
|
};
|
|
700
823
|
var INTERACTIVE_RENDER_CONFIG = {
|
|
@@ -730,9 +853,17 @@ var INTERACTIVE_RENDER_CONFIG = {
|
|
|
730
853
|
}
|
|
731
854
|
},
|
|
732
855
|
construction: {
|
|
733
|
-
cementPad: {
|
|
856
|
+
cementPad: { widthRatio: 1.4, height: 6 },
|
|
857
|
+
casingShoe: { active: true, size: 4 },
|
|
858
|
+
screenEnds: { active: true },
|
|
734
859
|
surfaceCase: { diameterPaddingRatio: 0.1 },
|
|
735
|
-
centralizer: { markerHalfHeight: 4 }
|
|
860
|
+
centralizer: { markerHalfHeight: 4 },
|
|
861
|
+
pump: {
|
|
862
|
+
active: true,
|
|
863
|
+
bodyHeight: 22,
|
|
864
|
+
bodyWidthRatio: 0.6,
|
|
865
|
+
riserWidthRatio: 0.3
|
|
866
|
+
}
|
|
736
867
|
},
|
|
737
868
|
tooltipLabels: resolveTooltipLabels("pt"),
|
|
738
869
|
labels: {
|
|
@@ -743,7 +874,11 @@ var INTERACTIVE_RENDER_CONFIG = {
|
|
|
743
874
|
descriptionXOffset: 78,
|
|
744
875
|
descriptionMaxWidth: 226,
|
|
745
876
|
stackingLineHeight: 11,
|
|
746
|
-
stackingGap: 0
|
|
877
|
+
stackingGap: 0,
|
|
878
|
+
continuation: {
|
|
879
|
+
active: false,
|
|
880
|
+
prefix: resolveRenderLabel(RENDER_LABELS.continuation.prefix, "pt")
|
|
881
|
+
}
|
|
747
882
|
},
|
|
748
883
|
unitLabels: {
|
|
749
884
|
active: false,
|
|
@@ -801,10 +936,21 @@ var INTERACTIVE_RENDER_CONFIG = {
|
|
|
801
936
|
wellScreen: "Filtro",
|
|
802
937
|
reduction: "Redu\xE7\xE3o",
|
|
803
938
|
centralizer: "Centralizador",
|
|
939
|
+
pump: "Bomba e edutor",
|
|
804
940
|
cementPad: "Laje de cimento",
|
|
805
941
|
conflict: "Conflito"
|
|
806
942
|
}
|
|
807
943
|
},
|
|
944
|
+
overview: { active: false, x: 4, width: 8, height: 200 },
|
|
945
|
+
columnHeaders: {
|
|
946
|
+
active: false,
|
|
947
|
+
height: 14,
|
|
948
|
+
labels: resolveGroup(RENDER_LABELS.columnHeaders, "pt")
|
|
949
|
+
},
|
|
950
|
+
markers: { lithology: false, fractures: false, radius: 4.5 },
|
|
951
|
+
overlap: {
|
|
952
|
+
label: resolveRenderLabel(RENDER_LABELS.overlap.label, "pt")
|
|
953
|
+
},
|
|
808
954
|
highlights: DEFAULT_HIGHLIGHT_CONFIG
|
|
809
955
|
};
|
|
810
956
|
|
|
@@ -821,6 +967,8 @@ var import_defu2 = require("defu");
|
|
|
821
967
|
|
|
822
968
|
// src/configs/render.textures.ts
|
|
823
969
|
var import_textures = __toESM(require("textures"), 1);
|
|
970
|
+
var dot = (x, y, r) => `M${x - r},${y}a${r},${r} 0 1,0 ${2 * r},0a${r},${r} 0 1,0 ${-2 * r},0Z`;
|
|
971
|
+
var concreteAggregate = (s) => `M${s * 0.08},${s * 0.42}l${s * 0.3},0l${-s * 0.12},${-s * 0.26}ZM${s * 0.55},${s * 0.92}l${s * 0.26},${-s * 0.06}l${-s * 0.16},${-s * 0.2}Z${dot(s * 0.72, s * 0.24, s * 0.06)}${dot(s * 0.22, s * 0.78, s * 0.05)}`;
|
|
824
972
|
function createWellTextures(cfg) {
|
|
825
973
|
const pad = {
|
|
826
974
|
background: "#ffffff",
|
|
@@ -868,7 +1016,9 @@ function createWellTextures(cfg) {
|
|
|
868
1016
|
...cfg?.surface_case
|
|
869
1017
|
};
|
|
870
1018
|
return {
|
|
871
|
-
|
|
1019
|
+
// Concrete: aggregate (small triangles and dots) on a light ground, so it
|
|
1020
|
+
// reads apart from the seal's diagonals and the gravel pack's circles.
|
|
1021
|
+
pad: import_textures.default.paths().d(concreteAggregate).size(6).strokeWidth(0.4).stroke(pad.stroke).fill(pad.stroke).background(pad.background),
|
|
872
1022
|
conflict: import_textures.default.lines().heavier().stroke(conflict.stroke),
|
|
873
1023
|
cave_dry: import_textures.default.lines().size(cave_dry.size).orientation("6/8").heavier(0.3).thinner(0.8).background(cave_dry.background).stroke(cave_dry.stroke),
|
|
874
1024
|
cave_wet: import_textures.default.lines().size(cave_wet.size).orientation("6/8").heavier(0.3).thinner(0.8).background(cave_wet.background).stroke(cave_wet.stroke),
|
|
@@ -880,8 +1030,8 @@ function createWellTextures(cfg) {
|
|
|
880
1030
|
}
|
|
881
1031
|
|
|
882
1032
|
// src/Renderer.ts
|
|
883
|
-
var
|
|
884
|
-
var
|
|
1033
|
+
var import_core4 = require("@welldot/core");
|
|
1034
|
+
var import_utils10 = require("@welldot/utils");
|
|
885
1035
|
|
|
886
1036
|
// src/configs/render.classnames.ts
|
|
887
1037
|
var DEFAULT_COMPONENTS_CLASS_NAMES = {
|
|
@@ -943,6 +1093,10 @@ var DEFAULT_COMPONENTS_CLASS_NAMES = {
|
|
|
943
1093
|
group: "centralizer",
|
|
944
1094
|
item: "centralizer-marker"
|
|
945
1095
|
},
|
|
1096
|
+
pump: {
|
|
1097
|
+
group: "pump",
|
|
1098
|
+
item: "pump-item"
|
|
1099
|
+
},
|
|
946
1100
|
reduction: {
|
|
947
1101
|
group: "reduction",
|
|
948
1102
|
item: "reduction-poly"
|
|
@@ -974,6 +1128,26 @@ var DEFAULT_COMPONENTS_CLASS_NAMES = {
|
|
|
974
1128
|
caveFill: "cave-fill",
|
|
975
1129
|
constructionRect: "construction-rect"
|
|
976
1130
|
},
|
|
1131
|
+
overview: {
|
|
1132
|
+
group: "wp-overview",
|
|
1133
|
+
item: "wp-overview-item",
|
|
1134
|
+
window: "wp-overview-window"
|
|
1135
|
+
},
|
|
1136
|
+
columnHeaders: {
|
|
1137
|
+
group: "wp-column-headers",
|
|
1138
|
+
text: "wp-column-header",
|
|
1139
|
+
rule: "wp-column-headers-rule"
|
|
1140
|
+
},
|
|
1141
|
+
markers: {
|
|
1142
|
+
group: "wp-markers",
|
|
1143
|
+
lithology: "wp-marker-lithology",
|
|
1144
|
+
fracture: "wp-marker-fracture"
|
|
1145
|
+
},
|
|
1146
|
+
overlap: {
|
|
1147
|
+
group: "wp-overlap",
|
|
1148
|
+
band: "wp-overlap-band",
|
|
1149
|
+
label: "wp-overlap-label"
|
|
1150
|
+
},
|
|
977
1151
|
highlights: {
|
|
978
1152
|
geologicGroup: "wp-highlights-geologic",
|
|
979
1153
|
constructionGroup: "wp-highlights-construction",
|
|
@@ -988,6 +1162,156 @@ var DEFAULT_COMPONENTS_CLASS_NAMES = {
|
|
|
988
1162
|
// src/utils/render.utils.ts
|
|
989
1163
|
var import_textures2 = __toESM(require("textures"), 1);
|
|
990
1164
|
|
|
1165
|
+
// src/utils/construction.geometry.ts
|
|
1166
|
+
var JOINT_EPS = 1e-3;
|
|
1167
|
+
function diameterAt(items, depth) {
|
|
1168
|
+
return items.find((i) => depth >= i.from && depth <= i.to)?.diameter;
|
|
1169
|
+
}
|
|
1170
|
+
function getIntervalEnds(item, string, depthFrom, depthTo) {
|
|
1171
|
+
return {
|
|
1172
|
+
cutTop: item.from < depthFrom - JOINT_EPS,
|
|
1173
|
+
cutBottom: item.to > depthTo + JOINT_EPS,
|
|
1174
|
+
joinedTop: string.some(
|
|
1175
|
+
(o) => o !== item && Math.abs(o.to - item.from) < JOINT_EPS
|
|
1176
|
+
),
|
|
1177
|
+
joinedBottom: string.some(
|
|
1178
|
+
(o) => o !== item && Math.abs(o.from - item.to) < JOINT_EPS
|
|
1179
|
+
)
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
function pipeWallsPath(xLeft, xRight, yTop, yBottom) {
|
|
1183
|
+
return `M${xLeft},${yTop}V${yBottom}M${xRight},${yTop}V${yBottom}`;
|
|
1184
|
+
}
|
|
1185
|
+
function shoePath(xLeft, xRight, y, size) {
|
|
1186
|
+
return `M${xLeft},${y - size}L${xLeft},${y}L${xLeft - size},${y}ZM${xRight},${y - size}L${xRight},${y}L${xRight + size},${y}Z`;
|
|
1187
|
+
}
|
|
1188
|
+
function screenEndPath(xLeft, xRight, y) {
|
|
1189
|
+
return `M${xLeft},${y}H${xRight}`;
|
|
1190
|
+
}
|
|
1191
|
+
var clampDepth = (s, depth) => Math.min(Math.max(depth, s.depthFrom), s.depthTo);
|
|
1192
|
+
var inPanel = (s, depth) => depth >= s.depthFrom - JOINT_EPS && depth <= s.depthTo + JOINT_EPS;
|
|
1193
|
+
var shoulders = (s, a, b, y) => `M${s.left(a)},${y}H${s.left(b)}M${s.right(a)},${y}H${s.right(b)}`;
|
|
1194
|
+
function boreHoleOutlinePath(item, holes, s) {
|
|
1195
|
+
const yTop = s.y(clampDepth(s, item.from));
|
|
1196
|
+
const yBottom = s.y(clampDepth(s, item.to));
|
|
1197
|
+
let d = pipeWallsPath(
|
|
1198
|
+
s.left(item.diameter),
|
|
1199
|
+
s.right(item.diameter),
|
|
1200
|
+
yTop,
|
|
1201
|
+
yBottom
|
|
1202
|
+
);
|
|
1203
|
+
if (item.from > JOINT_EPS && inPanel(s, item.from)) {
|
|
1204
|
+
const above = holes.find(
|
|
1205
|
+
(o) => o !== item && o.from < item.from && o.to >= item.from - JOINT_EPS
|
|
1206
|
+
);
|
|
1207
|
+
if (above && above.diameter < item.diameter)
|
|
1208
|
+
d += shoulders(s, above.diameter, item.diameter, yTop);
|
|
1209
|
+
}
|
|
1210
|
+
if (inPanel(s, item.to)) {
|
|
1211
|
+
const below = holes.find(
|
|
1212
|
+
(o) => o !== item && o.from <= item.to + JOINT_EPS && o.to > item.to
|
|
1213
|
+
);
|
|
1214
|
+
if (!below) {
|
|
1215
|
+
d += `M${s.left(item.diameter)},${yBottom}H${s.right(item.diameter)}`;
|
|
1216
|
+
} else if (below.diameter < item.diameter) {
|
|
1217
|
+
d += shoulders(s, item.diameter, below.diameter, yBottom);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return d;
|
|
1221
|
+
}
|
|
1222
|
+
function holeFillOutlinePath(item, pipes, s) {
|
|
1223
|
+
const yTop = s.y(clampDepth(s, item.from));
|
|
1224
|
+
const yBottom = s.y(clampDepth(s, item.to));
|
|
1225
|
+
const xL = s.left(item.diameter);
|
|
1226
|
+
const xR = s.right(item.diameter);
|
|
1227
|
+
let d = pipeWallsPath(xL, xR, yTop, yBottom);
|
|
1228
|
+
const interfaces = [item.from, item.to].filter(
|
|
1229
|
+
(depth) => depth > JOINT_EPS && inPanel(s, depth)
|
|
1230
|
+
);
|
|
1231
|
+
for (const depth of interfaces) {
|
|
1232
|
+
const y = s.y(depth);
|
|
1233
|
+
const pipe = diameterAt(pipes, depth);
|
|
1234
|
+
if (pipe !== void 0 && pipe < item.diameter) {
|
|
1235
|
+
d += `M${xL},${y}H${s.left(pipe)}M${s.right(pipe)},${y}H${xR}`;
|
|
1236
|
+
} else {
|
|
1237
|
+
d += `M${xL},${y}H${xR}`;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
return d;
|
|
1241
|
+
}
|
|
1242
|
+
function pipeSlices(pipes, from, to) {
|
|
1243
|
+
const cuts = [.../* @__PURE__ */ new Set([from, to, ...pipes.flatMap((p) => [p.from, p.to])])].filter((d) => d >= from && d <= to).sort((a, b) => a - b);
|
|
1244
|
+
const slices = [];
|
|
1245
|
+
for (let i = 1; i < cuts.length; i++) {
|
|
1246
|
+
const a = cuts[i - 1];
|
|
1247
|
+
const b = cuts[i];
|
|
1248
|
+
const mid = (a + b) / 2;
|
|
1249
|
+
const widest = Math.max(
|
|
1250
|
+
0,
|
|
1251
|
+
...pipes.filter((p) => p.from <= mid && p.to >= mid).map((p) => p.diameter)
|
|
1252
|
+
);
|
|
1253
|
+
if (widest === 0) continue;
|
|
1254
|
+
const last = slices[slices.length - 1];
|
|
1255
|
+
if (last && last.to === a && last.diameter === widest) last.to = b;
|
|
1256
|
+
else slices.push({ from: a, to: b, diameter: widest });
|
|
1257
|
+
}
|
|
1258
|
+
return slices;
|
|
1259
|
+
}
|
|
1260
|
+
function annulusFillPath(item, pipes, s) {
|
|
1261
|
+
const from = clampDepth(s, item.from);
|
|
1262
|
+
const to = clampDepth(s, item.to);
|
|
1263
|
+
const box = (dia, a, b) => `M${s.left(dia)},${s.y(a)}H${s.right(dia)}V${s.y(b)}H${s.left(dia)}Z`;
|
|
1264
|
+
const inner = pipes.filter((p) => p.diameter < item.diameter);
|
|
1265
|
+
return box(item.diameter, from, to) + pipeSlices(inner, from, to).map((p) => box(p.diameter, p.from, p.to)).join("");
|
|
1266
|
+
}
|
|
1267
|
+
function getPadDiameters(data, surfaceCasePaddingRatio) {
|
|
1268
|
+
const surfaceCase = diameterAt(data.surface_case, 0);
|
|
1269
|
+
const paddedSurfaceCase = surfaceCase === void 0 ? void 0 : surfaceCase * (1 + surfaceCasePaddingRatio);
|
|
1270
|
+
const casing = diameterAt([...data.well_case, ...data.well_screen], 0);
|
|
1271
|
+
const hole = diameterAt(data.bore_hole, 0);
|
|
1272
|
+
const opening = casing ?? paddedSurfaceCase ?? hole ?? 0;
|
|
1273
|
+
const outer = Math.max(
|
|
1274
|
+
opening,
|
|
1275
|
+
paddedSurfaceCase ?? 0,
|
|
1276
|
+
hole ?? 0,
|
|
1277
|
+
diameterAt(data.hole_fill, 0) ?? 0
|
|
1278
|
+
);
|
|
1279
|
+
return { opening, outer };
|
|
1280
|
+
}
|
|
1281
|
+
function getCementPadGeometry(pocoWidth, pocoCenter, surfaceY, config, openingWidth = 0, outerWidth = openingWidth) {
|
|
1282
|
+
const h = config.height;
|
|
1283
|
+
const opening = Math.max(0, openingWidth);
|
|
1284
|
+
const width = Math.max(
|
|
1285
|
+
pocoWidth * config.widthRatio,
|
|
1286
|
+
opening + 3 * h,
|
|
1287
|
+
outerWidth + 2 * h
|
|
1288
|
+
);
|
|
1289
|
+
const xLeft = (pocoCenter - width) / 2;
|
|
1290
|
+
const xRight = xLeft + width;
|
|
1291
|
+
const oLeft = (pocoCenter - opening) / 2;
|
|
1292
|
+
const oRight = oLeft + opening;
|
|
1293
|
+
const yTop = surfaceY - h;
|
|
1294
|
+
const a = h * 0.3;
|
|
1295
|
+
const breakLine = (x, y0, y1, dir) => `L${x + dir * a},${y0 + (y1 - y0) * 0.4}L${x - dir * a},${y0 + (y1 - y0) * 0.6}L${x},${y1}`;
|
|
1296
|
+
const bbox = { x: xLeft, y: yTop, width, height: h };
|
|
1297
|
+
if (opening === 0) {
|
|
1298
|
+
return {
|
|
1299
|
+
bbox,
|
|
1300
|
+
slabs: [
|
|
1301
|
+
`M${xLeft},${yTop}H${xRight}${breakLine(xRight, yTop, surfaceY, 1)}H${xLeft}${breakLine(xLeft, surfaceY, yTop, -1)}Z`,
|
|
1302
|
+
""
|
|
1303
|
+
]
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1306
|
+
return {
|
|
1307
|
+
bbox,
|
|
1308
|
+
slabs: [
|
|
1309
|
+
`M${oLeft},${yTop}H${xLeft}${breakLine(xLeft, yTop, surfaceY, -1)}H${oLeft}Z`,
|
|
1310
|
+
`M${oRight},${yTop}H${xRight}${breakLine(xRight, yTop, surfaceY, 1)}H${oRight}Z`
|
|
1311
|
+
]
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
|
|
991
1315
|
// src/utils/d3.utils.ts
|
|
992
1316
|
function mergeEnter(enter, update) {
|
|
993
1317
|
return enter.merge(update);
|
|
@@ -1058,6 +1382,7 @@ var makeSeededPrng = (seed, scramble = 6271) => {
|
|
|
1058
1382
|
// src/utils/tooltips.utils.ts
|
|
1059
1383
|
var import_d3_tip = __toESM(require("d3-tip"), 1);
|
|
1060
1384
|
var import_sanitize_html = __toESM(require("sanitize-html"), 1);
|
|
1385
|
+
var import_core2 = require("@welldot/core");
|
|
1061
1386
|
var import_utils2 = require("@welldot/utils");
|
|
1062
1387
|
var esc = (v) => (0, import_sanitize_html.default)(String(v ?? ""), { allowedTags: [], allowedAttributes: {} });
|
|
1063
1388
|
var _tooltipCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -1068,6 +1393,7 @@ var populateTooltips = (svg, customClasses, units, tooltipConfig, labels, locale
|
|
|
1068
1393
|
if (cached && cached.signature === signature) {
|
|
1069
1394
|
return cached.tooltips;
|
|
1070
1395
|
}
|
|
1396
|
+
const material = (value) => (0, import_core2.getVocabLabel)(import_core2.CONSTRUCTION_MATERIALS, value, locale);
|
|
1071
1397
|
const tipsText = {
|
|
1072
1398
|
geology: (_, d) => `
|
|
1073
1399
|
<span class="${customClasses.tooltip.title}">${labels.geology.title}</span>
|
|
@@ -1100,14 +1426,15 @@ var populateTooltips = (svg, customClasses, units, tooltipConfig, labels, locale
|
|
|
1100
1426
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
1101
1427
|
<strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}
|
|
1102
1428
|
</span>
|
|
1103
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>
|
|
1429
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(material(d.type))}</span>
|
|
1104
1430
|
`,
|
|
1105
1431
|
wellScreen: (_, d) => `
|
|
1106
1432
|
<span class="${customClasses.tooltip.title}">${labels.wellScreen.title}</span>
|
|
1107
1433
|
<span class="${customClasses.tooltip.primaryInfo}">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>
|
|
1108
1434
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
1109
1435
|
<strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>
|
|
1110
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.
|
|
1436
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.wellScreen.material}</strong> ${esc(material(d.type))}</span>
|
|
1437
|
+
${d.slot_type ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.wellScreen.slotType}</strong> ${esc((0, import_core2.getVocabLabel)(import_core2.SCREEN_SLOT_TYPES, d.slot_type, locale))}</span>` : ""}
|
|
1111
1438
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
1112
1439
|
<strong>${labels.wellScreen.slot}</strong> ${esc((0, import_utils2.formatNumber)(d.screen_slot, { maximumFractionDigits: 2, locale }))} mm
|
|
1113
1440
|
</span>
|
|
@@ -1118,17 +1445,29 @@ var populateTooltips = (svg, customClasses, units, tooltipConfig, labels, locale
|
|
|
1118
1445
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
1119
1446
|
<strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diam_from, units.diameter, locale))} \u2192 ${esc(formatDiameter(d.diam_to, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}
|
|
1120
1447
|
</span>
|
|
1121
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>
|
|
1448
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(material(d.type))}</span>
|
|
1122
1449
|
`,
|
|
1123
1450
|
centralizer: (_, d) => `
|
|
1124
1451
|
<span class="${customClasses.tooltip.title}">${labels.centralizer.title}</span>
|
|
1125
1452
|
<span class="${customClasses.tooltip.primaryInfo}"><strong>${labels.centralizer.depth}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>
|
|
1126
1453
|
${d.from !== d.to ? `<span class="${customClasses.tooltip.secondaryInfo}">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ""}
|
|
1127
1454
|
${d.spacing ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.centralizer.spacing}</strong> ${esc(formatLength(d.spacing, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ""}
|
|
1128
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>
|
|
1455
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc((0, import_core2.getVocabLabel)(import_core2.CENTRALIZER_TYPES, d.type, locale))}</span>
|
|
1129
1456
|
${d.diameter ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>` : ""}
|
|
1130
1457
|
${d.description ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>` : ""}
|
|
1131
1458
|
`,
|
|
1459
|
+
pump: (_, d) => {
|
|
1460
|
+
const typeLabel = labels.pump[`type_${d.type}`] ?? d.type;
|
|
1461
|
+
const model = [d.manufacturer, d.model].filter(Boolean).join(" ");
|
|
1462
|
+
return `
|
|
1463
|
+
<span class="${customClasses.tooltip.title}">${labels.pump.title}</span>
|
|
1464
|
+
<span class="${customClasses.tooltip.primaryInfo}">${esc(typeLabel)}</span>
|
|
1465
|
+
${d.intake_depth !== void 0 ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.pump.intakeDepth}</strong> ${esc(formatLength(d.intake_depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ""}
|
|
1466
|
+
${model ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.pump.model}</strong> ${esc(model)}</span>` : ""}
|
|
1467
|
+
${d.rated_power !== void 0 ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.pump.power}</strong> ${esc((0, import_utils2.formatNumber)((0, import_core2.powerFromCanonical)(d.rated_power, units.power ?? "kW"), { maximumFractionDigits: 2, locale }))} ${esc(units.power ?? "kW")}</span>` : ""}
|
|
1468
|
+
${d.riser_diameter !== void 0 ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.pump.riser}</strong> ${esc(formatDiameter(d.riser_diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}${d.riser_material ? ` \xB7 ${esc(material(d.riser_material))}` : ""}</span>` : ""}
|
|
1469
|
+
`;
|
|
1470
|
+
},
|
|
1132
1471
|
conflict: (_, d) => `
|
|
1133
1472
|
<span class="${customClasses.tooltip.title}">${labels.conflict.title}</span>
|
|
1134
1473
|
<span class="${customClasses.tooltip.primaryInfo}">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>
|
|
@@ -1139,14 +1478,14 @@ var populateTooltips = (svg, customClasses, units, tooltipConfig, labels, locale
|
|
|
1139
1478
|
<span class="${customClasses.tooltip.title}">${title}</span>
|
|
1140
1479
|
<span class="${customClasses.tooltip.primaryInfo}"><strong>${labels.fracture.depth}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>
|
|
1141
1480
|
${d.water_intake ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.fracture.waterIntake}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ""}
|
|
1142
|
-
|
|
1143
|
-
|
|
1481
|
+
${typeof d.dip === "number" ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.fracture.dip}</strong> ${esc(d.dip)}\xB0</span>` : ""}
|
|
1482
|
+
${typeof d.azimuth === "number" ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.fracture.azimuth}</strong> ${esc(d.azimuth)}\xB0</span>` : ""}
|
|
1144
1483
|
${d.description ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>` : ""}
|
|
1145
1484
|
`;
|
|
1146
1485
|
},
|
|
1147
1486
|
cementPad: (_, d) => `
|
|
1148
1487
|
<span class="${customClasses.tooltip.title}">${labels.cementPad.title}</span>
|
|
1149
|
-
<span class="${customClasses.tooltip.primaryInfo}">${esc(d.type)}</span>
|
|
1488
|
+
<span class="${customClasses.tooltip.primaryInfo}">${esc((0, import_core2.getVocabLabel)(import_core2.CEMENT_PAD_TYPES, d.type, locale))}</span>
|
|
1150
1489
|
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.cementPad.thickness}</strong>
|
|
1151
1490
|
${esc(formatLength(d.thickness, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>
|
|
1152
1491
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
@@ -1184,6 +1523,17 @@ var populateTooltips = (svg, customClasses, units, tooltipConfig, labels, locale
|
|
|
1184
1523
|
};
|
|
1185
1524
|
|
|
1186
1525
|
// src/utils/render.utils.ts
|
|
1526
|
+
var fractureDip = (dip) => typeof dip === "number" && Number.isFinite(dip) ? dip : 0;
|
|
1527
|
+
function getCementPadRect(pocoWidth, pocoCenter, surfaceY, config, openingWidth = 0, outerWidth = openingWidth) {
|
|
1528
|
+
return getCementPadGeometry(
|
|
1529
|
+
pocoWidth,
|
|
1530
|
+
pocoCenter,
|
|
1531
|
+
surfaceY,
|
|
1532
|
+
config,
|
|
1533
|
+
openingWidth,
|
|
1534
|
+
outerWidth
|
|
1535
|
+
).bbox;
|
|
1536
|
+
}
|
|
1187
1537
|
var _fgdcTextures = {};
|
|
1188
1538
|
var _fgdcTexturesPromise = null;
|
|
1189
1539
|
var preloadFgdcTextures = () => {
|
|
@@ -1292,14 +1642,23 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
1292
1642
|
}
|
|
1293
1643
|
const items = [];
|
|
1294
1644
|
if (active.has("lithology")) {
|
|
1645
|
+
const continuation = s.continuation;
|
|
1295
1646
|
data.lithology.filter((d) => d.from < ctx.depthTo).forEach((d) => {
|
|
1647
|
+
const range = `${formatLength(d.from, ctx.units.length, ctx.locale)}\u2013${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)}`;
|
|
1648
|
+
const continues = continuation?.active && d.from < ctx.depthFrom;
|
|
1296
1649
|
items.push({
|
|
1297
1650
|
sortDepth: d.from,
|
|
1298
1651
|
baseY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),
|
|
1299
1652
|
originX: ctx.geoXRight,
|
|
1300
1653
|
originY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),
|
|
1301
|
-
header:
|
|
1302
|
-
description: d.description || ""
|
|
1654
|
+
header: continues ? `\u2191 ${continuation.prefix} \xB7 ${range}` : range,
|
|
1655
|
+
description: continues ? "" : d.description || "",
|
|
1656
|
+
...show.has("units") ? {
|
|
1657
|
+
unit: d.geologic_unit || void 0,
|
|
1658
|
+
aquifer: continues ? void 0 : d.aquifer_unit || void 0
|
|
1659
|
+
} : {},
|
|
1660
|
+
...show.has("swatch") && !continues ? { swatch: d } : {},
|
|
1661
|
+
...show.has("rules") ? { rule: continues ? "dashed" : "solid" } : {}
|
|
1303
1662
|
});
|
|
1304
1663
|
});
|
|
1305
1664
|
}
|
|
@@ -1312,7 +1671,8 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
1312
1671
|
originX: ctx.pocoCenterX,
|
|
1313
1672
|
originY: ctx.yScale(d.depth),
|
|
1314
1673
|
header: `${formatLength(d.depth, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)} \xB7 ${typeLabel}`,
|
|
1315
|
-
description: d.description || ""
|
|
1674
|
+
description: d.description || "",
|
|
1675
|
+
...show.has("rules") ? { rule: "dashed" } : {}
|
|
1316
1676
|
});
|
|
1317
1677
|
});
|
|
1318
1678
|
}
|
|
@@ -1332,14 +1692,15 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
1332
1692
|
}
|
|
1333
1693
|
items.sort((a, b) => a.sortDepth - b.sortDepth);
|
|
1334
1694
|
const labelPositions = [];
|
|
1335
|
-
let currY = 0;
|
|
1695
|
+
let currY = ctx.repeatedTo != null ? s.stackingLineHeight + 2 : 0;
|
|
1336
1696
|
const charsPerLine = Math.max(
|
|
1337
1697
|
1,
|
|
1338
1698
|
Math.floor(s.descriptionMaxWidth / (st.fontSize * 0.6))
|
|
1339
1699
|
);
|
|
1340
1700
|
items.forEach((item) => {
|
|
1341
|
-
const descLines = Math.ceil((item.description.length || 1) / charsPerLine);
|
|
1342
|
-
const
|
|
1701
|
+
const descLines = show.has("units") ? item.description ? wrapText(item.description, charsPerLine).length : 0 : Math.ceil((item.description.length || 1) / charsPerLine);
|
|
1702
|
+
const extraLines = (item.unit ? 1 : 0) + (item.aquifer ? 1 : 0);
|
|
1703
|
+
const estH = (1 + descLines + extraLines) * s.stackingLineHeight + 4;
|
|
1343
1704
|
const yLabel = Math.max(item.baseY, currY + s.stackingGap);
|
|
1344
1705
|
currY = yLabel + estH;
|
|
1345
1706
|
labelPositions.push({ item, yLabel, estH });
|
|
@@ -1356,16 +1717,41 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
1356
1717
|
if (show.has("description")) {
|
|
1357
1718
|
const lineH = s.stackingLineHeight;
|
|
1358
1719
|
const bgFill = st.annotationBg ?? "white";
|
|
1720
|
+
const swatchFill = labelPositions.some((p) => p.item.swatch) ? getLithologyFill(data.lithology, ctx.svg, ctx.theme.lithologyTexture) : null;
|
|
1359
1721
|
labelPositions.forEach(({ item, yLabel, estH }) => {
|
|
1360
1722
|
const labelG = ctx.groups.lithologyLabelsGroup.append("g").attr("class", ctx.classes.labels.lithology.label).attr("transform", `translate(${labelX},${yLabel})`);
|
|
1361
1723
|
labelG.append("rect").attr("x", 0).attr("y", 0).attr("width", s.descriptionMaxWidth).attr("height", estH).attr("rx", st.annotationRadius ?? 2).attr("fill", bgFill).attr("fill-opacity", st.annotationBgOpacity ?? 0.85).attr("stroke", st.annotationBorderColor ?? "none");
|
|
1362
|
-
|
|
1724
|
+
if (item.rule) {
|
|
1725
|
+
labelG.append("line").attr("x1", 0).attr("x2", s.descriptionMaxWidth).attr("y1", 0).attr("y2", 0).attr("stroke", ctx.theme.labels.color).attr(
|
|
1726
|
+
"stroke-width",
|
|
1727
|
+
item.rule === "solid" ? 0.8 : ctx.theme.labels.dividerStrokeWidth
|
|
1728
|
+
).attr(
|
|
1729
|
+
"stroke-dasharray",
|
|
1730
|
+
item.rule === "solid" ? null : ctx.theme.labels.dividerStrokeDasharray
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
let headerX = 0;
|
|
1734
|
+
if (item.swatch && swatchFill) {
|
|
1735
|
+
const size = lineH * 0.75;
|
|
1736
|
+
labelG.append("rect").attr("x", 0).attr("y", lineH * 0.85 - size + 1).attr("width", size).attr("height", size).attr("fill", swatchFill(item.swatch)).attr("stroke", ctx.theme.lithology.stroke).attr("stroke-width", 0.5);
|
|
1737
|
+
headerX = size + 3;
|
|
1738
|
+
}
|
|
1739
|
+
labelG.append("text").attr("class", "wp-annotation-header").attr("fill", ctx.theme.labels.color).attr("font-weight", st.headerFontWeight ?? 600).attr("font-family", ctx.theme.labels.headerFont).attr("x", headerX).attr("y", lineH * 0.85).attr("font-size", st.fontSize).text(item.header);
|
|
1740
|
+
let lineY = lineH * 0.85 + lineH;
|
|
1741
|
+
if (item.unit) {
|
|
1742
|
+
labelG.append("text").attr("class", "wp-annotation-unit").attr("fill", ctx.theme.labels.color).attr("font-weight", st.headerFontWeight ?? 600).attr("font-family", ctx.theme.labels.bodyFont ?? "sans-serif").attr("x", 0).attr("y", lineY).attr("font-size", st.fontSize).text(item.unit);
|
|
1743
|
+
lineY += lineH;
|
|
1744
|
+
}
|
|
1363
1745
|
if (item.description) {
|
|
1364
1746
|
const lines = wrapText(item.description, charsPerLine);
|
|
1365
|
-
const bodyEl = labelG.append("text").attr("class", "wp-annotation-body").attr("fill", ctx.theme.labels.bodyColor).attr("font-weight", st.bodyFontWeight ?? 400).attr("font-family", ctx.theme.labels.bodyFont ?? "sans-serif").attr("x", 0).attr("y",
|
|
1747
|
+
const bodyEl = labelG.append("text").attr("class", "wp-annotation-body").attr("fill", ctx.theme.labels.bodyColor).attr("font-weight", st.bodyFontWeight ?? 400).attr("font-family", ctx.theme.labels.bodyFont ?? "sans-serif").attr("x", 0).attr("y", lineY).attr("font-size", st.fontSize);
|
|
1366
1748
|
lines.forEach((line, i) => {
|
|
1367
1749
|
bodyEl.append("tspan").attr("x", 0).attr("dy", i === 0 ? 0 : lineH).text(line);
|
|
1368
1750
|
});
|
|
1751
|
+
lineY += lines.length * lineH;
|
|
1752
|
+
}
|
|
1753
|
+
if (item.aquifer) {
|
|
1754
|
+
labelG.append("text").attr("class", "wp-annotation-aquifer").attr("fill", ctx.theme.labels.bodyColor).attr("font-style", "italic").attr("font-family", ctx.theme.labels.bodyFont ?? "sans-serif").attr("x", 0).attr("y", lineY).attr("font-size", st.fontSize).text(item.aquifer);
|
|
1369
1755
|
}
|
|
1370
1756
|
});
|
|
1371
1757
|
}
|
|
@@ -1386,7 +1772,6 @@ var makePointKey = (type) => (d, i) => {
|
|
|
1386
1772
|
|
|
1387
1773
|
// src/renderers/caves.renderer.ts
|
|
1388
1774
|
function drawCaves(ctx, data) {
|
|
1389
|
-
if (!data.length) return;
|
|
1390
1775
|
const {
|
|
1391
1776
|
groups: { cavesGroup },
|
|
1392
1777
|
geoXLeft,
|
|
@@ -1396,7 +1781,7 @@ function drawCaves(ctx, data) {
|
|
|
1396
1781
|
yScale,
|
|
1397
1782
|
renderConfig,
|
|
1398
1783
|
theme,
|
|
1399
|
-
textures:
|
|
1784
|
+
textures: textures4,
|
|
1400
1785
|
classes,
|
|
1401
1786
|
tooltips
|
|
1402
1787
|
} = ctx;
|
|
@@ -1433,7 +1818,7 @@ function drawCaves(ctx, data) {
|
|
|
1433
1818
|
const botPath = botCut ? `M ${geoXLeft.toFixed(1)},${yBot.toFixed(1)} L ${geoXRight.toFixed(1)},${yBot.toFixed(1)}` : ptsToSmoothPath(botPts);
|
|
1434
1819
|
const botReversed = botCut ? `L ${geoXLeft.toFixed(1)},${yBot.toFixed(1)}` : ptsToSmoothPath([...botPts].reverse(), { omitMoveTo: true });
|
|
1435
1820
|
const closedPath = `${topPath} L ${geoXRight.toFixed(1)},${yBot.toFixed(1)}${botReversed} L ${geoXLeft.toFixed(1)},${yTop.toFixed(1)} Z`;
|
|
1436
|
-
const caveTexture = cave.water_intake ?
|
|
1821
|
+
const caveTexture = cave.water_intake ? textures4.cave_wet : textures4.cave_dry;
|
|
1437
1822
|
const caveStroke = cave.water_intake ? theme.cave.wetStroke : theme.cave.dryStroke;
|
|
1438
1823
|
g.append("path").attr("class", classes.caves.fill).attr("d", closedPath).attr("fill", caveTexture.url()).attr("fill-opacity", theme.cave.fillOpacity).attr("stroke", "none");
|
|
1439
1824
|
g.append("path").attr("class", classes.caves.contact).attr("d", topPath).attr("fill", "none").attr("stroke", caveStroke).attr("stroke-width", theme.cave.contactStrokeWidth).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
@@ -1445,9 +1830,6 @@ function drawCaves(ctx, data) {
|
|
|
1445
1830
|
// src/renderers/centralizers.renderer.ts
|
|
1446
1831
|
var d32 = __toESM(require("d3"), 1);
|
|
1447
1832
|
var import_utils3 = require("@welldot/utils");
|
|
1448
|
-
function diameterAt(items, depth) {
|
|
1449
|
-
return items.find((i) => depth >= i.from && depth <= i.to)?.diameter;
|
|
1450
|
-
}
|
|
1451
1833
|
function drawCentralizers(ctx, data) {
|
|
1452
1834
|
const group = ctx.groups.centralizerGroup;
|
|
1453
1835
|
const cls = ctx.classes.centralizer;
|
|
@@ -1484,8 +1866,108 @@ function drawCentralizers(ctx, data) {
|
|
|
1484
1866
|
});
|
|
1485
1867
|
}
|
|
1486
1868
|
|
|
1869
|
+
// src/utils/layout.utils.ts
|
|
1870
|
+
function getProfileTopDepth(profile) {
|
|
1871
|
+
return Math.min(
|
|
1872
|
+
0,
|
|
1873
|
+
...[
|
|
1874
|
+
...profile.surface_case ?? [],
|
|
1875
|
+
...profile.well_case ?? [],
|
|
1876
|
+
...profile.well_screen ?? []
|
|
1877
|
+
].map((i) => i.from).filter(Number.isFinite)
|
|
1878
|
+
);
|
|
1879
|
+
}
|
|
1880
|
+
function resolvePanelWindows(panels, totalDepth, topDepth = 0) {
|
|
1881
|
+
if (panels.length > 0 && panels.every((p) => p.depthRange)) {
|
|
1882
|
+
return panels.map((p) => [p.depthRange[0], p.depthRange[1]]);
|
|
1883
|
+
}
|
|
1884
|
+
if (panels.length === 1) return [[topDepth, totalDepth]];
|
|
1885
|
+
const totalHeight = panels.reduce((s, p) => s + p.height, 0) || 1;
|
|
1886
|
+
const metersPerPx = (totalDepth - topDepth) / totalHeight;
|
|
1887
|
+
let current = topDepth;
|
|
1888
|
+
return panels.map((p) => {
|
|
1889
|
+
const from = current;
|
|
1890
|
+
current = from + p.height * metersPerPx;
|
|
1891
|
+
return [from, current];
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
function getColumnHeaderPositions(geometry) {
|
|
1895
|
+
const { marginLeft, geoXLeft, geoXRight, pocoCenterX, descriptionX } = geometry;
|
|
1896
|
+
return {
|
|
1897
|
+
depth: marginLeft - 2,
|
|
1898
|
+
lithology: marginLeft + (geoXLeft + geoXRight) / 2,
|
|
1899
|
+
construction: marginLeft + pocoCenterX,
|
|
1900
|
+
...descriptionX != null ? { description: marginLeft + descriptionX } : {}
|
|
1901
|
+
};
|
|
1902
|
+
}
|
|
1903
|
+
function getLithologyMarkers(lithology, depthFrom, depthTo) {
|
|
1904
|
+
const markers = [];
|
|
1905
|
+
lithology.forEach((layer, i) => {
|
|
1906
|
+
const from = Math.max(layer.from, depthFrom);
|
|
1907
|
+
const to = Math.min(layer.to, depthTo);
|
|
1908
|
+
if (to > from) markers.push({ index: i + 1, from, to });
|
|
1909
|
+
});
|
|
1910
|
+
return markers;
|
|
1911
|
+
}
|
|
1912
|
+
function getFractureMarkers(fractures, depthFrom, depthTo) {
|
|
1913
|
+
const markers = [];
|
|
1914
|
+
fractures.forEach((f, i) => {
|
|
1915
|
+
if (f.depth >= depthFrom && f.depth < depthTo) {
|
|
1916
|
+
markers.push({ label: `F${i + 1}`, depth: f.depth });
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
1919
|
+
return markers;
|
|
1920
|
+
}
|
|
1921
|
+
function getOverviewGeometry(totalDepth, height, depthFrom, depthTo) {
|
|
1922
|
+
const ratio = totalDepth > 0 ? height / totalDepth : 0;
|
|
1923
|
+
const y = (depth) => Math.min(height, Math.max(0, depth * ratio));
|
|
1924
|
+
return {
|
|
1925
|
+
y,
|
|
1926
|
+
window: { y: y(depthFrom), height: Math.max(1, y(depthTo) - y(depthFrom)) }
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
function formatOverlapLabel(template, range) {
|
|
1930
|
+
return template.replace("{range}", range);
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
// src/renderers/column-headers.renderer.ts
|
|
1934
|
+
function hasDescriptionColumn(ctx) {
|
|
1935
|
+
const { active, lithology } = ctx.renderConfig.labels;
|
|
1936
|
+
if (active === false) return false;
|
|
1937
|
+
if (Array.isArray(active) && !active.includes("lithology")) return false;
|
|
1938
|
+
if (lithology === false) return false;
|
|
1939
|
+
return !Array.isArray(lithology) || lithology.includes("description");
|
|
1940
|
+
}
|
|
1941
|
+
function drawColumnHeaders(ctx) {
|
|
1942
|
+
const group = ctx.groups.columnHeadersGroup;
|
|
1943
|
+
group.selectAll("*").remove();
|
|
1944
|
+
const cfg = ctx.renderConfig.columnHeaders;
|
|
1945
|
+
if (!cfg.active) return;
|
|
1946
|
+
const theme = ctx.theme.columnHeaders;
|
|
1947
|
+
const { margins } = ctx.state;
|
|
1948
|
+
const positions = getColumnHeaderPositions({
|
|
1949
|
+
marginLeft: margins.left,
|
|
1950
|
+
geoXLeft: ctx.geoXLeft,
|
|
1951
|
+
geoXRight: ctx.geoXRight,
|
|
1952
|
+
pocoCenterX: ctx.pocoCenterX,
|
|
1953
|
+
descriptionX: hasDescriptionColumn(ctx) ? ctx.geoXRight + ctx.renderConfig.labels.descriptionXOffset : void 0
|
|
1954
|
+
});
|
|
1955
|
+
const ruleY = margins.top - 2 - ctx.renderConfig.construction.cementPad.height;
|
|
1956
|
+
const textY = ruleY - 4;
|
|
1957
|
+
const addText = (x, text, anchor) => group.append("text").attr("class", ctx.classes.columnHeaders.text).attr("x", x).attr("y", textY).attr("text-anchor", anchor).attr("font-size", theme.fontSize).attr("font-family", theme.fontFamily ?? "sans-serif").attr("font-weight", theme.fontWeight ?? 600).attr("fill", theme.color).text(text);
|
|
1958
|
+
addText(positions.depth, cfg.labels.depth, "end");
|
|
1959
|
+
addText(positions.lithology, cfg.labels.lithology, "middle");
|
|
1960
|
+
addText(positions.construction, cfg.labels.construction, "middle");
|
|
1961
|
+
if (positions.description != null) {
|
|
1962
|
+
addText(positions.description, cfg.labels.description, "start");
|
|
1963
|
+
}
|
|
1964
|
+
const overview = ctx.renderConfig.overview;
|
|
1965
|
+
group.append("line").attr("class", ctx.classes.columnHeaders.rule).attr("x1", overview.active ? overview.x : 0).attr("x2", ctx.svgWidth).attr("y1", ruleY).attr("y2", ruleY).attr("stroke", theme.ruleStroke).attr("stroke-width", theme.ruleStrokeWidth);
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1487
1968
|
// src/renderers/construction-labels.renderer.ts
|
|
1488
1969
|
var d33 = __toESM(require("d3"), 1);
|
|
1970
|
+
var import_core3 = require("@welldot/core");
|
|
1489
1971
|
var import_utils4 = require("@welldot/utils");
|
|
1490
1972
|
function drawConstructionLabels(ctx, data) {
|
|
1491
1973
|
if (!ctx.renderConfig.constructionLabels.active) return;
|
|
@@ -1494,16 +1976,18 @@ function drawConstructionLabels(ctx, data) {
|
|
|
1494
1976
|
const clct = ctx.theme.constructionLabels;
|
|
1495
1977
|
const fmtD = (mm) => formatDiameter(mm, ctx.units.diameter, ctx.locale);
|
|
1496
1978
|
const dUnit = getDiameterUnit(ctx.units.diameter, ctx.locale);
|
|
1979
|
+
const material = (value) => (0, import_core3.getVocabLabel)(import_core3.CONSTRUCTION_MATERIALS, value, ctx.locale);
|
|
1497
1980
|
const maxXValues = (0, import_utils4.getProfileDiamValues)(ctx.constructionData);
|
|
1498
1981
|
const xScale = d33.scaleLinear().domain([0, d33.max(maxXValues) || 0]).range([0, ctx.POCO_WIDTH]);
|
|
1499
1982
|
const occupied = [];
|
|
1500
|
-
const
|
|
1983
|
+
const onRight = clc.side === "right";
|
|
1984
|
+
const continuation = ctx.renderConfig.labels.continuation;
|
|
1985
|
+
const placeLabel = (d, label) => {
|
|
1501
1986
|
const clampedFrom = Math.max(d.from, ctx.depthFrom);
|
|
1502
1987
|
const clampedTo = Math.min(d.to, ctx.depthTo);
|
|
1503
1988
|
if (clampedFrom >= clampedTo) return;
|
|
1989
|
+
const text = continuation?.active && d.from < ctx.depthFrom ? `\u2191 ${label}` : label;
|
|
1504
1990
|
const midY = ctx.yScale((clampedFrom + clampedTo) / 2);
|
|
1505
|
-
const leftEdgeX = (ctx.POCO_CENTER - xScale(d.diameter)) / 2;
|
|
1506
|
-
const labelRightX = leftEdgeX - clc.xOffset;
|
|
1507
1991
|
const charW = clct.fontSize * 0.52;
|
|
1508
1992
|
const lineH = clct.fontSize * 1.35;
|
|
1509
1993
|
const vertPad = 6;
|
|
@@ -1520,16 +2004,17 @@ function drawConstructionLabels(ctx, data) {
|
|
|
1520
2004
|
lines = [text];
|
|
1521
2005
|
boxW = text.length * charW + 8;
|
|
1522
2006
|
}
|
|
2007
|
+
const labelRightX = onRight ? (ctx.POCO_CENTER + ctx.POCO_WIDTH) / 2 + clc.xOffset + boxW : (ctx.POCO_CENTER - xScale(d.diameter)) / 2 - clc.xOffset;
|
|
1523
2008
|
const labelH = lines.length * lineH + vertPad;
|
|
1524
|
-
let labelY = midY - labelH / 2;
|
|
2009
|
+
let labelY = onRight ? ctx.yScale(clampedFrom) + 1 : midY - labelH / 2;
|
|
1525
2010
|
for (const pos of occupied) {
|
|
1526
2011
|
if (labelY < pos.bot && labelY + labelH > pos.top) labelY = pos.bot + 2;
|
|
1527
2012
|
}
|
|
1528
2013
|
occupied.push({ top: labelY, bot: labelY + labelH });
|
|
1529
2014
|
ctx.groups.constructionLabelsGroup.append("rect").attr("x", labelRightX - boxW).attr("y", labelY).attr("width", boxW).attr("height", labelH).attr("rx", clc.labelRadius).attr("fill", clct.labelFill ?? "white").attr("stroke", clct.labelColor ?? "#303030").attr("stroke-width", 0.5);
|
|
1530
|
-
const textEl = ctx.groups.constructionLabelsGroup.append("text").attr("x", labelRightX - 4).attr("y", labelY + lineH * 0.85).attr("font-size", clct.fontSize).attr("font-family", clct.fontFamily ?? "sans-serif").attr("font-weight", clct.fontWeight ?? 400).attr("text-anchor", "end").attr("fill", clct.labelColor ?? "#303030");
|
|
2015
|
+
const textEl = ctx.groups.constructionLabelsGroup.append("text").attr("x", onRight ? labelRightX - boxW + 4 : labelRightX - 4).attr("y", labelY + lineH * 0.85).attr("font-size", clct.fontSize).attr("font-family", clct.fontFamily ?? "sans-serif").attr("font-weight", clct.fontWeight ?? 400).attr("text-anchor", onRight ? "start" : "end").attr("fill", clct.labelColor ?? "#303030");
|
|
1531
2016
|
lines.forEach((line, i) => {
|
|
1532
|
-
textEl.append("tspan").attr("x", labelRightX - 4).attr("dy", i === 0 ? 0 : lineH).text(line);
|
|
2017
|
+
textEl.append("tspan").attr("x", onRight ? labelRightX - boxW + 4 : labelRightX - 4).attr("dy", i === 0 ? 0 : lineH).text(line);
|
|
1533
2018
|
});
|
|
1534
2019
|
};
|
|
1535
2020
|
let lastDiam = 0;
|
|
@@ -1542,7 +2027,7 @@ function drawConstructionLabels(ctx, data) {
|
|
|
1542
2027
|
}).forEach(
|
|
1543
2028
|
(d) => placeLabel(
|
|
1544
2029
|
d,
|
|
1545
|
-
`${clc.labels.wellCasePrefix} ${fmtD(d.diameter)}${dUnit} ${d.type}`
|
|
2030
|
+
`${clc.labels.wellCasePrefix} ${fmtD(d.diameter)}${dUnit} ${material(d.type)}`
|
|
1546
2031
|
)
|
|
1547
2032
|
);
|
|
1548
2033
|
lastDiam = 0;
|
|
@@ -1555,7 +2040,7 @@ function drawConstructionLabels(ctx, data) {
|
|
|
1555
2040
|
}).forEach(
|
|
1556
2041
|
(d) => placeLabel(
|
|
1557
2042
|
d,
|
|
1558
|
-
`${clc.labels.wellScreenPrefix} ${fmtD(d.diameter)}${dUnit} ${d.type} ${clc.labels.wellScreenSlotPrefix} ${fmtD(d.screen_slot)}${dUnit}`
|
|
2043
|
+
`${clc.labels.wellScreenPrefix} ${fmtD(d.diameter)}${dUnit} ${material(d.type)} ${clc.labels.wellScreenSlotPrefix} ${fmtD(d.screen_slot)}${dUnit}`
|
|
1559
2044
|
)
|
|
1560
2045
|
);
|
|
1561
2046
|
}
|
|
@@ -1563,110 +2048,307 @@ function drawConstructionLabels(ctx, data) {
|
|
|
1563
2048
|
// src/renderers/construction.renderer.ts
|
|
1564
2049
|
var d34 = __toESM(require("d3"), 1);
|
|
1565
2050
|
var import_utils5 = require("@welldot/utils");
|
|
2051
|
+
var entering = /* @__PURE__ */ new WeakSet();
|
|
2052
|
+
function constructionXScale(ctx) {
|
|
2053
|
+
const max6 = d34.max((0, import_utils5.getProfileDiamValues)(ctx.constructionData)) || 0;
|
|
2054
|
+
return d34.scaleLinear().domain([0, max6]).range([0, ctx.POCO_WIDTH]);
|
|
2055
|
+
}
|
|
2056
|
+
function outlineScales(ctx) {
|
|
2057
|
+
const x = constructionXScale(ctx);
|
|
2058
|
+
return {
|
|
2059
|
+
y: ctx.yScale,
|
|
2060
|
+
left: (d) => (ctx.POCO_CENTER - x(d)) / 2,
|
|
2061
|
+
right: (d) => (ctx.POCO_CENTER + x(d)) / 2,
|
|
2062
|
+
depthFrom: ctx.depthFrom,
|
|
2063
|
+
depthTo: ctx.depthTo
|
|
2064
|
+
};
|
|
2065
|
+
}
|
|
2066
|
+
var surfaceCaseDiameter = (ctx, diameter) => diameter * (1 + ctx.renderConfig.construction.surfaceCase.diameterPaddingRatio);
|
|
2067
|
+
function joinIntervalLayer(ctx, group, cls, data, key, tooltip, { shoe = false, pathFill = false, ends = false } = {}) {
|
|
2068
|
+
const sel = group.selectAll(`g.${cls}`).data(data, makeIntervalKey(key));
|
|
2069
|
+
sel.exit().transition(ctx.transition).style("opacity", 0).remove();
|
|
2070
|
+
const top = (d) => ctx.yScale(Math.max(d.from, ctx.depthFrom));
|
|
2071
|
+
const entered = sel.enter().append("g").attr("class", cls).each((_d, i, nodes) => entering.add(nodes[i])).on("mouseover", tooltip.show).on("mouseout", tooltip.hide);
|
|
2072
|
+
if (pathFill)
|
|
2073
|
+
entered.append("path").attr("class", `${cls}-fill`).attr("stroke", "none").attr("fill-rule", "evenodd").attr("d", "");
|
|
2074
|
+
else
|
|
2075
|
+
entered.append("rect").attr("class", `${cls}-fill`).attr("stroke", "none").attr("y", top).attr("height", 0);
|
|
2076
|
+
entered.append("path").attr("class", `${cls}-outline`).attr("fill", "none").attr("d", "");
|
|
2077
|
+
if (shoe)
|
|
2078
|
+
entered.append("path").attr("class", `${cls}-shoe`).attr("stroke-linejoin", "round").attr("d", "");
|
|
2079
|
+
if (ends)
|
|
2080
|
+
entered.append("path").attr("class", `${cls}-ends`).attr("fill", "none").attr("d", "");
|
|
2081
|
+
return entered.merge(sel);
|
|
2082
|
+
}
|
|
2083
|
+
function drawCementPad(ctx, pad) {
|
|
2084
|
+
const cls = ctx.classes.cementPad.item;
|
|
2085
|
+
const visible = !!pad?.thickness && ctx.depthFrom <= 0 && ctx.depthTo > 0;
|
|
2086
|
+
const sel = ctx.groups.cementPadGroup.selectAll(`g.${cls}`).data(visible ? [pad] : [], () => "cement_pad");
|
|
2087
|
+
sel.exit().remove();
|
|
2088
|
+
if (!visible) return;
|
|
2089
|
+
const entered = sel.enter().append("g").attr("class", cls).on("mouseover", ctx.tooltips.cementPad.show).on("mouseout", ctx.tooltips.cementPad.hide);
|
|
2090
|
+
entered.append("path").attr("class", `${cls}-slab`);
|
|
2091
|
+
entered.append("path").attr("class", `${cls}-slab`);
|
|
2092
|
+
const x = constructionXScale(ctx);
|
|
2093
|
+
const { opening, outer } = getPadDiameters(
|
|
2094
|
+
ctx.constructionData,
|
|
2095
|
+
ctx.renderConfig.construction.surfaceCase.diameterPaddingRatio
|
|
2096
|
+
);
|
|
2097
|
+
const { slabs } = getCementPadGeometry(
|
|
2098
|
+
ctx.POCO_WIDTH,
|
|
2099
|
+
ctx.POCO_CENTER,
|
|
2100
|
+
ctx.yScale(0),
|
|
2101
|
+
ctx.renderConfig.construction.cementPad,
|
|
2102
|
+
x(opening),
|
|
2103
|
+
x(outer)
|
|
2104
|
+
);
|
|
2105
|
+
entered.merge(sel).selectAll("path").attr("d", (_d, i) => slabs[i] ?? "").attr("fill", ctx.textures.pad.url()).attr("stroke", ctx.theme.cementPad.stroke).attr("stroke-width", ctx.theme.cementPad.strokeWidth).attr("stroke-linejoin", "round");
|
|
2106
|
+
}
|
|
2107
|
+
function layoutConstruction(ctx, animate = false) {
|
|
2108
|
+
const c = ctx.classes;
|
|
2109
|
+
const scales = outlineScales(ctx);
|
|
2110
|
+
const data = ctx.constructionData;
|
|
2111
|
+
const motion = (sel) => animate ? withTransition(sel, ctx.transition) : sel;
|
|
2112
|
+
const yTop = (d) => ctx.yScale(Math.max(d.from, ctx.depthFrom));
|
|
2113
|
+
const yBottom = (d) => ctx.yScale(Math.min(d.to, ctx.depthTo));
|
|
2114
|
+
const collapsed = (d) => ({
|
|
2115
|
+
...scales,
|
|
2116
|
+
y: () => yTop(d)
|
|
2117
|
+
});
|
|
2118
|
+
const shapeParts = (items, part, attr, shape) => {
|
|
2119
|
+
const parts = items.select(part);
|
|
2120
|
+
if (animate)
|
|
2121
|
+
parts.filter(function() {
|
|
2122
|
+
return entering.has(this.parentNode);
|
|
2123
|
+
}).attr(attr, (d) => shape(d, collapsed(d)));
|
|
2124
|
+
motion(parts).attr(attr, (d) => shape(d, scales));
|
|
2125
|
+
};
|
|
2126
|
+
const layoutLayer = (group, cls, diameter, outline, {
|
|
2127
|
+
shoe: shoe2,
|
|
2128
|
+
ends,
|
|
2129
|
+
fill
|
|
2130
|
+
} = {}) => {
|
|
2131
|
+
const items = group.selectAll(`g.${cls}`);
|
|
2132
|
+
shapeParts(items, `.${cls}-outline`, "d", outline);
|
|
2133
|
+
if (shoe2) shapeParts(items, `.${cls}-shoe`, "d", shoe2);
|
|
2134
|
+
if (ends) shapeParts(items, `.${cls}-ends`, "d", ends);
|
|
2135
|
+
if (fill) {
|
|
2136
|
+
shapeParts(items, `.${cls}-fill`, "d", fill);
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
motion(
|
|
2140
|
+
items.select(`.${cls}-fill`).attr("x", (d) => scales.left(diameter(d))).attr(
|
|
2141
|
+
"width",
|
|
2142
|
+
(d) => scales.right(diameter(d)) - scales.left(diameter(d))
|
|
2143
|
+
)
|
|
2144
|
+
).attr("y", yTop).attr("height", (d) => Math.max(0, yBottom(d) - yTop(d)));
|
|
2145
|
+
};
|
|
2146
|
+
const walls = (d, s, dia = d.diameter) => pipeWallsPath(
|
|
2147
|
+
s.left(dia),
|
|
2148
|
+
s.right(dia),
|
|
2149
|
+
s.y(Math.max(d.from, s.depthFrom)),
|
|
2150
|
+
s.y(Math.min(d.to, s.depthTo))
|
|
2151
|
+
);
|
|
2152
|
+
layoutLayer(
|
|
2153
|
+
ctx.groups.holeGroup,
|
|
2154
|
+
c.boreHole.rect,
|
|
2155
|
+
(d) => d.diameter,
|
|
2156
|
+
(d, s) => boreHoleOutlinePath(d, data.bore_hole, s)
|
|
2157
|
+
);
|
|
2158
|
+
const pipes = [...data.well_case, ...data.well_screen];
|
|
2159
|
+
const insideSurface = [...data.bore_hole, ...data.hole_fill, ...pipes];
|
|
2160
|
+
const scDiameter = (d) => surfaceCaseDiameter(ctx, d.diameter);
|
|
2161
|
+
layoutLayer(
|
|
2162
|
+
ctx.groups.surfaceCaseGroup,
|
|
2163
|
+
c.surfaceCase.rect,
|
|
2164
|
+
scDiameter,
|
|
2165
|
+
(d, s) => walls(d, s, scDiameter(d)),
|
|
2166
|
+
// Only the ring outside the hole: the texture never shows under the casing.
|
|
2167
|
+
{
|
|
2168
|
+
fill: (d, s) => annulusFillPath({ ...d, diameter: scDiameter(d) }, insideSurface, s)
|
|
2169
|
+
}
|
|
2170
|
+
);
|
|
2171
|
+
layoutLayer(
|
|
2172
|
+
ctx.groups.holeFillGroup,
|
|
2173
|
+
c.holeFill.rect,
|
|
2174
|
+
(d) => d.diameter,
|
|
2175
|
+
(d, s) => holeFillOutlinePath(d, pipes, s),
|
|
2176
|
+
{ fill: (d, s) => annulusFillPath(d, pipes, s) }
|
|
2177
|
+
);
|
|
2178
|
+
const string = [...pipes, ...data.reduction ?? []];
|
|
2179
|
+
const shoeCfg = ctx.renderConfig.construction.casingShoe;
|
|
2180
|
+
const endsCfg = ctx.renderConfig.construction.screenEnds;
|
|
2181
|
+
const room = (d, depth, size) => {
|
|
2182
|
+
const hole = diameterAt(data.bore_hole, depth);
|
|
2183
|
+
const annulus = hole !== void 0 && hole > d.diameter ? scales.left(d.diameter) - scales.left(hole) - 1 : size;
|
|
2184
|
+
return Math.max(2, Math.min(size, annulus));
|
|
2185
|
+
};
|
|
2186
|
+
const shoe = (d, s) => {
|
|
2187
|
+
const ends = getIntervalEnds(d, string, ctx.depthFrom, ctx.depthTo);
|
|
2188
|
+
if (!shoeCfg.active || ends.cutBottom || ends.joinedBottom) return "";
|
|
2189
|
+
return shoePath(
|
|
2190
|
+
s.left(d.diameter),
|
|
2191
|
+
s.right(d.diameter),
|
|
2192
|
+
s.y(Math.min(d.to, s.depthTo)),
|
|
2193
|
+
room(d, d.to, shoeCfg.size)
|
|
2194
|
+
);
|
|
2195
|
+
};
|
|
2196
|
+
const screenEnds = (d, s) => {
|
|
2197
|
+
if (!endsCfg.active) return "";
|
|
2198
|
+
const ends = getIntervalEnds(d, string, ctx.depthFrom, ctx.depthTo);
|
|
2199
|
+
const mark = (depth) => screenEndPath(s.left(d.diameter), s.right(d.diameter), s.y(depth));
|
|
2200
|
+
return (ends.cutTop ? "" : mark(d.from)) + (ends.cutBottom ? "" : mark(d.to));
|
|
2201
|
+
};
|
|
2202
|
+
layoutLayer(
|
|
2203
|
+
ctx.groups.wellCaseGroup,
|
|
2204
|
+
c.wellCase.rect,
|
|
2205
|
+
(d) => d.diameter,
|
|
2206
|
+
walls,
|
|
2207
|
+
{ shoe }
|
|
2208
|
+
);
|
|
2209
|
+
layoutLayer(
|
|
2210
|
+
ctx.groups.wellScreenGroup,
|
|
2211
|
+
c.wellScreen.rect,
|
|
2212
|
+
(d) => d.diameter,
|
|
2213
|
+
walls,
|
|
2214
|
+
{ shoe, ends: screenEnds }
|
|
2215
|
+
);
|
|
2216
|
+
const reductions = ctx.groups.reductionGroup.selectAll(`g.${c.reduction.item}`);
|
|
2217
|
+
const corners = (d, s) => {
|
|
2218
|
+
const t = s.y(Math.max(d.from, s.depthFrom));
|
|
2219
|
+
const b = s.y(Math.min(d.to, s.depthTo));
|
|
2220
|
+
return {
|
|
2221
|
+
tl: `${s.left(d.diam_from)},${t}`,
|
|
2222
|
+
tr: `${s.right(d.diam_from)},${t}`,
|
|
2223
|
+
bl: `${s.left(d.diam_to)},${b}`,
|
|
2224
|
+
br: `${s.right(d.diam_to)},${b}`
|
|
2225
|
+
};
|
|
2226
|
+
};
|
|
2227
|
+
shapeParts(reductions, `.${c.reduction.item}-fill`, "points", (d, s) => {
|
|
2228
|
+
const p = corners(d, s);
|
|
2229
|
+
return `${p.tl} ${p.tr} ${p.br} ${p.bl}`;
|
|
2230
|
+
});
|
|
2231
|
+
shapeParts(reductions, `.${c.reduction.item}-outline`, "d", (d, s) => {
|
|
2232
|
+
const p = corners(d, s);
|
|
2233
|
+
return `M${p.tl}L${p.bl}M${p.tr}L${p.br}`;
|
|
2234
|
+
});
|
|
2235
|
+
if (animate) {
|
|
2236
|
+
for (const group of [
|
|
2237
|
+
ctx.groups.holeGroup,
|
|
2238
|
+
ctx.groups.surfaceCaseGroup,
|
|
2239
|
+
ctx.groups.holeFillGroup,
|
|
2240
|
+
ctx.groups.wellCaseGroup,
|
|
2241
|
+
ctx.groups.wellScreenGroup,
|
|
2242
|
+
ctx.groups.reductionGroup
|
|
2243
|
+
])
|
|
2244
|
+
group.selectAll("g").each(function() {
|
|
2245
|
+
entering.delete(this);
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
1566
2249
|
function drawConstructive(ctx, data) {
|
|
1567
2250
|
const { getHeight, getYPos } = getYAxisFunctions(ctx.yScale, {
|
|
1568
2251
|
from: ctx.depthFrom,
|
|
1569
2252
|
to: ctx.depthTo
|
|
1570
2253
|
});
|
|
1571
|
-
const
|
|
1572
|
-
const
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
).attr("
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
withTransition(mergedHole, ctx.transition).attr("y", getYPos).attr("height", getHeight);
|
|
1598
|
-
const surfaceCaseGs = ctx.groups.surfaceCaseGroup.selectAll(`g.${ctx.classes.surfaceCase.rect}`).data(data.surface_case, makeIntervalKey("surface_case"));
|
|
1599
|
-
surfaceCaseGs.exit().transition(ctx.transition).style("opacity", 0).remove();
|
|
1600
|
-
const newSC = surfaceCaseGs.enter().append("g").attr("class", ctx.classes.surfaceCase.rect).on("mouseover", ctx.tooltips.surfaceCase.show).on("mouseout", ctx.tooltips.surfaceCase.hide);
|
|
1601
|
-
newSC.append("rect").attr("class", "surface-case-fill").attr("stroke", "none").attr("y", yPos).attr("height", 0);
|
|
1602
|
-
newSC.append("line").attr("class", "surface-case-side").attr("stroke", ctx.theme.surfaceCase.stroke).attr("stroke-width", ctx.theme.surfaceCase.strokeWidth);
|
|
1603
|
-
newSC.append("line").attr("class", "surface-case-side").attr("stroke", ctx.theme.surfaceCase.stroke).attr("stroke-width", ctx.theme.surfaceCase.strokeWidth);
|
|
1604
|
-
const mergedSC = mergeEnter(newSC, surfaceCaseGs);
|
|
1605
|
-
mergedSC.each((d, i, nodes) => {
|
|
1606
|
-
const x = (ctx.POCO_CENTER - xScale(
|
|
1607
|
-
d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio
|
|
1608
|
-
)) / 2;
|
|
1609
|
-
const w = xScale(
|
|
1610
|
-
d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio
|
|
2254
|
+
const c = ctx.classes;
|
|
2255
|
+
const theme = ctx.theme;
|
|
2256
|
+
drawCementPad(ctx, data.cement_pad);
|
|
2257
|
+
joinIntervalLayer(
|
|
2258
|
+
ctx,
|
|
2259
|
+
ctx.groups.holeGroup,
|
|
2260
|
+
c.boreHole.rect,
|
|
2261
|
+
data.bore_hole,
|
|
2262
|
+
"bore_hole",
|
|
2263
|
+
ctx.tooltips.hole
|
|
2264
|
+
).attr("opacity", theme.boreHole.opacity).call((g) => {
|
|
2265
|
+
g.select(`.${c.boreHole.rect}-fill`).attr("fill", theme.boreHole.fill);
|
|
2266
|
+
g.select(`.${c.boreHole.rect}-outline`).attr("stroke", theme.boreHole.stroke).attr("stroke-width", theme.boreHole.strokeWidth).attr("stroke-dasharray", theme.boreHole.strokeDasharray);
|
|
2267
|
+
});
|
|
2268
|
+
joinIntervalLayer(
|
|
2269
|
+
ctx,
|
|
2270
|
+
ctx.groups.surfaceCaseGroup,
|
|
2271
|
+
c.surfaceCase.rect,
|
|
2272
|
+
data.surface_case,
|
|
2273
|
+
"surface_case",
|
|
2274
|
+
ctx.tooltips.surfaceCase,
|
|
2275
|
+
{ pathFill: true }
|
|
2276
|
+
).call((g) => {
|
|
2277
|
+
g.select(`.${c.surfaceCase.rect}-fill`).attr(
|
|
2278
|
+
"fill",
|
|
2279
|
+
ctx.textures.surface_case.url()
|
|
1611
2280
|
);
|
|
1612
|
-
|
|
1613
|
-
g.select(".surface-case-fill").attr("x", x).attr("width", w).attr("fill", ctx.textures.surface_case.url());
|
|
1614
|
-
const sideNodes = g.selectAll(".surface-case-side").nodes();
|
|
1615
|
-
d34.select(sideNodes[0]).attr("x1", x).attr("x2", x);
|
|
1616
|
-
d34.select(sideNodes[1]).attr("x1", x + w).attr("x2", x + w);
|
|
2281
|
+
g.select(`.${c.surfaceCase.rect}-outline`).attr("stroke", theme.surfaceCase.stroke).attr("stroke-width", theme.surfaceCase.strokeWidth);
|
|
1617
2282
|
});
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
ctx.
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
"
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
2283
|
+
joinIntervalLayer(
|
|
2284
|
+
ctx,
|
|
2285
|
+
ctx.groups.holeFillGroup,
|
|
2286
|
+
c.holeFill.rect,
|
|
2287
|
+
data.hole_fill,
|
|
2288
|
+
"hole_fill",
|
|
2289
|
+
ctx.tooltips.holeFill,
|
|
2290
|
+
{ pathFill: true }
|
|
2291
|
+
).call((g) => {
|
|
2292
|
+
g.select(`.${c.holeFill.rect}-fill`).attr(
|
|
2293
|
+
"fill",
|
|
2294
|
+
(d) => ctx.textures[d.type].url()
|
|
2295
|
+
);
|
|
2296
|
+
g.select(`.${c.holeFill.rect}-outline`).attr("stroke", theme.holeFill.stroke).attr("stroke-width", theme.holeFill.strokeWidth);
|
|
2297
|
+
});
|
|
2298
|
+
for (const [group, cls, items, key, tooltip, fill, stroke] of [
|
|
2299
|
+
[
|
|
2300
|
+
ctx.groups.wellCaseGroup,
|
|
2301
|
+
c.wellCase.rect,
|
|
2302
|
+
data.well_case,
|
|
2303
|
+
"well_case",
|
|
2304
|
+
ctx.tooltips.wellCase,
|
|
2305
|
+
theme.wellCase.fill,
|
|
2306
|
+
theme.wellCase
|
|
2307
|
+
],
|
|
2308
|
+
[
|
|
2309
|
+
ctx.groups.wellScreenGroup,
|
|
2310
|
+
c.wellScreen.rect,
|
|
2311
|
+
data.well_screen,
|
|
2312
|
+
"well_screen",
|
|
2313
|
+
ctx.tooltips.wellScreen,
|
|
2314
|
+
ctx.textures.well_screen.url(),
|
|
2315
|
+
theme.wellScreen
|
|
2316
|
+
]
|
|
2317
|
+
]) {
|
|
2318
|
+
joinIntervalLayer(ctx, group, cls, items, key, tooltip, {
|
|
2319
|
+
shoe: true,
|
|
2320
|
+
ends: cls === c.wellScreen.rect
|
|
2321
|
+
}).call((g) => {
|
|
2322
|
+
g.select(`.${cls}-fill`).attr("fill", fill);
|
|
2323
|
+
g.select(`.${cls}-outline`).attr("stroke", stroke.stroke).attr("stroke-width", stroke.strokeWidth);
|
|
2324
|
+
g.select(`.${cls}-shoe`).attr("fill", stroke.stroke).attr("stroke", stroke.stroke).attr("stroke-width", 0.5);
|
|
2325
|
+
g.select(`.${cls}-ends`).attr("stroke", stroke.stroke).attr("stroke-width", theme.wellScreen.endStrokeWidth).attr("stroke-dasharray", theme.wellScreen.endDasharray);
|
|
2326
|
+
});
|
|
2327
|
+
}
|
|
2328
|
+
const reduction = ctx.groups.reductionGroup.selectAll(`g.${c.reduction.item}`).data(data.reduction ?? [], makeIntervalKey("reduction"));
|
|
1649
2329
|
reduction.exit().transition(ctx.transition).style("opacity", 0).remove();
|
|
1650
|
-
const
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
2330
|
+
const newReduction = reduction.enter().append("g").attr("class", c.reduction.item).each((_d, i, nodes) => entering.add(nodes[i])).on("mouseover", ctx.tooltips.reduction.show).on("mouseout", ctx.tooltips.reduction.hide);
|
|
2331
|
+
newReduction.append("polygon").attr("class", `${c.reduction.item}-fill`).attr("stroke", "none");
|
|
2332
|
+
newReduction.append("path").attr("class", `${c.reduction.item}-outline`).attr("fill", "none");
|
|
2333
|
+
newReduction.merge(reduction).call((g) => {
|
|
2334
|
+
g.select(`.${c.reduction.item}-fill`).attr("fill", theme.reduction.fill);
|
|
2335
|
+
g.select(`.${c.reduction.item}-outline`).attr("stroke", theme.reduction.stroke).attr("stroke-width", theme.reduction.strokeWidth);
|
|
2336
|
+
});
|
|
2337
|
+
const mergedConflicts = mergeConflicts(
|
|
2338
|
+
[
|
|
2339
|
+
...getConflictAreas(data.well_case, data.well_screen),
|
|
2340
|
+
...getConflictAreas(data.well_screen, data.well_case)
|
|
2341
|
+
],
|
|
2342
|
+
1
|
|
1660
2343
|
);
|
|
1661
|
-
const
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
const mergedConflicts = mergeConflicts(conflictAreas, 1);
|
|
1665
|
-
const conflict = ctx.groups.conflictGroup.selectAll(`.${ctx.classes.conflict.rect}`).data(mergedConflicts, makeIntervalKey("conflict"));
|
|
2344
|
+
const xScale = constructionXScale(ctx);
|
|
2345
|
+
const yPos = getYPos;
|
|
2346
|
+
const conflict = ctx.groups.conflictGroup.selectAll(`.${c.conflict.rect}`).data(mergedConflicts, makeIntervalKey("conflict"));
|
|
1666
2347
|
conflict.exit().transition(ctx.transition).attr("height", 0).remove();
|
|
1667
|
-
const newConflict = conflict.enter().append("rect").attr("class",
|
|
2348
|
+
const newConflict = conflict.enter().append("rect").attr("class", c.conflict.rect).attr("fill", ctx.textures.conflict.url()).attr("stroke", theme.conflict.stroke).attr("stroke-width", theme.conflict.strokeWidth).on("mouseover", ctx.tooltips.conflict.show).on("mouseout", ctx.tooltips.conflict.hide).attr("y", yPos).attr("height", 0);
|
|
1668
2349
|
const mergedConflict = mergeEnter(newConflict, conflict).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
|
|
1669
|
-
withTransition(mergedConflict, ctx.transition).attr("y",
|
|
2350
|
+
withTransition(mergedConflict, ctx.transition).attr("y", getYPos).attr("height", getHeight);
|
|
2351
|
+
layoutConstruction(ctx, true);
|
|
1670
2352
|
}
|
|
1671
2353
|
|
|
1672
2354
|
// src/renderers/fractures.renderer.ts
|
|
@@ -1682,7 +2364,6 @@ function wavyLine(rng, steps, baseY, jitter, startInset, endInset) {
|
|
|
1682
2364
|
return pts;
|
|
1683
2365
|
}
|
|
1684
2366
|
function drawFractures(ctx, data) {
|
|
1685
|
-
if (!data.length) return;
|
|
1686
2367
|
const {
|
|
1687
2368
|
groups: { fracturesGroup },
|
|
1688
2369
|
POCO_WIDTH,
|
|
@@ -1704,7 +2385,7 @@ function drawFractures(ctx, data) {
|
|
|
1704
2385
|
const merged = mergeEnter(entered, groups);
|
|
1705
2386
|
merged.attr(
|
|
1706
2387
|
"transform",
|
|
1707
|
-
(fracture) => `translate(0,${yScale(fracture.depth)}) rotate(${fracture.dip},${pocoCenterX},0)`
|
|
2388
|
+
(fracture) => `translate(0,${yScale(fracture.depth)}) rotate(${fractureDip(fracture.dip)},${pocoCenterX},0)`
|
|
1708
2389
|
);
|
|
1709
2390
|
merged.each(function(fracture) {
|
|
1710
2391
|
const g = d35.select(this);
|
|
@@ -1849,24 +2530,26 @@ function drawHighlights(ctx, hl) {
|
|
|
1849
2530
|
const maxXVals = (0, import_utils6.getProfileDiamValues)(ctx.constructionData);
|
|
1850
2531
|
const xScaleConstr = d36.scaleLinear().domain([0, d36.max(maxXVals) || 0]).range([0, ctx.POCO_WIDTH]);
|
|
1851
2532
|
const constructionConfig = ctx.renderConfig.construction;
|
|
1852
|
-
if (hl.cement_pad && ctx.depthFrom
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
const cpY = ctx.yScale(0) - ctx.yScale(
|
|
1857
|
-
cp.thickness * constructionConfig.cementPad.thicknessMultiplier
|
|
2533
|
+
if (hl.cement_pad && ctx.depthFrom <= 0 && ctx.depthTo > 0 && ctx.constructionData.cement_pad?.thickness) {
|
|
2534
|
+
const { opening, outer } = getPadDiameters(
|
|
2535
|
+
ctx.constructionData,
|
|
2536
|
+
constructionConfig.surfaceCase.diameterPaddingRatio
|
|
1858
2537
|
);
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
|
|
2538
|
+
const pad = getCementPadRect(
|
|
2539
|
+
ctx.POCO_WIDTH,
|
|
2540
|
+
ctx.POCO_CENTER,
|
|
2541
|
+
ctx.yScale(0),
|
|
2542
|
+
constructionConfig.cementPad,
|
|
2543
|
+
xScaleConstr(opening),
|
|
2544
|
+
xScaleConstr(outer)
|
|
1862
2545
|
);
|
|
1863
2546
|
drawHighlightItem(
|
|
1864
2547
|
ctx,
|
|
1865
2548
|
ctx.groups.highlightsConstructionGroup,
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2549
|
+
pad.x,
|
|
2550
|
+
pad.y,
|
|
2551
|
+
pad.width,
|
|
2552
|
+
pad.height,
|
|
1870
2553
|
hl.cement_pad.label
|
|
1871
2554
|
);
|
|
1872
2555
|
}
|
|
@@ -1942,8 +2625,12 @@ function drawHighlights(ctx, hl) {
|
|
|
1942
2625
|
// src/renderers/legend.renderer.ts
|
|
1943
2626
|
var d3module = __toESM(require("d3"), 1);
|
|
1944
2627
|
var import_defu = require("defu");
|
|
2628
|
+
var import_utils7 = require("@welldot/utils");
|
|
1945
2629
|
var d37 = { ...d3module };
|
|
1946
|
-
|
|
2630
|
+
var SYMBOL_WIDTH = 24;
|
|
2631
|
+
var SYMBOL_HEIGHT = 12;
|
|
2632
|
+
var SYMBOL_MARGIN = 2;
|
|
2633
|
+
function getWellLegendItems(profile, labels = INTERACTIVE_RENDER_CONFIG.legend.labels) {
|
|
1947
2634
|
const fractures = profile.fractures ?? [];
|
|
1948
2635
|
const caves = profile.caves ?? [];
|
|
1949
2636
|
const boreHoles = profile.bore_hole ?? [];
|
|
@@ -1964,6 +2651,7 @@ function drawWellLegend(selector, profile, options = {}) {
|
|
|
1964
2651
|
const hasWellScreen = wellScreens.length > 0;
|
|
1965
2652
|
const hasReduction = reductions.length > 0;
|
|
1966
2653
|
const hasCentralizer = (profile.centralizers ?? []).length > 0;
|
|
2654
|
+
const hasPump = (0, import_utils7.getCurrentPump)(profile)?.intake_depth !== void 0;
|
|
1967
2655
|
const hasCementPad = !!profile.cement_pad?.thickness;
|
|
1968
2656
|
const hasConflict = mergeConflicts(
|
|
1969
2657
|
[
|
|
@@ -1972,222 +2660,314 @@ function drawWellLegend(selector, profile, options = {}) {
|
|
|
1972
2660
|
],
|
|
1973
2661
|
1
|
|
1974
2662
|
).length > 0;
|
|
1975
|
-
const cfg = (0, import_defu.defu)(
|
|
1976
|
-
options.config ?? {},
|
|
1977
|
-
INTERACTIVE_RENDER_CONFIG.legend
|
|
1978
|
-
);
|
|
1979
|
-
const theme = (0, import_defu.defu)(options.theme ?? {}, DEFAULT_WELL_THEME);
|
|
1980
|
-
const cls = options.classNames ? { ...DEFAULT_COMPONENTS_CLASS_NAMES.legend, ...options.classNames } : DEFAULT_COMPONENTS_CLASS_NAMES.legend;
|
|
1981
2663
|
const items = [];
|
|
1982
2664
|
if (hasSimple)
|
|
1983
2665
|
items.push({
|
|
1984
2666
|
kind: "fracture",
|
|
1985
|
-
|
|
2667
|
+
key: "fractureSingle",
|
|
2668
|
+
label: labels.fractureSingle,
|
|
1986
2669
|
swarm: false,
|
|
1987
2670
|
water_intake: false
|
|
1988
2671
|
});
|
|
1989
2672
|
if (hasSwarm)
|
|
1990
2673
|
items.push({
|
|
1991
2674
|
kind: "fracture",
|
|
1992
|
-
|
|
2675
|
+
key: "fractureSwarm",
|
|
2676
|
+
label: labels.fractureSwarm,
|
|
1993
2677
|
swarm: true,
|
|
1994
2678
|
water_intake: false
|
|
1995
2679
|
});
|
|
1996
2680
|
if (hasWaterFx)
|
|
1997
2681
|
items.push({
|
|
1998
2682
|
kind: "fracture",
|
|
1999
|
-
|
|
2683
|
+
key: "fractureWater",
|
|
2684
|
+
label: labels.fractureWater,
|
|
2000
2685
|
swarm: false,
|
|
2001
2686
|
water_intake: true
|
|
2002
2687
|
});
|
|
2003
2688
|
if (hasCaveDry)
|
|
2004
2689
|
items.push({
|
|
2005
2690
|
kind: "cave",
|
|
2006
|
-
|
|
2691
|
+
key: "caveDry",
|
|
2692
|
+
label: labels.caveDry,
|
|
2007
2693
|
water_intake: false
|
|
2008
2694
|
});
|
|
2009
2695
|
if (hasCaveWet)
|
|
2010
|
-
items.push({
|
|
2696
|
+
items.push({
|
|
2697
|
+
kind: "cave",
|
|
2698
|
+
key: "caveWet",
|
|
2699
|
+
label: labels.caveWet,
|
|
2700
|
+
water_intake: true
|
|
2701
|
+
});
|
|
2011
2702
|
if (hasCementPad)
|
|
2012
2703
|
items.push({
|
|
2013
2704
|
kind: "construction",
|
|
2014
|
-
|
|
2705
|
+
key: "cementPad",
|
|
2706
|
+
label: labels.cementPad,
|
|
2015
2707
|
subKind: "cementPad"
|
|
2016
2708
|
});
|
|
2017
2709
|
if (hasBoreHole)
|
|
2018
2710
|
items.push({
|
|
2019
2711
|
kind: "construction",
|
|
2020
|
-
|
|
2712
|
+
key: "boreHole",
|
|
2713
|
+
label: labels.boreHole,
|
|
2021
2714
|
subKind: "boreHole"
|
|
2022
2715
|
});
|
|
2023
2716
|
if (hasSurfaceCase)
|
|
2024
2717
|
items.push({
|
|
2025
2718
|
kind: "construction",
|
|
2026
|
-
|
|
2719
|
+
key: "surfaceCase",
|
|
2720
|
+
label: labels.surfaceCase,
|
|
2027
2721
|
subKind: "surfaceCase"
|
|
2028
2722
|
});
|
|
2029
2723
|
if (hasHoleFillGravel)
|
|
2030
2724
|
items.push({
|
|
2031
2725
|
kind: "construction",
|
|
2032
|
-
|
|
2726
|
+
key: "holeFillGravel",
|
|
2727
|
+
label: labels.holeFillGravel,
|
|
2033
2728
|
subKind: "holeFillGravel"
|
|
2034
2729
|
});
|
|
2035
2730
|
if (hasHoleFillSeal)
|
|
2036
2731
|
items.push({
|
|
2037
2732
|
kind: "construction",
|
|
2038
|
-
|
|
2733
|
+
key: "holeFillSeal",
|
|
2734
|
+
label: labels.holeFillSeal,
|
|
2039
2735
|
subKind: "holeFillSeal"
|
|
2040
2736
|
});
|
|
2041
2737
|
if (hasWellCase)
|
|
2042
2738
|
items.push({
|
|
2043
2739
|
kind: "construction",
|
|
2044
|
-
|
|
2740
|
+
key: "wellCase",
|
|
2741
|
+
label: labels.wellCase,
|
|
2045
2742
|
subKind: "wellCase"
|
|
2046
2743
|
});
|
|
2047
2744
|
if (hasWellScreen)
|
|
2048
2745
|
items.push({
|
|
2049
2746
|
kind: "construction",
|
|
2050
|
-
|
|
2747
|
+
key: "wellScreen",
|
|
2748
|
+
label: labels.wellScreen,
|
|
2051
2749
|
subKind: "wellScreen"
|
|
2052
2750
|
});
|
|
2053
2751
|
if (hasReduction)
|
|
2054
2752
|
items.push({
|
|
2055
2753
|
kind: "construction",
|
|
2056
|
-
|
|
2754
|
+
key: "reduction",
|
|
2755
|
+
label: labels.reduction,
|
|
2057
2756
|
subKind: "reduction"
|
|
2058
2757
|
});
|
|
2059
2758
|
if (hasCentralizer)
|
|
2060
2759
|
items.push({
|
|
2061
2760
|
kind: "construction",
|
|
2062
|
-
|
|
2761
|
+
key: "centralizer",
|
|
2762
|
+
label: labels.centralizer,
|
|
2063
2763
|
subKind: "centralizer"
|
|
2064
2764
|
});
|
|
2765
|
+
if (hasPump)
|
|
2766
|
+
items.push({
|
|
2767
|
+
kind: "construction",
|
|
2768
|
+
key: "pump",
|
|
2769
|
+
label: labels.pump,
|
|
2770
|
+
subKind: "pump"
|
|
2771
|
+
});
|
|
2065
2772
|
if (hasConflict)
|
|
2066
2773
|
items.push({
|
|
2067
2774
|
kind: "construction",
|
|
2068
|
-
|
|
2775
|
+
key: "conflict",
|
|
2776
|
+
label: labels.conflict,
|
|
2069
2777
|
subKind: "conflict"
|
|
2070
2778
|
});
|
|
2779
|
+
return items;
|
|
2780
|
+
}
|
|
2781
|
+
function drawLegendSymbol(symG, item, cx, rowSymY, { theme, cls, textures: legendTextures }) {
|
|
2782
|
+
const RC = "round";
|
|
2783
|
+
const rw = SYMBOL_WIDTH;
|
|
2784
|
+
const rh = SYMBOL_HEIGHT;
|
|
2785
|
+
if (item.kind === "fracture") {
|
|
2786
|
+
const color = item.water_intake ? theme.fracture.wetStroke : theme.fracture.dryStroke;
|
|
2787
|
+
if (item.swarm) {
|
|
2788
|
+
[-4, 0, 4].forEach((offset) => {
|
|
2789
|
+
symG.append("polyline").attr("class", cls.fracturePoly).attr(
|
|
2790
|
+
"points",
|
|
2791
|
+
`${cx},${rowSymY + offset} ${cx + 6},${rowSymY + offset - 1} ${cx + 12},${rowSymY + offset + 1} ${cx + 18},${rowSymY + offset - 0.5} ${cx + 24},${rowSymY + offset}`
|
|
2792
|
+
).attr("stroke", color).attr(
|
|
2793
|
+
"stroke-width",
|
|
2794
|
+
offset !== 0 ? theme.legend.fractureSideStrokeWidth : theme.legend.fractureStrokeWidth
|
|
2795
|
+
).attr("fill", "none").attr("stroke-linecap", RC).attr("stroke-linejoin", RC);
|
|
2796
|
+
});
|
|
2797
|
+
} else {
|
|
2798
|
+
symG.append("polyline").attr("class", cls.fracturePoly).attr(
|
|
2799
|
+
"points",
|
|
2800
|
+
`${cx},${rowSymY} ${cx + 5},${rowSymY - 1.5} ${cx + 11},${rowSymY + 1} ${cx + 17},${rowSymY - 0.5} ${cx + 24},${rowSymY}`
|
|
2801
|
+
).attr("stroke", color).attr("stroke-width", theme.legend.fractureStrokeWidth).attr("fill", "none").attr("stroke-linecap", RC).attr("stroke-linejoin", RC);
|
|
2802
|
+
}
|
|
2803
|
+
} else if (item.kind === "cave") {
|
|
2804
|
+
const color = item.water_intake ? theme.cave.wetStroke : theme.cave.dryStroke;
|
|
2805
|
+
const texture = item.water_intake ? legendTextures.cave_wet : legendTextures.cave_dry;
|
|
2806
|
+
symG.append("rect").attr("class", cls.caveFill).attr("x", cx).attr("y", rowSymY - rh / 2).attr("width", rw).attr("height", rh).attr("fill", texture.url()).attr("stroke", color).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2807
|
+
} else if (item.subKind === "surfaceCase") {
|
|
2808
|
+
symG.append("rect").attr("class", cls.constructionRect).attr("x", cx).attr("y", rowSymY - rh / 2).attr("width", rw).attr("height", rh).attr("fill", legendTextures.surface_case.url()).attr("stroke", "none");
|
|
2809
|
+
symG.append("line").attr("class", cls.constructionRect).attr("x1", cx).attr("x2", cx).attr("y1", rowSymY - rh / 2).attr("y2", rowSymY + rh / 2).attr("stroke", theme.surfaceCase.stroke).attr("stroke-width", 2);
|
|
2810
|
+
symG.append("line").attr("class", cls.constructionRect).attr("x1", cx + rw).attr("x2", cx + rw).attr("y1", rowSymY - rh / 2).attr("y2", rowSymY + rh / 2).attr("stroke", theme.surfaceCase.stroke).attr("stroke-width", 2);
|
|
2811
|
+
} else if (item.subKind === "centralizer") {
|
|
2812
|
+
const pipeW = rw * 0.4;
|
|
2813
|
+
const pipeL = cx + (rw - pipeW) / 2;
|
|
2814
|
+
const pipeR = pipeL + pipeW;
|
|
2815
|
+
const y1 = rowSymY - rh / 2;
|
|
2816
|
+
const y2 = rowSymY + rh / 2;
|
|
2817
|
+
const bowH = rh * 0.3;
|
|
2818
|
+
for (const x of [pipeL, pipeR]) {
|
|
2819
|
+
symG.append("line").attr("class", cls.constructionRect).attr("x1", x).attr("x2", x).attr("y1", y1).attr("y2", y2).attr("stroke", theme.wellCase.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2820
|
+
}
|
|
2821
|
+
for (const [from, to] of [
|
|
2822
|
+
[pipeL, cx],
|
|
2823
|
+
[pipeR, cx + rw]
|
|
2824
|
+
]) {
|
|
2825
|
+
symG.append("polyline").attr("class", cls.constructionRect).attr(
|
|
2826
|
+
"points",
|
|
2827
|
+
`${from},${rowSymY - bowH} ${to},${rowSymY} ${from},${rowSymY + bowH}`
|
|
2828
|
+
).attr("fill", theme.centralizer.fill).attr("stroke", theme.centralizer.stroke).attr("stroke-width", theme.centralizer.strokeWidth);
|
|
2829
|
+
}
|
|
2830
|
+
} else if (item.subKind === "pump") {
|
|
2831
|
+
const y1 = rowSymY - rh / 2;
|
|
2832
|
+
const y2 = rowSymY + rh / 2;
|
|
2833
|
+
const midX = cx + rw / 2;
|
|
2834
|
+
const riserHalf = rw * 0.12;
|
|
2835
|
+
const bodyHalf = rw * 0.28;
|
|
2836
|
+
const bodyTop = y1 + rh * 0.4;
|
|
2837
|
+
symG.append("rect").attr("class", cls.constructionRect).attr("x", midX - riserHalf).attr("y", y1).attr("width", 2 * riserHalf).attr("height", bodyTop - y1).attr("fill", theme.pump.riserFill).attr("stroke", "none");
|
|
2838
|
+
symG.append("path").attr("class", cls.constructionRect).attr("d", pipeWallsPath(midX - riserHalf, midX + riserHalf, y1, bodyTop)).attr("fill", "none").attr("stroke", theme.pump.riserStroke).attr("stroke-width", theme.pump.riserStrokeWidth);
|
|
2839
|
+
symG.append("path").attr("class", cls.constructionRect).attr(
|
|
2840
|
+
"d",
|
|
2841
|
+
`M${midX - bodyHalf},${bodyTop}H${midX + bodyHalf}V${y2}H${midX - bodyHalf}Z`
|
|
2842
|
+
).attr("fill", theme.pump.fill).attr("stroke", theme.pump.stroke).attr("stroke-width", theme.pump.strokeWidth);
|
|
2843
|
+
} else if (item.subKind === "reduction") {
|
|
2844
|
+
const topW = rw * 0.5;
|
|
2845
|
+
const y1 = rowSymY - rh / 2;
|
|
2846
|
+
const y2 = rowSymY + rh / 2;
|
|
2847
|
+
const midX = cx + rw / 2;
|
|
2848
|
+
const tl = `${midX - topW / 2},${y1}`;
|
|
2849
|
+
const tr = `${midX + topW / 2},${y1}`;
|
|
2850
|
+
symG.append("polygon").attr("class", cls.constructionRect).attr("points", `${tl} ${tr} ${cx + rw},${y2} ${cx},${y2}`).attr("fill", theme.reduction.fill).attr("stroke", "none");
|
|
2851
|
+
symG.append("path").attr("class", cls.constructionRect).attr("d", `M${tl}L${cx},${y2}M${tr}L${cx + rw},${y2}`).attr("fill", "none").attr("stroke", theme.reduction.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2852
|
+
} else if (item.subKind === "wellCase" || item.subKind === "wellScreen" || item.subKind === "boreHole") {
|
|
2853
|
+
const y1 = rowSymY - rh / 2;
|
|
2854
|
+
const y2 = rowSymY + rh / 2;
|
|
2855
|
+
const shoe = 3;
|
|
2856
|
+
const xL = cx + shoe;
|
|
2857
|
+
const xR = cx + rw - shoe;
|
|
2858
|
+
const style = {
|
|
2859
|
+
wellCase: { fill: theme.wellCase.fill, stroke: theme.wellCase.stroke },
|
|
2860
|
+
wellScreen: {
|
|
2861
|
+
fill: legendTextures.well_screen.url(),
|
|
2862
|
+
stroke: theme.wellScreen.stroke
|
|
2863
|
+
},
|
|
2864
|
+
boreHole: { fill: theme.boreHole.fill, stroke: theme.boreHole.stroke }
|
|
2865
|
+
}[item.subKind];
|
|
2866
|
+
symG.append("rect").attr("class", cls.constructionRect).attr("x", xL).attr("y", y1).attr("width", xR - xL).attr("height", rh).attr("fill", style.fill).attr("stroke", "none");
|
|
2867
|
+
const walls = symG.append("path").attr("class", cls.constructionRect).attr(
|
|
2868
|
+
"d",
|
|
2869
|
+
pipeWallsPath(xL, xR, y1, y2) + (item.subKind === "boreHole" ? `M${xL},${y2}H${xR}` : "")
|
|
2870
|
+
).attr("fill", "none").attr("stroke", style.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2871
|
+
if (item.subKind === "boreHole")
|
|
2872
|
+
walls.attr("stroke-dasharray", theme.boreHole.strokeDasharray);
|
|
2873
|
+
if (item.subKind === "wellCase")
|
|
2874
|
+
symG.append("path").attr("class", cls.constructionRect).attr("d", shoePath(xL, xR, y2, shoe)).attr("fill", style.stroke).attr("stroke", "none");
|
|
2875
|
+
if (item.subKind === "wellScreen")
|
|
2876
|
+
symG.append("path").attr("class", cls.constructionRect).attr(
|
|
2877
|
+
"d",
|
|
2878
|
+
screenEndPath(xL, xR, y1 + 0.5) + screenEndPath(xL, xR, y2 - 0.5)
|
|
2879
|
+
).attr("fill", "none").attr("stroke", style.stroke).attr("stroke-width", theme.wellScreen.endStrokeWidth).attr("stroke-dasharray", "2, 1.5");
|
|
2880
|
+
} else if (item.subKind === "cementPad") {
|
|
2881
|
+
const h = rh * 0.6;
|
|
2882
|
+
const { slabs } = getCementPadGeometry(
|
|
2883
|
+
rw,
|
|
2884
|
+
2 * cx + rw,
|
|
2885
|
+
rowSymY + h / 2,
|
|
2886
|
+
{ widthRatio: 1, height: h },
|
|
2887
|
+
rw * 0.3
|
|
2888
|
+
);
|
|
2889
|
+
for (const d of slabs)
|
|
2890
|
+
symG.append("path").attr("class", cls.constructionRect).attr("d", d).attr("fill", legendTextures.pad.url()).attr("stroke", theme.cementPad.stroke).attr("stroke-width", theme.legend.itemStrokeWidth).attr("stroke-linejoin", RC);
|
|
2891
|
+
} else {
|
|
2892
|
+
const symMap = {
|
|
2893
|
+
holeFillGravel: {
|
|
2894
|
+
fill: legendTextures.gravel_pack.url(),
|
|
2895
|
+
stroke: theme.holeFill.stroke
|
|
2896
|
+
},
|
|
2897
|
+
holeFillSeal: {
|
|
2898
|
+
fill: legendTextures.seal.url(),
|
|
2899
|
+
stroke: theme.holeFill.stroke
|
|
2900
|
+
},
|
|
2901
|
+
conflict: {
|
|
2902
|
+
fill: legendTextures.conflict.url(),
|
|
2903
|
+
stroke: theme.conflict.stroke
|
|
2904
|
+
}
|
|
2905
|
+
};
|
|
2906
|
+
const sym = symMap[item.subKind];
|
|
2907
|
+
const symRect = symG.append("rect").attr("class", cls.constructionRect).attr("x", cx).attr("y", rowSymY - rh / 2).attr("width", rw).attr("height", rh).attr("fill", sym.fill).attr("stroke", sym.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2908
|
+
if (sym.dasharray) symRect.attr("stroke-dasharray", sym.dasharray);
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
function resolveStyle(options) {
|
|
2912
|
+
return {
|
|
2913
|
+
theme: (0, import_defu.defu)(options.theme ?? {}, DEFAULT_WELL_THEME),
|
|
2914
|
+
cls: options.classNames ? { ...DEFAULT_COMPONENTS_CLASS_NAMES.legend, ...options.classNames } : DEFAULT_COMPONENTS_CLASS_NAMES.legend,
|
|
2915
|
+
textures: createWellTextures(options.textures)
|
|
2916
|
+
};
|
|
2917
|
+
}
|
|
2918
|
+
function drawWellLegendSymbol(selector, item, options = {}) {
|
|
2919
|
+
const style = resolveStyle(options);
|
|
2920
|
+
const svgEl = d37.select(selector);
|
|
2921
|
+
svgEl.selectAll("*").remove();
|
|
2922
|
+
svgEl.attr("width", SYMBOL_WIDTH + SYMBOL_MARGIN * 2).attr("height", SYMBOL_HEIGHT + SYMBOL_MARGIN * 2);
|
|
2923
|
+
Object.values(style.textures).forEach((t) => svgEl.call(t));
|
|
2924
|
+
const symG = svgEl.append("g").attr("class", style.cls.item);
|
|
2925
|
+
drawLegendSymbol(
|
|
2926
|
+
symG,
|
|
2927
|
+
item,
|
|
2928
|
+
SYMBOL_MARGIN,
|
|
2929
|
+
SYMBOL_MARGIN + SYMBOL_HEIGHT / 2,
|
|
2930
|
+
style
|
|
2931
|
+
);
|
|
2932
|
+
}
|
|
2933
|
+
function drawWellLegend(selector, profile, options = {}) {
|
|
2934
|
+
const cfg = (0, import_defu.defu)(
|
|
2935
|
+
options.config ?? {},
|
|
2936
|
+
INTERACTIVE_RENDER_CONFIG.legend
|
|
2937
|
+
);
|
|
2938
|
+
const items = getWellLegendItems(profile, cfg.labels);
|
|
2071
2939
|
const svgEl = d37.select(selector);
|
|
2072
2940
|
svgEl.selectAll("*").remove();
|
|
2073
2941
|
if (items.length === 0) {
|
|
2074
2942
|
svgEl.attr("width", 0).attr("height", 0);
|
|
2075
2943
|
return;
|
|
2076
2944
|
}
|
|
2077
|
-
const
|
|
2078
|
-
|
|
2945
|
+
const style = resolveStyle(options);
|
|
2946
|
+
const { theme, cls } = style;
|
|
2947
|
+
Object.values(style.textures).forEach((t) => svgEl.call(t));
|
|
2079
2948
|
const itemsPerRow = cfg.maxWidth ? Math.max(1, Math.floor((cfg.maxWidth - cfg.padding * 2) / cfg.itemWidth)) : items.length;
|
|
2080
2949
|
const numRows = Math.ceil(items.length / itemsPerRow);
|
|
2081
2950
|
const rowWidth = Math.min(items.length, itemsPerRow) * cfg.itemWidth;
|
|
2082
2951
|
const totalWidth = cfg.padding * 2 + rowWidth;
|
|
2083
2952
|
const totalHeight = numRows * cfg.height;
|
|
2084
2953
|
svgEl.attr("width", totalWidth).attr("height", totalHeight);
|
|
2085
|
-
const RC = "round";
|
|
2086
2954
|
const g = svgEl.append("g").attr("transform", `translate(${cfg.padding}, 2)`);
|
|
2087
2955
|
g.append("rect").attr("class", cls.border).attr("x", 0).attr("y", 0).attr("width", totalWidth - cfg.padding).attr("height", totalHeight - 4).attr("fill", "white").attr("rx", cfg.borderRadius).attr("stroke-width", theme.legend.borderStrokeWidth);
|
|
2088
2956
|
g.append("text").attr("class", cls.title).attr("x", 4).attr("y", 11).attr("font-size", theme.legend.fontSize).attr("font-family", theme.legend.fontFamily ?? "sans-serif").attr("font-weight", theme.legend.titleFontWeight ?? "bold").text(`${cfg.title}:`);
|
|
2089
|
-
const rw = 24;
|
|
2090
|
-
const rh = 12;
|
|
2091
2957
|
items.forEach((item, i) => {
|
|
2092
2958
|
const col = i % itemsPerRow;
|
|
2093
2959
|
const row = Math.floor(i / itemsPerRow);
|
|
2094
2960
|
const rowSymY = row * cfg.height + (cfg.height - 4) / 2;
|
|
2095
2961
|
const cx = col * cfg.itemWidth;
|
|
2096
2962
|
const symG = g.append("g").attr("class", cls.item);
|
|
2097
|
-
|
|
2098
|
-
const color = item.water_intake ? theme.fracture.wetStroke : theme.fracture.dryStroke;
|
|
2099
|
-
if (item.swarm) {
|
|
2100
|
-
[-4, 0, 4].forEach((offset) => {
|
|
2101
|
-
symG.append("polyline").attr("class", cls.fracturePoly).attr(
|
|
2102
|
-
"points",
|
|
2103
|
-
`${cx},${rowSymY + offset} ${cx + 6},${rowSymY + offset - 1} ${cx + 12},${rowSymY + offset + 1} ${cx + 18},${rowSymY + offset - 0.5} ${cx + 24},${rowSymY + offset}`
|
|
2104
|
-
).attr("stroke", color).attr(
|
|
2105
|
-
"stroke-width",
|
|
2106
|
-
offset !== 0 ? theme.legend.fractureSideStrokeWidth : theme.legend.fractureStrokeWidth
|
|
2107
|
-
).attr("fill", "none").attr("stroke-linecap", RC).attr("stroke-linejoin", RC);
|
|
2108
|
-
});
|
|
2109
|
-
} else {
|
|
2110
|
-
symG.append("polyline").attr("class", cls.fracturePoly).attr(
|
|
2111
|
-
"points",
|
|
2112
|
-
`${cx},${rowSymY} ${cx + 5},${rowSymY - 1.5} ${cx + 11},${rowSymY + 1} ${cx + 17},${rowSymY - 0.5} ${cx + 24},${rowSymY}`
|
|
2113
|
-
).attr("stroke", color).attr("stroke-width", theme.legend.fractureStrokeWidth).attr("fill", "none").attr("stroke-linecap", RC).attr("stroke-linejoin", RC);
|
|
2114
|
-
}
|
|
2115
|
-
} else if (item.kind === "cave") {
|
|
2116
|
-
const color = item.water_intake ? theme.cave.wetStroke : theme.cave.dryStroke;
|
|
2117
|
-
const texture = item.water_intake ? legendTextures.cave_wet : legendTextures.cave_dry;
|
|
2118
|
-
symG.append("rect").attr("class", cls.caveFill).attr("x", cx).attr("y", rowSymY - rh / 2).attr("width", rw).attr("height", rh).attr("fill", texture.url()).attr("stroke", color).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2119
|
-
} else if (item.subKind === "surfaceCase") {
|
|
2120
|
-
symG.append("rect").attr("class", cls.constructionRect).attr("x", cx).attr("y", rowSymY - rh / 2).attr("width", rw).attr("height", rh).attr("fill", legendTextures.surface_case.url()).attr("stroke", "none");
|
|
2121
|
-
symG.append("line").attr("class", cls.constructionRect).attr("x1", cx).attr("x2", cx).attr("y1", rowSymY - rh / 2).attr("y2", rowSymY + rh / 2).attr("stroke", theme.surfaceCase.stroke).attr("stroke-width", 2);
|
|
2122
|
-
symG.append("line").attr("class", cls.constructionRect).attr("x1", cx + rw).attr("x2", cx + rw).attr("y1", rowSymY - rh / 2).attr("y2", rowSymY + rh / 2).attr("stroke", theme.surfaceCase.stroke).attr("stroke-width", 2);
|
|
2123
|
-
} else if (item.subKind === "centralizer") {
|
|
2124
|
-
const pipeW = rw * 0.4;
|
|
2125
|
-
const pipeL = cx + (rw - pipeW) / 2;
|
|
2126
|
-
const pipeR = pipeL + pipeW;
|
|
2127
|
-
const y1 = rowSymY - rh / 2;
|
|
2128
|
-
const y2 = rowSymY + rh / 2;
|
|
2129
|
-
const bowH = rh * 0.3;
|
|
2130
|
-
for (const x of [pipeL, pipeR]) {
|
|
2131
|
-
symG.append("line").attr("class", cls.constructionRect).attr("x1", x).attr("x2", x).attr("y1", y1).attr("y2", y2).attr("stroke", theme.wellCase.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2132
|
-
}
|
|
2133
|
-
for (const [from, to] of [
|
|
2134
|
-
[pipeL, cx],
|
|
2135
|
-
[pipeR, cx + rw]
|
|
2136
|
-
]) {
|
|
2137
|
-
symG.append("polyline").attr("class", cls.constructionRect).attr(
|
|
2138
|
-
"points",
|
|
2139
|
-
`${from},${rowSymY - bowH} ${to},${rowSymY} ${from},${rowSymY + bowH}`
|
|
2140
|
-
).attr("fill", theme.centralizer.fill).attr("stroke", theme.centralizer.stroke).attr("stroke-width", theme.centralizer.strokeWidth);
|
|
2141
|
-
}
|
|
2142
|
-
} else if (item.subKind === "reduction") {
|
|
2143
|
-
const topW = rw * 0.5;
|
|
2144
|
-
const y1 = rowSymY - rh / 2;
|
|
2145
|
-
const y2 = rowSymY + rh / 2;
|
|
2146
|
-
const midX = cx + rw / 2;
|
|
2147
|
-
symG.append("polygon").attr("class", cls.constructionRect).attr(
|
|
2148
|
-
"points",
|
|
2149
|
-
`${midX - topW / 2},${y1} ${midX + topW / 2},${y1} ${cx + rw},${y2} ${cx},${y2}`
|
|
2150
|
-
).attr("fill", theme.reduction.fill).attr("stroke", theme.reduction.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2151
|
-
} else {
|
|
2152
|
-
const symMap = {
|
|
2153
|
-
boreHole: {
|
|
2154
|
-
fill: theme.boreHole.fill,
|
|
2155
|
-
stroke: theme.boreHole.stroke,
|
|
2156
|
-
dasharray: theme.boreHole.strokeDasharray
|
|
2157
|
-
},
|
|
2158
|
-
holeFillGravel: {
|
|
2159
|
-
fill: legendTextures.gravel_pack.url(),
|
|
2160
|
-
stroke: theme.holeFill.stroke
|
|
2161
|
-
},
|
|
2162
|
-
holeFillSeal: {
|
|
2163
|
-
fill: legendTextures.seal.url(),
|
|
2164
|
-
stroke: theme.holeFill.stroke
|
|
2165
|
-
},
|
|
2166
|
-
wellCase: { fill: theme.wellCase.fill, stroke: theme.wellCase.stroke },
|
|
2167
|
-
wellScreen: {
|
|
2168
|
-
fill: legendTextures.well_screen.url(),
|
|
2169
|
-
stroke: theme.wellScreen.stroke
|
|
2170
|
-
},
|
|
2171
|
-
cementPad: {
|
|
2172
|
-
fill: legendTextures.pad.url(),
|
|
2173
|
-
stroke: theme.cementPad.stroke
|
|
2174
|
-
},
|
|
2175
|
-
conflict: {
|
|
2176
|
-
fill: legendTextures.conflict.url(),
|
|
2177
|
-
stroke: theme.conflict.stroke
|
|
2178
|
-
}
|
|
2179
|
-
};
|
|
2180
|
-
const sym = symMap[item.subKind];
|
|
2181
|
-
const symRect = symG.append("rect").attr("class", cls.constructionRect).attr("x", cx).attr("y", rowSymY - rh / 2).attr("width", rw).attr("height", rh).attr("fill", sym.fill).attr("stroke", sym.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
2182
|
-
if (sym.dasharray) symRect.attr("stroke-dasharray", sym.dasharray);
|
|
2183
|
-
}
|
|
2963
|
+
drawLegendSymbol(symG, item, cx, rowSymY, style);
|
|
2184
2964
|
g.append("text").attr("class", cls.label).attr("x", cx + 28).attr("y", rowSymY + 3).attr("font-size", theme.legend.fontSize).attr("font-family", theme.legend.fontFamily ?? "sans-serif").attr("font-weight", theme.legend.labelFontWeight ?? 400).text(item.label);
|
|
2185
2965
|
});
|
|
2186
2966
|
}
|
|
2187
2967
|
|
|
2188
2968
|
// src/renderers/lithology.renderer.ts
|
|
2969
|
+
var d38 = __toESM(require("d3"), 1);
|
|
2189
2970
|
function drawLithology(ctx, data) {
|
|
2190
|
-
if (!data.length) return;
|
|
2191
2971
|
const {
|
|
2192
2972
|
groups: { lithologyGroup },
|
|
2193
2973
|
svg,
|
|
@@ -2211,10 +2991,219 @@ function drawLithology(ctx, data) {
|
|
|
2211
2991
|
const merged = mergeEnter(newLayers, rects);
|
|
2212
2992
|
withTransition(merged, transition).attr("y", getYPos).attr("height", getHeight).attr("fill", getLithologyFill(data, svg, ctx.theme.lithologyTexture));
|
|
2213
2993
|
}
|
|
2994
|
+
function drawLithologySwatch(selector, layer, options) {
|
|
2995
|
+
const { size, theme } = options;
|
|
2996
|
+
const svg = d38.select(selector);
|
|
2997
|
+
svg.selectAll("*").remove();
|
|
2998
|
+
svg.attr("width", size).attr("height", size);
|
|
2999
|
+
const fill = getLithologyFill([layer], svg, {
|
|
3000
|
+
...theme.lithologyTexture,
|
|
3001
|
+
// Denser pattern so a few strokes show inside the small square.
|
|
3002
|
+
size: Math.max(12, size * 3)
|
|
3003
|
+
});
|
|
3004
|
+
svg.append("rect").attr("x", 0.5).attr("y", 0.5).attr("width", size - 1).attr("height", size - 1).attr("fill", fill(layer)).attr("stroke", theme.lithology.stroke).attr("stroke-width", 0.5);
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
// src/renderers/markers.renderer.ts
|
|
3008
|
+
function drawMarkers(ctx, data) {
|
|
3009
|
+
const group = ctx.groups.markersGroup;
|
|
3010
|
+
group.selectAll("*").remove();
|
|
3011
|
+
const cfg = ctx.renderConfig.markers;
|
|
3012
|
+
const theme = ctx.theme.markers;
|
|
3013
|
+
const r = cfg.radius;
|
|
3014
|
+
if (cfg.lithology) {
|
|
3015
|
+
const cx = (ctx.geoXLeft + ctx.geoXRight) / 2;
|
|
3016
|
+
getLithologyMarkers(data.lithology, ctx.depthFrom, ctx.depthTo).forEach(
|
|
3017
|
+
(marker) => {
|
|
3018
|
+
const top = ctx.yScale(marker.from);
|
|
3019
|
+
const bottom = ctx.yScale(marker.to);
|
|
3020
|
+
if (bottom - top < r) return;
|
|
3021
|
+
const cy = bottom - top >= 2 * r + 4 ? top + r + 2 : (top + bottom) / 2;
|
|
3022
|
+
const g = group.append("g").attr("class", ctx.classes.markers.lithology);
|
|
3023
|
+
g.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r).attr("fill", theme.fill).attr("stroke", theme.stroke).attr("stroke-width", theme.strokeWidth);
|
|
3024
|
+
g.append("text").attr("x", cx).attr("y", cy).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", theme.fontSize).attr("font-family", theme.fontFamily ?? "sans-serif").attr("font-weight", theme.fontWeight ?? 600).attr("fill", theme.color).text(String(marker.index));
|
|
3025
|
+
}
|
|
3026
|
+
);
|
|
3027
|
+
}
|
|
3028
|
+
if (cfg.fractures) {
|
|
3029
|
+
const x = ctx.pocoCenterX + ctx.POCO_WIDTH * ctx.renderConfig.fractures.widthMultiplier / 2 + 3;
|
|
3030
|
+
getFractureMarkers(data.fractures, ctx.depthFrom, ctx.depthTo).forEach(
|
|
3031
|
+
(marker) => {
|
|
3032
|
+
group.append("text").attr("class", ctx.classes.markers.fracture).attr("x", x).attr("y", ctx.yScale(marker.depth)).attr("dominant-baseline", "central").attr("font-size", theme.fontSize).attr("font-family", theme.fontFamily ?? "sans-serif").attr("font-weight", theme.fontWeight ?? 600).attr("fill", theme.color).text(marker.label);
|
|
3033
|
+
}
|
|
3034
|
+
);
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3037
|
+
|
|
3038
|
+
// src/renderers/overlap.renderer.ts
|
|
3039
|
+
var import_textures3 = __toESM(require("textures"), 1);
|
|
3040
|
+
var import_utils8 = require("@welldot/utils");
|
|
3041
|
+
function drawOverlap(ctx) {
|
|
3042
|
+
const group = ctx.groups.overlapGroup;
|
|
3043
|
+
group.selectAll("*").remove();
|
|
3044
|
+
const { repeatedTo, depthFrom } = ctx;
|
|
3045
|
+
if (repeatedTo == null || repeatedTo <= depthFrom) return;
|
|
3046
|
+
const theme = ctx.theme.overlap;
|
|
3047
|
+
const { margins } = ctx.state;
|
|
3048
|
+
const overview = ctx.renderConfig.overview;
|
|
3049
|
+
const showsDescription = hasDescriptionColumn(ctx);
|
|
3050
|
+
const x0 = -margins.left + (overview.active ? overview.x + overview.width + 4 : 0);
|
|
3051
|
+
const x1 = showsDescription ? ctx.geoXRight + ctx.renderConfig.labels.descriptionXOffset - 4 : ctx.svgWidth - margins.left;
|
|
3052
|
+
const y0 = ctx.yScale(depthFrom);
|
|
3053
|
+
const y1 = ctx.yScale(repeatedTo);
|
|
3054
|
+
const hatch = import_textures3.default.lines().size(theme.size).strokeWidth(theme.strokeWidth).stroke(theme.stroke);
|
|
3055
|
+
ctx.svg.call(hatch);
|
|
3056
|
+
group.append("rect").attr("class", ctx.classes.overlap.band).attr("x", x0).attr("y", y0).attr("width", Math.max(0, x1 - x0)).attr("height", Math.max(0, y1 - y0)).attr("fill", hatch.url()).style("pointer-events", "none");
|
|
3057
|
+
group.append("line").attr("x1", x0).attr("x2", ctx.svgWidth - margins.left).attr("y1", y1).attr("y2", y1).attr("stroke", theme.ruleStroke).attr("stroke-width", 0.6).attr("stroke-dasharray", "3, 2");
|
|
3058
|
+
const whole = (m) => (0, import_utils8.formatNumber)(ctx.units.length === "ft" ? m * 3.28084 : m, {
|
|
3059
|
+
maximumFractionDigits: 0,
|
|
3060
|
+
locale: ctx.locale
|
|
3061
|
+
});
|
|
3062
|
+
const unit = getLengthUnit(ctx.units.length);
|
|
3063
|
+
const range = `${whole(depthFrom)}\u2013${whole(repeatedTo)} ${unit}`;
|
|
3064
|
+
group.append("text").attr("class", ctx.classes.overlap.label).attr("x", ctx.svgWidth - margins.left - 2).attr("y", y0 + theme.fontSize + 1).attr("text-anchor", "end").attr("font-size", theme.fontSize).attr("font-family", theme.fontFamily ?? "monospace").attr("fill", theme.labelColor).text(formatOverlapLabel(ctx.renderConfig.overlap.label, range));
|
|
3065
|
+
}
|
|
3066
|
+
|
|
3067
|
+
// src/renderers/overview.renderer.ts
|
|
3068
|
+
function drawOverview(ctx, lithology) {
|
|
3069
|
+
const group = ctx.groups.overviewGroup;
|
|
3070
|
+
group.selectAll("*").remove();
|
|
3071
|
+
const cfg = ctx.renderConfig.overview;
|
|
3072
|
+
if (!cfg.active || lithology.length === 0 || ctx.totalDepth <= 0) return;
|
|
3073
|
+
const theme = ctx.theme.overview;
|
|
3074
|
+
const height = Math.min(cfg.height, ctx.state.height);
|
|
3075
|
+
const { y, window } = getOverviewGeometry(
|
|
3076
|
+
ctx.totalDepth,
|
|
3077
|
+
height,
|
|
3078
|
+
ctx.depthFrom,
|
|
3079
|
+
ctx.depthTo
|
|
3080
|
+
);
|
|
3081
|
+
lithology.forEach((layer) => {
|
|
3082
|
+
group.append("rect").attr("class", ctx.classes.overview.item).attr("x", cfg.x).attr("y", y(layer.from)).attr("width", cfg.width).attr("height", Math.max(0, y(layer.to) - y(layer.from))).attr("fill", layer.color || theme.emptyFill);
|
|
3083
|
+
});
|
|
3084
|
+
group.append("rect").attr("x", cfg.x).attr("y", 0).attr("width", cfg.width).attr("height", y(ctx.totalDepth)).attr("fill", "none").attr("stroke", theme.stroke).attr("stroke-width", theme.strokeWidth);
|
|
3085
|
+
group.append("rect").attr("class", ctx.classes.overview.window).attr("x", cfg.x - 2).attr("y", window.y).attr("width", cfg.width + 4).attr("height", window.height).attr("fill", "none").attr("stroke", theme.windowStroke).attr("stroke-width", theme.windowStrokeWidth);
|
|
3086
|
+
}
|
|
3087
|
+
|
|
3088
|
+
// src/renderers/pump.renderer.ts
|
|
3089
|
+
var d39 = __toESM(require("d3"), 1);
|
|
3090
|
+
var import_utils9 = require("@welldot/utils");
|
|
3091
|
+
function getPumpSpans(panelTop, panelBottom, bodyTop, intakeY) {
|
|
3092
|
+
const riserBottom = Math.min(Math.max(panelTop, bodyTop), panelBottom);
|
|
3093
|
+
const top = Math.max(bodyTop, panelTop);
|
|
3094
|
+
const bottom = Math.min(intakeY, panelBottom);
|
|
3095
|
+
return {
|
|
3096
|
+
riserBottom,
|
|
3097
|
+
body: bottom > top ? { top, bottom, cutTop: top > bodyTop, cutBottom: bottom < intakeY } : null
|
|
3098
|
+
};
|
|
3099
|
+
}
|
|
3100
|
+
var riserBreakAmplitude = (width) => Math.min(2, width / 3);
|
|
3101
|
+
function getRiserTop(xLeft, xRight, y, broken) {
|
|
3102
|
+
if (!broken) return { edge: `H${xRight}`, breakLine: "" };
|
|
3103
|
+
const a = riserBreakAmplitude(xRight - xLeft);
|
|
3104
|
+
const w = xRight - xLeft;
|
|
3105
|
+
const zigzag = `L${xLeft + w / 3},${y - a}L${xLeft + 2 * w / 3},${y + a}L${xRight},${y}`;
|
|
3106
|
+
return { edge: zigzag, breakLine: `M${xLeft},${y}${zigzag}` };
|
|
3107
|
+
}
|
|
3108
|
+
var BODY_MAX_FILL = 0.85;
|
|
3109
|
+
var RISER_MAX_FILL = 0.7;
|
|
3110
|
+
function getPumpDiameters(intakeD, narrowestD, riserDiameter, cfg) {
|
|
3111
|
+
const maxBody = intakeD * BODY_MAX_FILL;
|
|
3112
|
+
const riser = Math.min(
|
|
3113
|
+
riserDiameter ?? intakeD * cfg.riserWidthRatio,
|
|
3114
|
+
narrowestD * RISER_MAX_FILL,
|
|
3115
|
+
maxBody * RISER_MAX_FILL
|
|
3116
|
+
);
|
|
3117
|
+
const body = Math.min(
|
|
3118
|
+
Math.max(intakeD * cfg.bodyWidthRatio, riser * 1.4),
|
|
3119
|
+
maxBody
|
|
3120
|
+
);
|
|
3121
|
+
return { riser, body };
|
|
3122
|
+
}
|
|
3123
|
+
function drawPump(ctx, pump) {
|
|
3124
|
+
const group = ctx.groups.pumpGroup;
|
|
3125
|
+
const cls = ctx.classes.pump;
|
|
3126
|
+
const cfg = ctx.renderConfig.construction.pump;
|
|
3127
|
+
const theme = ctx.theme.pump;
|
|
3128
|
+
const intake = pump?.intake_depth;
|
|
3129
|
+
const visible = !!pump && cfg.active && intake !== void 0 && intake > 0 && // the riser crosses this panel when the panel starts above the intake
|
|
3130
|
+
ctx.depthFrom < intake;
|
|
3131
|
+
const data = visible ? [pump] : [];
|
|
3132
|
+
const selection = group.selectAll(`g.${cls.item}`).data(data, (d) => d.id);
|
|
3133
|
+
selection.exit().remove();
|
|
3134
|
+
if (!visible) return;
|
|
3135
|
+
const maxXValue = d39.max((0, import_utils9.getProfileDiamValues)(ctx.constructionData)) || 0;
|
|
3136
|
+
const xScale = d39.scaleLinear().domain([0, maxXValue]).range([0, ctx.POCO_WIDTH]);
|
|
3137
|
+
const pipes = [
|
|
3138
|
+
...ctx.constructionData.well_case,
|
|
3139
|
+
...ctx.constructionData.well_screen
|
|
3140
|
+
];
|
|
3141
|
+
const casingD = diameterAt(pipes, intake) ?? diameterAt(ctx.constructionData.bore_hole, intake) ?? maxXValue;
|
|
3142
|
+
const narrowestD = Math.min(
|
|
3143
|
+
casingD,
|
|
3144
|
+
...[...pipes, ...ctx.constructionData.bore_hole].filter((i) => i.from < intake && i.to > 0).map((i) => i.diameter)
|
|
3145
|
+
);
|
|
3146
|
+
const { riser: riserD, body: bodyD } = getPumpDiameters(
|
|
3147
|
+
casingD,
|
|
3148
|
+
narrowestD,
|
|
3149
|
+
pump.riser_diameter,
|
|
3150
|
+
cfg
|
|
3151
|
+
);
|
|
3152
|
+
const riserLeft = (ctx.POCO_CENTER - xScale(riserD)) / 2;
|
|
3153
|
+
const riserRight = (ctx.POCO_CENTER + xScale(riserD)) / 2;
|
|
3154
|
+
const bodyLeft = (ctx.POCO_CENTER - xScale(bodyD)) / 2;
|
|
3155
|
+
const bodyRight = (ctx.POCO_CENTER + xScale(bodyD)) / 2;
|
|
3156
|
+
const yIntake = ctx.yScale(intake);
|
|
3157
|
+
const yBodyTop = yIntake - cfg.bodyHeight;
|
|
3158
|
+
const headDepth = Math.min(
|
|
3159
|
+
0,
|
|
3160
|
+
...pipes.filter((p) => p.from < 0).map((p) => p.from)
|
|
3161
|
+
);
|
|
3162
|
+
const headInPanel = ctx.depthFrom <= headDepth;
|
|
3163
|
+
const padOnHead = headDepth === 0 && !!ctx.constructionData.cement_pad?.thickness;
|
|
3164
|
+
const yRiserTop = headInPanel ? ctx.yScale(headDepth) - (padOnHead ? ctx.renderConfig.construction.cementPad.height - riserBreakAmplitude(xScale(riserD)) : 0) : ctx.yScale(ctx.depthFrom);
|
|
3165
|
+
const { riserBottom: yRiserBottom, body } = getPumpSpans(
|
|
3166
|
+
yRiserTop,
|
|
3167
|
+
ctx.yScale(ctx.depthTo),
|
|
3168
|
+
yBodyTop,
|
|
3169
|
+
yIntake
|
|
3170
|
+
);
|
|
3171
|
+
const r = Math.min(3, (bodyRight - bodyLeft) / 4);
|
|
3172
|
+
const entered = selection.enter().append("g").attr("class", cls.item).on("mouseover", ctx.tooltips.pump.show).on("mouseout", ctx.tooltips.pump.hide);
|
|
3173
|
+
entered.append("path").attr("class", `${cls.item}-riser-fill`);
|
|
3174
|
+
entered.append("path").attr("class", `${cls.item}-riser`);
|
|
3175
|
+
entered.append("path").attr("class", `${cls.item}-body`);
|
|
3176
|
+
entered.append("path").attr("class", `${cls.item}-intake`);
|
|
3177
|
+
const merged = entered.merge(selection);
|
|
3178
|
+
const top = getRiserTop(riserLeft, riserRight, yRiserTop, headInPanel);
|
|
3179
|
+
merged.select(`.${cls.item}-riser-fill`).attr(
|
|
3180
|
+
"d",
|
|
3181
|
+
yRiserBottom > yRiserTop ? `M${riserLeft},${yRiserTop}${top.edge}V${yRiserBottom}H${riserLeft}Z` : ""
|
|
3182
|
+
).attr("fill", theme.riserFill).attr("stroke", "none");
|
|
3183
|
+
merged.select(`.${cls.item}-riser`).attr(
|
|
3184
|
+
"d",
|
|
3185
|
+
yRiserBottom > yRiserTop ? `M${riserLeft},${yRiserTop}V${yRiserBottom}M${riserRight},${yRiserTop}V${yRiserBottom}${top.breakLine}` : ""
|
|
3186
|
+
).attr("stroke-linejoin", "round").attr("fill", "none").attr("stroke", theme.riserStroke).attr("stroke-width", theme.riserStrokeWidth);
|
|
3187
|
+
let bodyPath = "";
|
|
3188
|
+
if (body) {
|
|
3189
|
+
const rt = body.cutTop ? 0 : Math.min(r, (body.bottom - body.top) / 2);
|
|
3190
|
+
const rb = body.cutBottom ? 0 : Math.min(r, (body.bottom - body.top) / 2);
|
|
3191
|
+
const { top: top2, bottom } = body;
|
|
3192
|
+
bodyPath = `M${bodyLeft + rt},${top2}H${bodyRight - rt}Q${bodyRight},${top2} ${bodyRight},${top2 + rt}V${bottom - rb}Q${bodyRight},${bottom} ${bodyRight - rb},${bottom}H${bodyLeft + rb}Q${bodyLeft},${bottom} ${bodyLeft},${bottom - rb}V${top2 + rt}Q${bodyLeft},${top2} ${bodyLeft + rt},${top2}Z`;
|
|
3193
|
+
}
|
|
3194
|
+
merged.select(`.${cls.item}-body`).attr("d", bodyPath).attr("fill", theme.fill).attr("stroke", theme.stroke).attr("stroke-width", theme.strokeWidth);
|
|
3195
|
+
const hatchY = [
|
|
3196
|
+
yIntake - cfg.bodyHeight * 0.3,
|
|
3197
|
+
yIntake - cfg.bodyHeight * 0.15
|
|
3198
|
+
].filter((y) => body && y > body.top && y < body.bottom);
|
|
3199
|
+
merged.select(`.${cls.item}-intake`).attr(
|
|
3200
|
+
"d",
|
|
3201
|
+
hatchY.map((y) => `M${bodyLeft + 1.5},${y}H${bodyRight - 1.5}`).join("")
|
|
3202
|
+
).attr("fill", "none").attr("stroke", theme.stroke).attr("stroke-width", 0.8);
|
|
3203
|
+
}
|
|
2214
3204
|
|
|
2215
3205
|
// src/renderers/unit-labels.renderer.ts
|
|
2216
3206
|
function drawUnitLabels(ctx, data) {
|
|
2217
|
-
if (!ctx.renderConfig.unitLabels.active || !data.length) return;
|
|
2218
3207
|
const {
|
|
2219
3208
|
groups: { unitLabelsGroup },
|
|
2220
3209
|
depthFrom,
|
|
@@ -2225,6 +3214,7 @@ function drawUnitLabels(ctx, data) {
|
|
|
2225
3214
|
classes
|
|
2226
3215
|
} = ctx;
|
|
2227
3216
|
unitLabelsGroup.selectAll("*").remove();
|
|
3217
|
+
if (!renderConfig.unitLabels.active || !data.length) return;
|
|
2228
3218
|
const ru = renderConfig.unitLabels;
|
|
2229
3219
|
const rut = theme.unitLabels;
|
|
2230
3220
|
const sw = ru.stripWidth;
|
|
@@ -2305,7 +3295,7 @@ function buildSvgStyleBlock(theme) {
|
|
|
2305
3295
|
}
|
|
2306
3296
|
|
|
2307
3297
|
// src/Renderer.ts
|
|
2308
|
-
var
|
|
3298
|
+
var d310 = { ...d3module2, tip: import_d3_tip2.default };
|
|
2309
3299
|
var WellRenderer = class {
|
|
2310
3300
|
/**
|
|
2311
3301
|
* @param svgs - One entry per SVG panel; multi-entry for split-panel layouts.
|
|
@@ -2365,12 +3355,14 @@ var WellRenderer = class {
|
|
|
2365
3355
|
const { selector, height, width, margins } = inst;
|
|
2366
3356
|
const svgWidth = width + margins.left + margins.right;
|
|
2367
3357
|
const svgHeight = height + margins.top + margins.bottom;
|
|
2368
|
-
const svg =
|
|
3358
|
+
const svg = d310.select(selector);
|
|
2369
3359
|
svg.selectAll("*").remove();
|
|
2370
3360
|
svg.attr("height", svgHeight).attr("width", svgWidth);
|
|
2371
3361
|
const defs = svg.append("defs");
|
|
2372
3362
|
defs.append("style").text(buildSvgStyleBlock(this.theme));
|
|
2373
3363
|
defs.append("clipPath").attr("id", clipId).append("rect").attr("id", clipRectId).attr("x", 0).attr("y", 0).attr("width", 1e5).attr("height", 1e4);
|
|
3364
|
+
svg.append("g").attr("class", this.classes.overview.group).attr("transform", `translate(0, ${margins.top})`);
|
|
3365
|
+
svg.append("g").attr("class", this.classes.columnHeaders.group);
|
|
2374
3366
|
const poco = svg.append("g").attr("class", this.classes.wellGroup);
|
|
2375
3367
|
const geologic = poco.append("g").attr("class", this.classes.geologicGroup).attr("transform", `translate(${margins.left}, ${margins.top})`);
|
|
2376
3368
|
geologic.append("g").attr("class", this.classes.yAxis);
|
|
@@ -2385,6 +3377,7 @@ var WellRenderer = class {
|
|
|
2385
3377
|
);
|
|
2386
3378
|
const fracturesGroup = poco.append("g").attr("class", this.classes.fractures.group).attr("transform", `translate(${margins.left}, ${margins.top})`).attr("clip-path", `url(#${clipId})`);
|
|
2387
3379
|
fracturesGroup.append("g").attr("class", this.classes.highlights.fracturesGroup);
|
|
3380
|
+
poco.append("g").attr("class", this.classes.markers.group).attr("transform", `translate(${margins.left}, ${margins.top})`);
|
|
2388
3381
|
construction.append("g").attr("class", this.classes.cementPad.group);
|
|
2389
3382
|
construction.append("g").attr("class", this.classes.boreHole.group);
|
|
2390
3383
|
construction.append("g").attr("class", this.classes.surfaceCase.group);
|
|
@@ -2392,12 +3385,23 @@ var WellRenderer = class {
|
|
|
2392
3385
|
construction.append("g").attr("class", this.classes.wellCase.group);
|
|
2393
3386
|
construction.append("g").attr("class", this.classes.wellScreen.group);
|
|
2394
3387
|
construction.append("g").attr("class", this.classes.reduction.group);
|
|
3388
|
+
construction.append("g").attr("class", this.classes.pump.group);
|
|
2395
3389
|
construction.append("g").attr("class", this.classes.centralizer.group);
|
|
2396
3390
|
construction.append("g").attr("class", this.classes.conflict.group);
|
|
2397
3391
|
construction.append("g").attr("class", this.classes.constructionLabels.group);
|
|
2398
3392
|
construction.append("g").attr("class", this.classes.highlights.constructionGroup);
|
|
3393
|
+
poco.append("g").attr("class", this.classes.overlap.group).attr("transform", `translate(${margins.left}, ${margins.top})`);
|
|
2399
3394
|
Object.values(this.textures).forEach((texture) => svg.call(texture));
|
|
2400
|
-
return {
|
|
3395
|
+
return {
|
|
3396
|
+
svg,
|
|
3397
|
+
height,
|
|
3398
|
+
width,
|
|
3399
|
+
margins,
|
|
3400
|
+
clipId,
|
|
3401
|
+
clipRectId,
|
|
3402
|
+
depthRange: inst.depthRange,
|
|
3403
|
+
repeatedTo: inst.repeatedTo
|
|
3404
|
+
};
|
|
2401
3405
|
}
|
|
2402
3406
|
/** Renders a standalone legend into the element matched by `selector`. */
|
|
2403
3407
|
renderLegend(selector, profile) {
|
|
@@ -2408,6 +3412,30 @@ var WellRenderer = class {
|
|
|
2408
3412
|
textures: this.renderConfig.textures
|
|
2409
3413
|
});
|
|
2410
3414
|
}
|
|
3415
|
+
/** Lists the legend entries `profile` needs, labeled from `renderConfig.legend.labels`. */
|
|
3416
|
+
getLegendItems(profile) {
|
|
3417
|
+
return getWellLegendItems(profile, this.renderConfig.legend.labels);
|
|
3418
|
+
}
|
|
3419
|
+
/**
|
|
3420
|
+
* Renders one legend entry's symbol (see {@link getLegendItems}) into its
|
|
3421
|
+
* own SVG matched by `selector`, with the textures it needs defined inside.
|
|
3422
|
+
*/
|
|
3423
|
+
renderLegendSymbol(selector, item) {
|
|
3424
|
+
drawWellLegendSymbol(selector, item, {
|
|
3425
|
+
theme: this.theme,
|
|
3426
|
+
classNames: this.classes.legend,
|
|
3427
|
+
textures: this.renderConfig.textures
|
|
3428
|
+
});
|
|
3429
|
+
}
|
|
3430
|
+
/**
|
|
3431
|
+
* Renders one lithology layer's fill as a `size`×`size` square into its
|
|
3432
|
+
* own SVG matched by `selector`, with its texture defined inside (e.g. for
|
|
3433
|
+
* a swatch in a PDF table). Call after `prepareSvg()`, which loads the
|
|
3434
|
+
* FGDC textures.
|
|
3435
|
+
*/
|
|
3436
|
+
renderLithologySwatch(selector, layer, size = 10) {
|
|
3437
|
+
drawLithologySwatch(selector, layer, { size, theme: this.theme });
|
|
3438
|
+
}
|
|
2411
3439
|
/**
|
|
2412
3440
|
* Multiplies the current zoom scale by `factor` (e.g. `1.25` to zoom in,
|
|
2413
3441
|
* `1 / 1.25` to zoom out) on every panel. No-op if both `renderConfig.zoom`
|
|
@@ -2424,7 +3452,7 @@ var WellRenderer = class {
|
|
|
2424
3452
|
* (defaults to `1`, i.e. the initial fit-to-container view).
|
|
2425
3453
|
*/
|
|
2426
3454
|
resetZoom() {
|
|
2427
|
-
const target =
|
|
3455
|
+
const target = d310.zoomIdentity.scale(this.renderConfig.zoomLevel ?? 1);
|
|
2428
3456
|
for (const state of this.instanceStates) {
|
|
2429
3457
|
if (!state.zoomNode) continue;
|
|
2430
3458
|
asSvgElement(state.svg).transition().call(state.zoomNode.transform, target);
|
|
@@ -2436,7 +3464,46 @@ var WellRenderer = class {
|
|
|
2436
3464
|
*/
|
|
2437
3465
|
getZoomScale() {
|
|
2438
3466
|
const node = this.instanceStates[0]?.svg.node();
|
|
2439
|
-
return node ?
|
|
3467
|
+
return node ? d310.zoomTransform(node).k : 1;
|
|
3468
|
+
}
|
|
3469
|
+
/**
|
|
3470
|
+
* Removes everything drawn on every panel (layers, labels, axis,
|
|
3471
|
+
* highlights) and keeps the structure `prepareSvg()` built, so the next
|
|
3472
|
+
* `draw()` needs no new `prepareSvg()`. `draw()` calls it for an empty well.
|
|
3473
|
+
*/
|
|
3474
|
+
clear() {
|
|
3475
|
+
const c = this.classes;
|
|
3476
|
+
const layerGroups = [
|
|
3477
|
+
c.overview.group,
|
|
3478
|
+
c.columnHeaders.group,
|
|
3479
|
+
c.yAxis,
|
|
3480
|
+
c.unitLabels.group,
|
|
3481
|
+
c.lithology.group,
|
|
3482
|
+
c.caves.group,
|
|
3483
|
+
c.labels.lithology.group,
|
|
3484
|
+
c.highlights.geologicGroup,
|
|
3485
|
+
c.highlights.constructionGroup,
|
|
3486
|
+
c.highlights.fracturesGroup,
|
|
3487
|
+
c.markers.group,
|
|
3488
|
+
c.cementPad.group,
|
|
3489
|
+
c.boreHole.group,
|
|
3490
|
+
c.surfaceCase.group,
|
|
3491
|
+
c.holeFill.group,
|
|
3492
|
+
c.wellCase.group,
|
|
3493
|
+
c.wellScreen.group,
|
|
3494
|
+
c.reduction.group,
|
|
3495
|
+
c.pump.group,
|
|
3496
|
+
c.centralizer.group,
|
|
3497
|
+
c.conflict.group,
|
|
3498
|
+
c.constructionLabels.group,
|
|
3499
|
+
c.overlap.group
|
|
3500
|
+
];
|
|
3501
|
+
for (const { svg } of this.instanceStates) {
|
|
3502
|
+
for (const cls of layerGroups) {
|
|
3503
|
+
svg.select(`.${cls}`).selectAll("*").interrupt().remove();
|
|
3504
|
+
}
|
|
3505
|
+
svg.select(`.${c.fractures.group}`).selectAll(`g.${c.fractures.item}`).interrupt().remove();
|
|
3506
|
+
}
|
|
2440
3507
|
}
|
|
2441
3508
|
/**
|
|
2442
3509
|
* Initialises the SVG DOM structure and preloads FGDC textures.
|
|
@@ -2449,15 +3516,20 @@ var WellRenderer = class {
|
|
|
2449
3516
|
);
|
|
2450
3517
|
}
|
|
2451
3518
|
/**
|
|
2452
|
-
* Renders the well profile into all configured SVG panels.
|
|
3519
|
+
* Renders the well profile into all configured SVG panels. Layers the
|
|
3520
|
+
* profile no longer has are removed; an empty well (`isWellEmpty`) clears
|
|
3521
|
+
* the panels (see {@link clear}).
|
|
2453
3522
|
* @param profile - The well data to render.
|
|
2454
3523
|
* @param options.units - Override the instance-level measurement units for this render.
|
|
2455
3524
|
* @param options.locale - Override the instance-level locale for this render.
|
|
2456
3525
|
* @param options.highlights - Highlight overlays to display on top of the profile.
|
|
2457
3526
|
*/
|
|
2458
3527
|
draw(profile, options = {}) {
|
|
2459
|
-
if ((0,
|
|
2460
|
-
|
|
3528
|
+
if ((0, import_core4.isWellEmpty)(profile)) {
|
|
3529
|
+
this.clear();
|
|
3530
|
+
return;
|
|
3531
|
+
}
|
|
3532
|
+
if ((0, import_core4.parseFormatVersion)(profile.version)?.major !== 2) {
|
|
2461
3533
|
console.warn(
|
|
2462
3534
|
`[WellRenderer] Received a .well file with version ${profile.version ?? "unknown"}. Only v2 is supported. Normalize with deserializeWell() from @welldot/core before rendering.`
|
|
2463
3535
|
);
|
|
@@ -2467,36 +3539,19 @@ var WellRenderer = class {
|
|
|
2467
3539
|
this.locale = options.locale;
|
|
2468
3540
|
}
|
|
2469
3541
|
const highlights = options.highlights ?? {};
|
|
2470
|
-
const maxValues = (0,
|
|
2471
|
-
const maxYValues =
|
|
2472
|
-
|
|
2473
|
-
this.
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
);
|
|
2480
|
-
|
|
2481
|
-
}
|
|
2482
|
-
const totalHeight = this.instanceStates.reduce((s, st) => s + st.height, 0) || 1;
|
|
2483
|
-
const yScaleGlobal = d38.scaleLinear().domain([0, maxYValues]).range([0, totalHeight]);
|
|
2484
|
-
let currentDepth = 0;
|
|
2485
|
-
for (const state of this.instanceStates) {
|
|
2486
|
-
const maxSvgDepth = yScaleGlobal.invert(
|
|
2487
|
-
yScaleGlobal(currentDepth) + state.height
|
|
2488
|
-
);
|
|
2489
|
-
this.drawLogToInstance(
|
|
2490
|
-
state,
|
|
2491
|
-
profile,
|
|
2492
|
-
currentDepth,
|
|
2493
|
-
maxSvgDepth,
|
|
2494
|
-
highlights
|
|
2495
|
-
);
|
|
2496
|
-
currentDepth = maxSvgDepth;
|
|
2497
|
-
}
|
|
3542
|
+
const maxValues = (0, import_utils10.getProfileLastItemsDepths)(profile);
|
|
3543
|
+
const maxYValues = d310.max(maxValues) || 0;
|
|
3544
|
+
const windows = resolvePanelWindows(
|
|
3545
|
+
this.instanceStates,
|
|
3546
|
+
maxYValues,
|
|
3547
|
+
getProfileTopDepth(profile)
|
|
3548
|
+
);
|
|
3549
|
+
this.instanceStates.forEach((state, i) => {
|
|
3550
|
+
const [from, to] = windows[i];
|
|
3551
|
+
this.drawLogToInstance(state, profile, from, to, maxYValues, highlights);
|
|
3552
|
+
});
|
|
2498
3553
|
}
|
|
2499
|
-
drawLogToInstance(state, profile, depthFrom, depthTo, highlights = {}) {
|
|
3554
|
+
drawLogToInstance(state, profile, depthFrom, depthTo, totalDepth, highlights = {}) {
|
|
2500
3555
|
const svg = state.svg;
|
|
2501
3556
|
const pocoGroup = svg.select(`.${this.classes.wellGroup}`);
|
|
2502
3557
|
const lithologyGroup = svg.select(`.${this.classes.lithology.group}`);
|
|
@@ -2514,6 +3569,7 @@ var WellRenderer = class {
|
|
|
2514
3569
|
const wellScreenGroup = svg.select(`.${this.classes.wellScreen.group}`);
|
|
2515
3570
|
const reductionGroup = svg.select(`.${this.classes.reduction.group}`);
|
|
2516
3571
|
const centralizerGroup = svg.select(`.${this.classes.centralizer.group}`);
|
|
3572
|
+
const pumpGroup = svg.select(`.${this.classes.pump.group}`);
|
|
2517
3573
|
const conflictGroup = svg.select(`.${this.classes.conflict.group}`);
|
|
2518
3574
|
const constructionLabelsGroup = svg.select(
|
|
2519
3575
|
`.${this.classes.constructionLabels.group}`
|
|
@@ -2528,13 +3584,19 @@ var WellRenderer = class {
|
|
|
2528
3584
|
`.${this.classes.highlights.fracturesGroup}`
|
|
2529
3585
|
);
|
|
2530
3586
|
const unitLabelsGroup = svg.select(`.${this.classes.unitLabels.group}`);
|
|
3587
|
+
const overviewGroup = svg.select(`.${this.classes.overview.group}`);
|
|
3588
|
+
const columnHeadersGroup = svg.select(
|
|
3589
|
+
`.${this.classes.columnHeaders.group}`
|
|
3590
|
+
);
|
|
3591
|
+
const markersGroup = svg.select(`.${this.classes.markers.group}`);
|
|
3592
|
+
const overlapGroup = svg.select(`.${this.classes.overlap.group}`);
|
|
2531
3593
|
const svgWidth = state.width + state.margins.left + state.margins.right;
|
|
2532
3594
|
const svgHeight = state.height + state.margins.top + state.margins.bottom;
|
|
2533
3595
|
const { pocoWidthRatio, pocoCenterRatio } = this.renderConfig.layout;
|
|
2534
3596
|
const POCO_WIDTH = svgWidth * pocoWidthRatio;
|
|
2535
3597
|
const POCO_CENTER = svgWidth * pocoCenterRatio;
|
|
2536
3598
|
const { duration, ease } = this.renderConfig.animation;
|
|
2537
|
-
const transition =
|
|
3599
|
+
const transition = d310.transition().duration(duration).ease(ease);
|
|
2538
3600
|
const tooltips = populateTooltips(
|
|
2539
3601
|
svg,
|
|
2540
3602
|
this.classes,
|
|
@@ -2563,11 +3625,11 @@ var WellRenderer = class {
|
|
|
2563
3625
|
fractures: profile.fractures
|
|
2564
3626
|
};
|
|
2565
3627
|
const contentHeight = svgHeight - state.margins.top - state.margins.bottom;
|
|
2566
|
-
const yScaleLocal =
|
|
3628
|
+
const yScaleLocal = d310.scaleLinear().domain([depthFrom, depthTo]).range([0, contentHeight]);
|
|
2567
3629
|
const depthFactor = this.units.length === "ft" ? 3.28084 : 1;
|
|
2568
|
-
const yScaleAxis =
|
|
2569
|
-
const yAxis =
|
|
2570
|
-
(d) => `${(0,
|
|
3630
|
+
const yScaleAxis = d310.scaleLinear().domain([depthFrom * depthFactor, depthTo * depthFactor]).range([0, contentHeight]);
|
|
3631
|
+
const yAxis = d310.axisLeft(yScaleAxis).tickFormat(
|
|
3632
|
+
(d) => `${(0, import_utils10.formatNumber)(Number(d), {
|
|
2571
3633
|
maximumFractionDigits: this.units.length === "ft" ? 1 : 2,
|
|
2572
3634
|
locale: this.locale
|
|
2573
3635
|
})}${getLengthUnit(this.units.length)}`
|
|
@@ -2609,10 +3671,15 @@ var WellRenderer = class {
|
|
|
2609
3671
|
wellScreenGroup,
|
|
2610
3672
|
reductionGroup,
|
|
2611
3673
|
centralizerGroup,
|
|
3674
|
+
pumpGroup,
|
|
2612
3675
|
conflictGroup,
|
|
2613
3676
|
highlightsGeologicGroup,
|
|
2614
3677
|
highlightsConstructionGroup,
|
|
2615
|
-
highlightsFracturesGroup
|
|
3678
|
+
highlightsFracturesGroup,
|
|
3679
|
+
overviewGroup,
|
|
3680
|
+
columnHeadersGroup,
|
|
3681
|
+
markersGroup,
|
|
3682
|
+
overlapGroup
|
|
2616
3683
|
};
|
|
2617
3684
|
const ctx = {
|
|
2618
3685
|
svg,
|
|
@@ -2626,6 +3693,8 @@ var WellRenderer = class {
|
|
|
2626
3693
|
geoXRight,
|
|
2627
3694
|
depthFrom,
|
|
2628
3695
|
depthTo,
|
|
3696
|
+
totalDepth,
|
|
3697
|
+
repeatedTo: state.repeatedTo,
|
|
2629
3698
|
yScale: yScaleLocal,
|
|
2630
3699
|
transition,
|
|
2631
3700
|
tooltips,
|
|
@@ -2639,6 +3708,7 @@ var WellRenderer = class {
|
|
|
2639
3708
|
groups
|
|
2640
3709
|
};
|
|
2641
3710
|
const inDepth = filterByDepth(depthFrom, depthTo);
|
|
3711
|
+
const currentPump = (0, import_utils10.getCurrentPump)(profile);
|
|
2642
3712
|
const filteredConstruction = {
|
|
2643
3713
|
...constructionData,
|
|
2644
3714
|
bore_hole: constructionData.bore_hole.filter(inDepth),
|
|
@@ -2663,33 +3733,14 @@ var WellRenderer = class {
|
|
|
2663
3733
|
if (!d) return null;
|
|
2664
3734
|
return transform.k * spanH(d);
|
|
2665
3735
|
});
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
const sc = d;
|
|
2669
|
-
const g = d38.select(nodes[i]);
|
|
2670
|
-
const y = transform.applyY(spanY(sc));
|
|
2671
|
-
const h = transform.k * spanH(sc);
|
|
2672
|
-
g.select(".surface-case-fill").attr("y", y).attr("height", h);
|
|
2673
|
-
g.selectAll(".surface-case-side").attr("y1", y).attr("y2", y + h);
|
|
2674
|
-
});
|
|
2675
|
-
const maxXValsReduction = (0, import_utils7.getProfileDiamValues)(constructionData);
|
|
2676
|
-
const xScaleReduction = d38.scaleLinear().domain([0, d38.max(maxXValsReduction) || 0]).range([0, POCO_WIDTH]);
|
|
2677
|
-
reductionGroup.selectAll(`polygon.${this.classes.reduction.item}`).attr("points", (d) => {
|
|
2678
|
-
const r = d;
|
|
2679
|
-
const yTop = transform.applyY(spanY(r));
|
|
2680
|
-
const yBot = yTop + transform.k * spanH(r);
|
|
2681
|
-
const xTopLeft = (POCO_CENTER - xScaleReduction(r.diam_from)) / 2;
|
|
2682
|
-
const xTopRight = (POCO_CENTER + xScaleReduction(r.diam_from)) / 2;
|
|
2683
|
-
const xBotLeft = (POCO_CENTER - xScaleReduction(r.diam_to)) / 2;
|
|
2684
|
-
const xBotRight = (POCO_CENTER + xScaleReduction(r.diam_to)) / 2;
|
|
2685
|
-
return `${xTopLeft},${yTop} ${xTopRight},${yTop} ${xBotRight},${yBot} ${xBotLeft},${yBot}`;
|
|
2686
|
-
});
|
|
3736
|
+
layoutConstruction(zoomedCtx);
|
|
3737
|
+
drawCementPad(zoomedCtx, constructionData.cement_pad);
|
|
2687
3738
|
fracturesGroup.selectAll(`g.${this.classes.fractures.item}`).attr("transform", (d) => {
|
|
2688
3739
|
if (!d) return null;
|
|
2689
3740
|
const f = d;
|
|
2690
3741
|
const cx = pocoCenterX;
|
|
2691
3742
|
const cy = transform.applyY(yScaleLocal(f.depth));
|
|
2692
|
-
return `translate(0,${cy}) rotate(${f.dip},${cx},0)`;
|
|
3743
|
+
return `translate(0,${cy}) rotate(${fractureDip(f.dip)},${cx},0)`;
|
|
2693
3744
|
});
|
|
2694
3745
|
drawCaves(zoomedCtx, geologicData.caves?.filter(inDepth) ?? []);
|
|
2695
3746
|
drawUnitLabels(zoomedCtx, profile.lithology?.filter(inDepth) ?? []);
|
|
@@ -2700,11 +3751,17 @@ var WellRenderer = class {
|
|
|
2700
3751
|
) ?? [],
|
|
2701
3752
|
caves: profile.caves?.filter(inDepth) ?? []
|
|
2702
3753
|
});
|
|
3754
|
+
drawPump(zoomedCtx, currentPump);
|
|
2703
3755
|
drawCentralizers(zoomedCtx, filteredConstruction);
|
|
2704
3756
|
drawConstructionLabels(zoomedCtx, {
|
|
2705
3757
|
well_case: constructionData.well_case.filter(inDepth),
|
|
2706
3758
|
well_screen: constructionData.well_screen.filter(inDepth)
|
|
2707
3759
|
});
|
|
3760
|
+
drawMarkers(zoomedCtx, {
|
|
3761
|
+
lithology: profile.lithology ?? [],
|
|
3762
|
+
fractures: profile.fractures ?? []
|
|
3763
|
+
});
|
|
3764
|
+
drawOverlap(zoomedCtx);
|
|
2708
3765
|
drawHighlights(zoomedCtx, highlights);
|
|
2709
3766
|
this.onZoom?.(transform.k);
|
|
2710
3767
|
};
|
|
@@ -2727,11 +3784,19 @@ var WellRenderer = class {
|
|
|
2727
3784
|
) ?? []
|
|
2728
3785
|
);
|
|
2729
3786
|
drawConstructive(ctx, filteredConstruction);
|
|
3787
|
+
drawPump(ctx, currentPump);
|
|
2730
3788
|
drawCentralizers(ctx, filteredConstruction);
|
|
2731
3789
|
drawConstructionLabels(ctx, {
|
|
2732
3790
|
well_case: filteredConstruction.well_case,
|
|
2733
3791
|
well_screen: filteredConstruction.well_screen
|
|
2734
3792
|
});
|
|
3793
|
+
drawMarkers(ctx, {
|
|
3794
|
+
lithology: profile.lithology ?? [],
|
|
3795
|
+
fractures: profile.fractures ?? []
|
|
3796
|
+
});
|
|
3797
|
+
drawOverview(ctx, profile.lithology ?? []);
|
|
3798
|
+
drawColumnHeaders(ctx);
|
|
3799
|
+
drawOverlap(ctx);
|
|
2735
3800
|
svg.select(`#${state.clipRectId}`).attr("y", 0).attr("height", svgHeight);
|
|
2736
3801
|
drawHighlights(ctx, highlights);
|
|
2737
3802
|
};
|
|
@@ -2747,7 +3812,7 @@ var WellRenderer = class {
|
|
|
2747
3812
|
}
|
|
2748
3813
|
const { zoom: zoomEnabled, pan: panEnabled } = this.renderConfig;
|
|
2749
3814
|
if (zoomEnabled || panEnabled) {
|
|
2750
|
-
const zoomNode =
|
|
3815
|
+
const zoomNode = d310.zoom();
|
|
2751
3816
|
if (zoomEnabled || panEnabled) zoomNode.on("zoom", zooming);
|
|
2752
3817
|
zoomNode.scaleExtent(
|
|
2753
3818
|
zoomEnabled ? [
|
|
@@ -2763,7 +3828,7 @@ var WellRenderer = class {
|
|
|
2763
3828
|
if (initialZoom !== 1) {
|
|
2764
3829
|
asSvgElement(svg).call(
|
|
2765
3830
|
zoomNode.transform,
|
|
2766
|
-
|
|
3831
|
+
d310.zoomIdentity.scale(initialZoom)
|
|
2767
3832
|
);
|
|
2768
3833
|
}
|
|
2769
3834
|
}
|
|
@@ -2778,10 +3843,13 @@ var WellRenderer = class {
|
|
|
2778
3843
|
WellRenderer,
|
|
2779
3844
|
applyRenderLocale,
|
|
2780
3845
|
drawWellLegend,
|
|
3846
|
+
drawWellLegendSymbol,
|
|
2781
3847
|
formatDiameter,
|
|
2782
3848
|
formatLength,
|
|
2783
3849
|
getDiameterUnit,
|
|
2784
3850
|
getLengthUnit,
|
|
3851
|
+
getProfileTopDepth,
|
|
3852
|
+
getWellLegendItems,
|
|
2785
3853
|
importFgdcTextures,
|
|
2786
3854
|
resolveRenderLabel
|
|
2787
3855
|
});
|