@welldot/render 0.1.0-next.20260509.039db95 → 0.2.2
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 +82 -33
- package/dist/{fgdcTextures-5IIUV7QV.js → fgdcTextures-P5DTFNPT.js} +1 -1
- package/dist/{fgdcTextures-5IIUV7QV.js.map → fgdcTextures-P5DTFNPT.js.map} +1 -1
- package/dist/index.cjs +461 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +209 -10
- package/dist/index.d.ts +209 -10
- package/dist/index.js +455 -139
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,146 @@
|
|
|
1
1
|
// src/configs/render.configs.ts
|
|
2
2
|
import { easeCubic } from "d3";
|
|
3
|
+
|
|
4
|
+
// src/utils/format.utils.ts
|
|
5
|
+
import { formatNumber } from "@welldot/utils";
|
|
6
|
+
var MM_TO_INCHES = 0.0393701;
|
|
7
|
+
var M_TO_FT = 3.28084;
|
|
8
|
+
function formatLength(m, units, locale) {
|
|
9
|
+
return units === "ft" ? formatNumber(m * M_TO_FT, { maximumFractionDigits: 1, locale }) : formatNumber(m, { maximumFractionDigits: 2, locale });
|
|
10
|
+
}
|
|
11
|
+
function formatDiameter(mm, units, locale) {
|
|
12
|
+
return units === "inches" ? formatNumber(mm * MM_TO_INCHES, { maximumFractionDigits: 2, locale }) : formatNumber(mm, { maximumFractionDigits: 2, locale });
|
|
13
|
+
}
|
|
14
|
+
function getLengthUnit(units) {
|
|
15
|
+
return units === "ft" ? "ft" : "m";
|
|
16
|
+
}
|
|
17
|
+
function getDiameterUnit(units, locale) {
|
|
18
|
+
if (units !== "inches") return "mm";
|
|
19
|
+
return locale === "en" ? "in." : '"';
|
|
20
|
+
}
|
|
21
|
+
function resolveRenderLabel(value, locale) {
|
|
22
|
+
if (typeof value === "string") return value;
|
|
23
|
+
return locale === "en" && value.en ? value.en : value.pt;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/configs/render.configs.ts
|
|
27
|
+
var RENDER_LABELS = {
|
|
28
|
+
constructionLabels: {
|
|
29
|
+
wellCasePrefix: { pt: "Revest.", en: "Casing" },
|
|
30
|
+
wellScreenPrefix: { pt: "Filtro", en: "Screen" },
|
|
31
|
+
wellScreenSlotPrefix: { pt: "Ranhura:", en: "Slot:" }
|
|
32
|
+
},
|
|
33
|
+
legend: {
|
|
34
|
+
title: { pt: "LEGENDA", en: "LEGEND" },
|
|
35
|
+
labels: {
|
|
36
|
+
fractureSingle: { pt: "Fratura simples", en: "Single fracture" },
|
|
37
|
+
fractureSwarm: { pt: "Enxame de fraturas", en: "Fracture swarm" },
|
|
38
|
+
fractureWater: { pt: "Entrada d'\xE1gua", en: "Water intake" },
|
|
39
|
+
caveDry: { pt: "Caverna seca", en: "Dry cave" },
|
|
40
|
+
caveWet: { pt: "Caverna c/ \xE1gua", en: "Wet cave" },
|
|
41
|
+
boreHole: { pt: "Perfura\xE7\xE3o", en: "Borehole" },
|
|
42
|
+
surfaceCase: { pt: "Tubo guia", en: "Surface casing" },
|
|
43
|
+
holeFillGravel: { pt: "Pr\xE9-filtro", en: "Gravel pack" },
|
|
44
|
+
holeFillSeal: { pt: "Veda\xE7\xE3o", en: "Seal" },
|
|
45
|
+
wellCase: { pt: "Revestimento", en: "Casing" },
|
|
46
|
+
wellScreen: { pt: "Filtro", en: "Screen" },
|
|
47
|
+
reduction: { pt: "Redu\xE7\xE3o", en: "Reduction" },
|
|
48
|
+
cementPad: { pt: "Laje de cimento", en: "Cement pad" },
|
|
49
|
+
conflict: { pt: "Conflito", en: "Conflict" }
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
tooltipLabels: {
|
|
53
|
+
common: {
|
|
54
|
+
from: { pt: "De", en: "From" },
|
|
55
|
+
to: { pt: "at\xE9", en: "to" },
|
|
56
|
+
description: { pt: "Descri\xE7\xE3o:", en: "Description:" },
|
|
57
|
+
diameter: { pt: "Di\xE2metro:", en: "Diameter:" },
|
|
58
|
+
type: { pt: "Tipo:", en: "Type:" }
|
|
59
|
+
},
|
|
60
|
+
geology: {
|
|
61
|
+
title: { pt: "Litologia", en: "Lithology" },
|
|
62
|
+
geologicUnit: { pt: "Unidade geol\xF3gica:", en: "Geologic unit:" },
|
|
63
|
+
aquiferUnit: { pt: "Unidade aqu\xEDfera:", en: "Aquifer unit:" }
|
|
64
|
+
},
|
|
65
|
+
hole: { title: { pt: "FURO", en: "BOREHOLE" } },
|
|
66
|
+
surfaceCase: { title: { pt: "TUBO DE BOCA", en: "SURFACE CASING" } },
|
|
67
|
+
holeFill: { title: { pt: "ESP. ANULAR", en: "ANNULAR SPACE" } },
|
|
68
|
+
wellCase: { title: { pt: "REVESTIMENTO", en: "CASING" } },
|
|
69
|
+
wellScreen: {
|
|
70
|
+
title: { pt: "FILTROS", en: "SCREENS" },
|
|
71
|
+
slot: { pt: "Ranhura:", en: "Slot:" }
|
|
72
|
+
},
|
|
73
|
+
reduction: { title: { pt: "REDU\xC7\xC3O", en: "REDUCTION" } },
|
|
74
|
+
conflict: { title: { pt: "CONFLITO", en: "CONFLICT" } },
|
|
75
|
+
fracture: {
|
|
76
|
+
title: { pt: "FRATURA", en: "FRACTURE" },
|
|
77
|
+
titleSwarm: { pt: "ENXAME DE FRATURAS", en: "FRACTURE SWARM" },
|
|
78
|
+
depth: { pt: "Profundidade:", en: "Depth:" },
|
|
79
|
+
waterIntake: { pt: "Entrada d'\xE1gua:", en: "Water intake:" },
|
|
80
|
+
dip: { pt: "Mergulho:", en: "Dip:" },
|
|
81
|
+
azimuth: { pt: "Azimute:", en: "Azimuth:" }
|
|
82
|
+
},
|
|
83
|
+
cementPad: {
|
|
84
|
+
title: { pt: "LAJE DE PROTE\xC7\xC3O", en: "PROTECTION SLAB" },
|
|
85
|
+
thickness: { pt: "Espessura:", en: "Thickness:" },
|
|
86
|
+
width: { pt: "Largura:", en: "Width:" },
|
|
87
|
+
length: { pt: "Comprimento:", en: "Length:" }
|
|
88
|
+
},
|
|
89
|
+
cave: {
|
|
90
|
+
title: { pt: "CAVERNA", en: "CAVE" },
|
|
91
|
+
waterIntake: { pt: "Entrada d'\xE1gua", en: "Water intake" }
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
typeLabels: {
|
|
95
|
+
fracture: { pt: "fratura", en: "fracture" },
|
|
96
|
+
fractureWater: { pt: "fratura aberta", en: "open fracture" },
|
|
97
|
+
cave: { pt: "caverna", en: "cave" },
|
|
98
|
+
caveWater: { pt: "caverna \xFAmida", en: "wet cave" }
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
function resolveGroup(group, locale) {
|
|
102
|
+
const result = {};
|
|
103
|
+
for (const key in group) {
|
|
104
|
+
result[key] = resolveRenderLabel(group[key], locale);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
function resolveTooltipLabels(locale) {
|
|
109
|
+
const t = RENDER_LABELS.tooltipLabels;
|
|
110
|
+
return {
|
|
111
|
+
common: resolveGroup(t.common, locale),
|
|
112
|
+
geology: resolveGroup(t.geology, locale),
|
|
113
|
+
hole: resolveGroup(t.hole, locale),
|
|
114
|
+
surfaceCase: resolveGroup(t.surfaceCase, locale),
|
|
115
|
+
holeFill: resolveGroup(t.holeFill, locale),
|
|
116
|
+
wellCase: resolveGroup(t.wellCase, locale),
|
|
117
|
+
wellScreen: resolveGroup(t.wellScreen, locale),
|
|
118
|
+
reduction: resolveGroup(t.reduction, locale),
|
|
119
|
+
conflict: resolveGroup(t.conflict, locale),
|
|
120
|
+
fracture: resolveGroup(t.fracture, locale),
|
|
121
|
+
cementPad: resolveGroup(t.cementPad, locale),
|
|
122
|
+
cave: resolveGroup(t.cave, locale)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function applyRenderLocale(config, locale) {
|
|
126
|
+
return {
|
|
127
|
+
...config,
|
|
128
|
+
constructionLabels: {
|
|
129
|
+
...config.constructionLabels,
|
|
130
|
+
labels: resolveGroup(RENDER_LABELS.constructionLabels, locale)
|
|
131
|
+
},
|
|
132
|
+
legend: {
|
|
133
|
+
...config.legend,
|
|
134
|
+
title: resolveRenderLabel(RENDER_LABELS.legend.title, locale),
|
|
135
|
+
labels: resolveGroup(RENDER_LABELS.legend.labels, locale)
|
|
136
|
+
},
|
|
137
|
+
tooltipLabels: resolveTooltipLabels(locale),
|
|
138
|
+
labels: {
|
|
139
|
+
...config.labels,
|
|
140
|
+
typeLabels: resolveGroup(RENDER_LABELS.typeLabels, locale)
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
3
144
|
var DEFAULT_WELL_THEME = {
|
|
4
145
|
lithology: { stroke: "#101010", strokeWidth: 1 },
|
|
5
146
|
lithologyTexture: { size: 150, strokeWidth: 0.8, stroke: "#303030" },
|
|
@@ -34,6 +175,7 @@ var DEFAULT_WELL_THEME = {
|
|
|
34
175
|
holeFill: { stroke: "#303030", strokeWidth: 2 },
|
|
35
176
|
wellCase: { fill: "#ffffff", stroke: "#303030", strokeWidth: 2 },
|
|
36
177
|
wellScreen: { stroke: "#303030", strokeWidth: 2 },
|
|
178
|
+
reduction: { fill: "#ffffff", stroke: "#303030", strokeWidth: 2 },
|
|
37
179
|
conflict: { stroke: "#e52117", strokeWidth: 4 },
|
|
38
180
|
unitLabels: {
|
|
39
181
|
geologicFill: "#f0f0f0",
|
|
@@ -97,6 +239,8 @@ var STATIC_RENDER_CONFIG = {
|
|
|
97
239
|
zoom: true,
|
|
98
240
|
pan: true,
|
|
99
241
|
zoomLevel: 1,
|
|
242
|
+
maxZoomScale: 150,
|
|
243
|
+
minZoomScale: 0,
|
|
100
244
|
animation: { duration: 600, ease: easeCubic },
|
|
101
245
|
geologic: { xLeft: 20, xRightInset: 300 },
|
|
102
246
|
layout: {
|
|
@@ -127,9 +271,10 @@ var STATIC_RENDER_CONFIG = {
|
|
|
127
271
|
cementPad: { widthMultiplier: 0.9, thicknessMultiplier: 1.3 },
|
|
128
272
|
surfaceCase: { diameterPaddingRatio: 0.1 }
|
|
129
273
|
},
|
|
274
|
+
tooltipLabels: resolveTooltipLabels("pt"),
|
|
130
275
|
labels: {
|
|
131
276
|
active: true,
|
|
132
|
-
typeLabels:
|
|
277
|
+
typeLabels: resolveGroup(RENDER_LABELS.typeLabels, "pt"),
|
|
133
278
|
depthTipHeight: 11,
|
|
134
279
|
depthTipPadX: 2,
|
|
135
280
|
descriptionXOffset: 20,
|
|
@@ -194,6 +339,7 @@ var STATIC_RENDER_CONFIG = {
|
|
|
194
339
|
holeFillSeal: "Veda\xE7\xE3o",
|
|
195
340
|
wellCase: "Revestimento",
|
|
196
341
|
wellScreen: "Filtro",
|
|
342
|
+
reduction: "Redu\xE7\xE3o",
|
|
197
343
|
cementPad: "Laje de cimento",
|
|
198
344
|
conflict: "Conflito"
|
|
199
345
|
}
|
|
@@ -204,6 +350,8 @@ var INTERACTIVE_RENDER_CONFIG = {
|
|
|
204
350
|
zoom: true,
|
|
205
351
|
pan: true,
|
|
206
352
|
zoomLevel: 1,
|
|
353
|
+
maxZoomScale: 150,
|
|
354
|
+
minZoomScale: 0,
|
|
207
355
|
animation: { duration: 600, ease: easeCubic },
|
|
208
356
|
geologic: { xLeft: 6, xRightInset: 56 },
|
|
209
357
|
layout: {
|
|
@@ -234,9 +382,10 @@ var INTERACTIVE_RENDER_CONFIG = {
|
|
|
234
382
|
cementPad: { widthMultiplier: 0.9, thicknessMultiplier: 1.3 },
|
|
235
383
|
surfaceCase: { diameterPaddingRatio: 0.1 }
|
|
236
384
|
},
|
|
385
|
+
tooltipLabels: resolveTooltipLabels("pt"),
|
|
237
386
|
labels: {
|
|
238
387
|
active: false,
|
|
239
|
-
typeLabels:
|
|
388
|
+
typeLabels: resolveGroup(RENDER_LABELS.typeLabels, "pt"),
|
|
240
389
|
depthTipHeight: 11,
|
|
241
390
|
depthTipPadX: 2,
|
|
242
391
|
descriptionXOffset: 78,
|
|
@@ -298,6 +447,7 @@ var INTERACTIVE_RENDER_CONFIG = {
|
|
|
298
447
|
holeFillSeal: "Veda\xE7\xE3o",
|
|
299
448
|
wellCase: "Revestimento",
|
|
300
449
|
wellScreen: "Filtro",
|
|
450
|
+
reduction: "Redu\xE7\xE3o",
|
|
301
451
|
cementPad: "Laje de cimento",
|
|
302
452
|
conflict: "Conflito"
|
|
303
453
|
}
|
|
@@ -307,12 +457,12 @@ var INTERACTIVE_RENDER_CONFIG = {
|
|
|
307
457
|
|
|
308
458
|
// src/utils/fgdcTextures.ts
|
|
309
459
|
async function importFgdcTextures() {
|
|
310
|
-
const fgdcTextures = await import("./fgdcTextures-
|
|
460
|
+
const fgdcTextures = await import("./fgdcTextures-P5DTFNPT.js");
|
|
311
461
|
return fgdcTextures.default;
|
|
312
462
|
}
|
|
313
463
|
|
|
314
464
|
// src/Renderer.ts
|
|
315
|
-
import * as
|
|
465
|
+
import * as d3module2 from "d3";
|
|
316
466
|
import d3tip2 from "d3-tip";
|
|
317
467
|
import { defu as defu2 } from "defu";
|
|
318
468
|
|
|
@@ -380,23 +530,11 @@ function createWellTextures(cfg) {
|
|
|
380
530
|
import {
|
|
381
531
|
isWellEmpty
|
|
382
532
|
} from "@welldot/core";
|
|
383
|
-
import {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
function formatLength(m, units) {
|
|
389
|
-
return units === "ft" ? (m * M_TO_FT).toFixed(1) : String(m);
|
|
390
|
-
}
|
|
391
|
-
function formatDiameter(mm, units) {
|
|
392
|
-
return units === "inches" ? (mm * MM_TO_INCHES).toFixed(2) : String(mm);
|
|
393
|
-
}
|
|
394
|
-
function getLengthUnit(units) {
|
|
395
|
-
return units === "ft" ? "ft" : "m";
|
|
396
|
-
}
|
|
397
|
-
function getDiameterUnit(units) {
|
|
398
|
-
return units === "inches" ? '"' : "mm";
|
|
399
|
-
}
|
|
533
|
+
import {
|
|
534
|
+
formatNumber as formatNumber3,
|
|
535
|
+
getProfileDiamValues as getProfileDiamValues4,
|
|
536
|
+
getProfileLastItemsDepths
|
|
537
|
+
} from "@welldot/utils";
|
|
400
538
|
|
|
401
539
|
// src/configs/render.classnames.ts
|
|
402
540
|
var DEFAULT_COMPONENTS_CLASS_NAMES = {
|
|
@@ -454,6 +592,10 @@ var DEFAULT_COMPONENTS_CLASS_NAMES = {
|
|
|
454
592
|
group: "well-screen",
|
|
455
593
|
rect: "well-screen-rect"
|
|
456
594
|
},
|
|
595
|
+
reduction: {
|
|
596
|
+
group: "reduction",
|
|
597
|
+
item: "reduction-poly"
|
|
598
|
+
},
|
|
457
599
|
conflict: {
|
|
458
600
|
group: "conflict",
|
|
459
601
|
rect: "conflict-rect"
|
|
@@ -563,92 +705,102 @@ var makeSeededPrng = (seed, scramble = 6271) => {
|
|
|
563
705
|
};
|
|
564
706
|
|
|
565
707
|
// src/utils/tooltips.utils.ts
|
|
566
|
-
import * as d3module from "d3";
|
|
567
708
|
import d3tip from "d3-tip";
|
|
568
709
|
import sanitizeHtml from "sanitize-html";
|
|
569
|
-
|
|
710
|
+
import { formatNumber as formatNumber2 } from "@welldot/utils";
|
|
570
711
|
var esc = (v) => sanitizeHtml(String(v ?? ""), { allowedTags: [], allowedAttributes: {} });
|
|
571
|
-
var
|
|
712
|
+
var _tooltipCache = /* @__PURE__ */ new WeakMap();
|
|
713
|
+
var populateTooltips = (svg, customClasses, units, tooltipConfig, labels, locale) => {
|
|
572
714
|
const svgEl = typeof svg.node === "function" ? svg.node() : null;
|
|
573
|
-
|
|
574
|
-
|
|
715
|
+
const signature = JSON.stringify({ units, tooltipConfig, labels, locale });
|
|
716
|
+
const cached = svgEl ? _tooltipCache.get(svgEl) : void 0;
|
|
717
|
+
if (cached && cached.signature === signature) {
|
|
718
|
+
return cached.tooltips;
|
|
575
719
|
}
|
|
576
720
|
const tipsText = {
|
|
577
721
|
geology: (_, d) => `
|
|
578
|
-
<span class="${customClasses.tooltip.title}"
|
|
579
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
580
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
581
|
-
${d.geologic_unit ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
582
|
-
${d.aquifer_unit ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
722
|
+
<span class="${customClasses.tooltip.title}">${labels.geology.title}</span>
|
|
723
|
+
<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>
|
|
724
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>
|
|
725
|
+
${d.geologic_unit ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.geology.geologicUnit}</strong> ${esc(d.geologic_unit)}</span>` : ""}
|
|
726
|
+
${d.aquifer_unit ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.geology.aquiferUnit}</strong> ${esc(d.aquifer_unit)}</span>` : ""}
|
|
583
727
|
`,
|
|
584
728
|
hole: (_, d) => `
|
|
585
|
-
<span class="${customClasses.tooltip.title}"
|
|
586
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
587
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
729
|
+
<span class="${customClasses.tooltip.title}">${labels.hole.title}</span>
|
|
730
|
+
<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>
|
|
731
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>
|
|
588
732
|
`,
|
|
589
733
|
surfaceCase: (_, d) => `
|
|
590
|
-
<span class="${customClasses.tooltip.title}"
|
|
591
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
592
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
734
|
+
<span class="${customClasses.tooltip.title}">${labels.surfaceCase.title}</span>
|
|
735
|
+
<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>
|
|
736
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>
|
|
593
737
|
`,
|
|
594
738
|
holeFill: (_, d) => `
|
|
595
|
-
<span class="${customClasses.tooltip.title}"
|
|
596
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
597
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
739
|
+
<span class="${customClasses.tooltip.title}">${labels.holeFill.title}</span>
|
|
740
|
+
<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>
|
|
741
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>
|
|
598
742
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
599
|
-
<strong
|
|
743
|
+
<strong>${labels.common.description}</strong> ${esc(d.description)}
|
|
600
744
|
</span>
|
|
601
745
|
`,
|
|
602
746
|
wellCase: (_, d) => `
|
|
603
|
-
<span class="${customClasses.tooltip.title}"
|
|
604
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
747
|
+
<span class="${customClasses.tooltip.title}">${labels.wellCase.title}</span>
|
|
748
|
+
<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>
|
|
605
749
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
606
|
-
<strong
|
|
750
|
+
<strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}
|
|
607
751
|
</span>
|
|
608
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
752
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>
|
|
609
753
|
`,
|
|
610
754
|
wellScreen: (_, d) => `
|
|
611
|
-
<span class="${customClasses.tooltip.title}"
|
|
612
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
755
|
+
<span class="${customClasses.tooltip.title}">${labels.wellScreen.title}</span>
|
|
756
|
+
<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>
|
|
613
757
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
614
|
-
<strong
|
|
615
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
758
|
+
<strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>
|
|
759
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>
|
|
760
|
+
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
761
|
+
<strong>${labels.wellScreen.slot}</strong> ${esc(formatNumber2(d.screen_slot, { maximumFractionDigits: 2, locale }))} mm
|
|
762
|
+
</span>
|
|
763
|
+
`,
|
|
764
|
+
reduction: (_, d) => `
|
|
765
|
+
<span class="${customClasses.tooltip.title}">${labels.reduction.title}</span>
|
|
766
|
+
<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>
|
|
616
767
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
617
|
-
<strong
|
|
768
|
+
<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))}
|
|
618
769
|
</span>
|
|
770
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>
|
|
619
771
|
`,
|
|
620
772
|
conflict: (_, d) => `
|
|
621
|
-
<span class="${customClasses.tooltip.title}"
|
|
622
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
773
|
+
<span class="${customClasses.tooltip.title}">${labels.conflict.title}</span>
|
|
774
|
+
<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>
|
|
623
775
|
`,
|
|
624
776
|
fracture: (_, d) => {
|
|
625
|
-
const title = d.swarm ?
|
|
777
|
+
const title = d.swarm ? labels.fracture.titleSwarm : labels.fracture.title;
|
|
626
778
|
return `
|
|
627
779
|
<span class="${customClasses.tooltip.title}">${title}</span>
|
|
628
|
-
<span class="${customClasses.tooltip.primaryInfo}"><strong
|
|
629
|
-
${d.water_intake ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
630
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
631
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
632
|
-
${d.description ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
780
|
+
<span class="${customClasses.tooltip.primaryInfo}"><strong>${labels.fracture.depth}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>
|
|
781
|
+
${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>` : ""}
|
|
782
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.fracture.dip}</strong> ${esc(d.dip)}\xB0</span>
|
|
783
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.fracture.azimuth}</strong> ${esc(d.azimuth)}\xB0</span>
|
|
784
|
+
${d.description ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>` : ""}
|
|
633
785
|
`;
|
|
634
786
|
},
|
|
635
787
|
cementPad: (_, d) => `
|
|
636
|
-
<span class="${customClasses.tooltip.title}"
|
|
788
|
+
<span class="${customClasses.tooltip.title}">${labels.cementPad.title}</span>
|
|
637
789
|
<span class="${customClasses.tooltip.primaryInfo}">${esc(d.type)}</span>
|
|
638
|
-
<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
639
|
-
${esc(formatLength(d.thickness, units.length))} ${esc(units.length)}</span>
|
|
790
|
+
<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.cementPad.thickness}</strong>
|
|
791
|
+
${esc(formatLength(d.thickness, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>
|
|
640
792
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
641
|
-
<strong
|
|
793
|
+
<strong>${labels.cementPad.width}</strong> ${esc(formatLength(d.width, units.length, locale))} ${esc(getLengthUnit(units.length))}
|
|
642
794
|
</span>
|
|
643
795
|
<span class="${customClasses.tooltip.secondaryInfo}">
|
|
644
|
-
<strong
|
|
796
|
+
<strong>${labels.cementPad.length}</strong> ${esc(formatLength(d.length, units.length, locale))} ${esc(getLengthUnit(units.length))}
|
|
645
797
|
</span>
|
|
646
798
|
`,
|
|
647
799
|
cave: (_, d) => `
|
|
648
|
-
<span class="${customClasses.tooltip.title}"
|
|
649
|
-
<span class="${customClasses.tooltip.primaryInfo}"
|
|
650
|
-
${d.water_intake ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
651
|
-
${d.description ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong
|
|
800
|
+
<span class="${customClasses.tooltip.title}">${labels.cave.title}</span>
|
|
801
|
+
<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>
|
|
802
|
+
${d.water_intake ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.cave.waterIntake}</strong></span>` : ""}
|
|
803
|
+
${d.description ? `<span class="${customClasses.tooltip.secondaryInfo}"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>` : ""}
|
|
652
804
|
`
|
|
653
805
|
};
|
|
654
806
|
const noop = { show: () => {
|
|
@@ -661,12 +813,13 @@ var populateTooltips = (svg, customClasses, units, tooltipConfig) => {
|
|
|
661
813
|
tooltips[tipTextKey] = noop;
|
|
662
814
|
return;
|
|
663
815
|
}
|
|
664
|
-
tooltips[tipTextKey] =
|
|
816
|
+
tooltips[tipTextKey] = d3tip().attr("class", customClasses.tooltip.root).direction("e").html(tipsText[tipTextKey]);
|
|
665
817
|
svg.call(
|
|
666
818
|
tooltips[tipTextKey]
|
|
667
819
|
);
|
|
668
820
|
});
|
|
669
821
|
svgEl?.setAttribute("data-tooltips-init", "true");
|
|
822
|
+
if (svgEl) _tooltipCache.set(svgEl, { signature, tooltips });
|
|
670
823
|
return tooltips;
|
|
671
824
|
};
|
|
672
825
|
|
|
@@ -682,21 +835,31 @@ var preloadFgdcTextures = () => {
|
|
|
682
835
|
return _fgdcTexturesPromise;
|
|
683
836
|
};
|
|
684
837
|
var getLithologicalFillList = (data, opts) => {
|
|
685
|
-
const
|
|
838
|
+
const textureKey = (d) => String(d.texture.code);
|
|
839
|
+
const isFgdc = (d) => !d.texture.vocabulary || d.texture.vocabulary === "fgdc";
|
|
840
|
+
const uniqueTextureCodes = [...new Set(data.filter(isFgdc).map(textureKey))];
|
|
686
841
|
const texturesLoaded = Object.fromEntries(
|
|
687
|
-
uniqueTextureCodes.filter((code) =>
|
|
842
|
+
uniqueTextureCodes.filter((code) => {
|
|
843
|
+
const path = _fgdcTextures[code];
|
|
844
|
+
return path && path !== "-" && /^[Mm]/.test(path);
|
|
845
|
+
}).map((code) => [code, _fgdcTextures[code]])
|
|
688
846
|
);
|
|
689
847
|
return Object.fromEntries(
|
|
690
|
-
data.map((d) =>
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
848
|
+
data.map((d) => {
|
|
849
|
+
const key = textureKey(d);
|
|
850
|
+
const pathData = isFgdc(d) ? texturesLoaded[key] : void 0;
|
|
851
|
+
if (!pathData) return [`${key}.${d.from}`, d.color];
|
|
852
|
+
return [
|
|
853
|
+
`${key}.${d.from}`,
|
|
854
|
+
textures2.paths().d(() => pathData).size(opts.size).strokeWidth(opts.strokeWidth).stroke(opts.stroke).background(d.color)
|
|
855
|
+
];
|
|
856
|
+
})
|
|
694
857
|
);
|
|
695
858
|
};
|
|
696
859
|
var getLithologyFill = (geologyData, svg, opts) => {
|
|
697
860
|
const lithologicalFill = getLithologicalFillList(geologyData, opts);
|
|
698
861
|
return (d) => {
|
|
699
|
-
const fill = lithologicalFill[`${d.
|
|
862
|
+
const fill = lithologicalFill[`${String(d.texture.code)}.${d.from}`];
|
|
700
863
|
if (!fill.url) return fill;
|
|
701
864
|
svg.call(fill);
|
|
702
865
|
return fill.url();
|
|
@@ -759,7 +922,7 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
759
922
|
ctx.groups.lithologyLabelsGroup.selectAll("*").remove();
|
|
760
923
|
if (active.has("lithology") && show.has("depth")) {
|
|
761
924
|
data.lithology.filter((d) => d.to <= ctx.depthTo).forEach((d) => {
|
|
762
|
-
const text = `${d.to}`;
|
|
925
|
+
const text = `${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)}`;
|
|
763
926
|
const approxW = text.length * (st.fontSize * 0.52) + s.depthTipPadX * 2;
|
|
764
927
|
const y = ctx.yScale(d.to) - s.depthTipHeight / 2;
|
|
765
928
|
const tipG = ctx.groups.lithologyLabelsGroup.append("g").attr("class", ctx.classes.labels.lithology.depth);
|
|
@@ -775,20 +938,20 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
775
938
|
baseY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),
|
|
776
939
|
originX: ctx.geoXRight,
|
|
777
940
|
originY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),
|
|
778
|
-
header: `${d.from}\u2013${d.to}
|
|
941
|
+
header: `${formatLength(d.from, ctx.units.length, ctx.locale)}\u2013${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)}`,
|
|
779
942
|
description: d.description || ""
|
|
780
943
|
});
|
|
781
944
|
});
|
|
782
945
|
}
|
|
783
946
|
if (active.has("fractures")) {
|
|
784
947
|
data.fractures.filter((d) => d.depth >= ctx.depthFrom && d.depth < ctx.depthTo).forEach((d) => {
|
|
785
|
-
const typeLabel = d.water_intake ? "fratura aberta" : "fratura";
|
|
948
|
+
const typeLabel = d.water_intake ? ctx.renderConfig.labels.typeLabels?.fractureWater ?? "fratura aberta" : ctx.renderConfig.labels.typeLabels?.fracture ?? "fratura";
|
|
786
949
|
items.push({
|
|
787
950
|
sortDepth: d.depth,
|
|
788
951
|
baseY: ctx.yScale(d.depth),
|
|
789
952
|
originX: ctx.pocoCenterX,
|
|
790
953
|
originY: ctx.yScale(d.depth),
|
|
791
|
-
header: `${d.depth}
|
|
954
|
+
header: `${formatLength(d.depth, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)} \xB7 ${typeLabel}`,
|
|
792
955
|
description: d.description || ""
|
|
793
956
|
});
|
|
794
957
|
});
|
|
@@ -796,13 +959,13 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
796
959
|
if (active.has("caves")) {
|
|
797
960
|
data.caves.filter((d) => d.from < ctx.depthTo).forEach((d) => {
|
|
798
961
|
const midDepth = (d.from + d.to) / 2;
|
|
799
|
-
const typeLabel = d.water_intake ? "caverna \xFAmida" : "caverna";
|
|
962
|
+
const typeLabel = d.water_intake ? ctx.renderConfig.labels.typeLabels?.caveWater ?? "caverna \xFAmida" : ctx.renderConfig.labels.typeLabels?.cave ?? "caverna";
|
|
800
963
|
items.push({
|
|
801
964
|
sortDepth: d.from,
|
|
802
965
|
baseY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),
|
|
803
966
|
originX: ctx.geoXRight,
|
|
804
967
|
originY: ctx.yScale(Math.max(midDepth, ctx.depthFrom)),
|
|
805
|
-
header: `${d.from}\u2013${d.to}
|
|
968
|
+
header: `${formatLength(d.from, ctx.units.length, ctx.locale)}\u2013${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)} \xB7 ${typeLabel}`,
|
|
806
969
|
description: d.description || ""
|
|
807
970
|
});
|
|
808
971
|
});
|
|
@@ -848,6 +1011,19 @@ function drawAnnotationLabels(ctx, data) {
|
|
|
848
1011
|
}
|
|
849
1012
|
}
|
|
850
1013
|
|
|
1014
|
+
// src/renderers/caves.renderer.ts
|
|
1015
|
+
import * as d3 from "d3";
|
|
1016
|
+
|
|
1017
|
+
// src/utils/key.utils.ts
|
|
1018
|
+
var makeIntervalKey = (type) => (d, _i) => {
|
|
1019
|
+
const { key, from, to } = d;
|
|
1020
|
+
return key ? `${key}` : `${type}:${from}:${to}`;
|
|
1021
|
+
};
|
|
1022
|
+
var makePointKey = (type) => (d, i) => {
|
|
1023
|
+
const { key, depth } = d;
|
|
1024
|
+
return key ? `${key}` : `${type}:${depth}:${i}`;
|
|
1025
|
+
};
|
|
1026
|
+
|
|
851
1027
|
// src/renderers/caves.renderer.ts
|
|
852
1028
|
function drawCaves(ctx, data) {
|
|
853
1029
|
if (!data.length) return;
|
|
@@ -864,9 +1040,14 @@ function drawCaves(ctx, data) {
|
|
|
864
1040
|
classes,
|
|
865
1041
|
tooltips
|
|
866
1042
|
} = ctx;
|
|
867
|
-
cavesGroup.selectAll(`g.${classes.caves.item}`).remove();
|
|
868
1043
|
const rc = renderConfig.caves;
|
|
869
|
-
|
|
1044
|
+
const groups = cavesGroup.selectAll(`g.${classes.caves.item}`).data(data, makeIntervalKey("cave"));
|
|
1045
|
+
groups.exit().transition(ctx.transition).style("opacity", 0).remove();
|
|
1046
|
+
const entered = groups.enter().append("g").attr("class", classes.caves.item).style("cursor", "pointer").on("mouseover", tooltips.cave.show).on("mouseout", tooltips.cave.hide).style("opacity", 0);
|
|
1047
|
+
const merged = mergeEnter(entered, groups);
|
|
1048
|
+
merged.each(function(cave) {
|
|
1049
|
+
const g = d3.select(this);
|
|
1050
|
+
g.selectAll("*").remove();
|
|
870
1051
|
const seedTop = cave.from * 100 + cave.to;
|
|
871
1052
|
const seedBot = cave.to * 100 + cave.from + 999;
|
|
872
1053
|
const rngTop = makeSeededPrng(seedTop);
|
|
@@ -893,12 +1074,12 @@ function drawCaves(ctx, data) {
|
|
|
893
1074
|
const botReversed = botCut ? `L ${geoXLeft.toFixed(1)},${yBot.toFixed(1)}` : ptsToSmoothPath([...botPts].reverse(), { omitMoveTo: true });
|
|
894
1075
|
const closedPath = `${topPath} L ${geoXRight.toFixed(1)},${yBot.toFixed(1)}${botReversed} L ${geoXLeft.toFixed(1)},${yTop.toFixed(1)} Z`;
|
|
895
1076
|
const caveTexture = cave.water_intake ? textures3.cave_wet : textures3.cave_dry;
|
|
896
|
-
const g = cavesGroup.append("g").attr("class", classes.caves.item).datum(cave).style("cursor", "pointer").on("mouseover", tooltips.cave.show).on("mouseout", tooltips.cave.hide);
|
|
897
1077
|
const caveStroke = cave.water_intake ? theme.cave.wetStroke : theme.cave.dryStroke;
|
|
898
1078
|
g.append("path").attr("class", classes.caves.fill).attr("d", closedPath).attr("fill", caveTexture.url()).attr("fill-opacity", theme.cave.fillOpacity).attr("stroke", "none");
|
|
899
1079
|
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");
|
|
900
1080
|
g.append("path").attr("class", classes.caves.contact).attr("d", botPath).attr("fill", "none").attr("stroke", caveStroke).attr("stroke-width", theme.cave.contactStrokeWidth).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
901
1081
|
});
|
|
1082
|
+
merged.transition(ctx.transition).style("opacity", 1);
|
|
902
1083
|
}
|
|
903
1084
|
|
|
904
1085
|
// src/renderers/construction-labels.renderer.ts
|
|
@@ -909,8 +1090,8 @@ function drawConstructionLabels(ctx, data) {
|
|
|
909
1090
|
ctx.groups.constructionLabelsGroup.selectAll("*").remove();
|
|
910
1091
|
const clc = ctx.renderConfig.constructionLabels;
|
|
911
1092
|
const clct = ctx.theme.constructionLabels;
|
|
912
|
-
const fmtD = (mm) => formatDiameter(mm, ctx.units.diameter);
|
|
913
|
-
const dUnit = getDiameterUnit(ctx.units.diameter);
|
|
1093
|
+
const fmtD = (mm) => formatDiameter(mm, ctx.units.diameter, ctx.locale);
|
|
1094
|
+
const dUnit = getDiameterUnit(ctx.units.diameter, ctx.locale);
|
|
914
1095
|
const maxXValues = getProfileDiamValues(ctx.constructionData);
|
|
915
1096
|
const xScale = d32.scaleLinear().domain([0, d32.max(maxXValues) || 0]).range([0, ctx.POCO_WIDTH]);
|
|
916
1097
|
const occupied = [];
|
|
@@ -972,7 +1153,7 @@ function drawConstructionLabels(ctx, data) {
|
|
|
972
1153
|
}).forEach(
|
|
973
1154
|
(d) => placeLabel(
|
|
974
1155
|
d,
|
|
975
|
-
`${clc.labels.wellScreenPrefix} ${fmtD(d.diameter)}${dUnit} ${d.type} ${clc.labels.wellScreenSlotPrefix} ${fmtD(d.
|
|
1156
|
+
`${clc.labels.wellScreenPrefix} ${fmtD(d.diameter)}${dUnit} ${d.type} ${clc.labels.wellScreenSlotPrefix} ${fmtD(d.screen_slot)}${dUnit}`
|
|
976
1157
|
)
|
|
977
1158
|
);
|
|
978
1159
|
}
|
|
@@ -989,9 +1170,10 @@ function drawConstructive(ctx, data) {
|
|
|
989
1170
|
const maxXValueConstruction = d33.max(maxXValues) || 0;
|
|
990
1171
|
const xScale = d33.scaleLinear().domain([0, maxXValueConstruction]).range([0, ctx.POCO_WIDTH]);
|
|
991
1172
|
const rcc = ctx.renderConfig.construction;
|
|
1173
|
+
const yPos = getYPos;
|
|
992
1174
|
ctx.groups.constructionGroup.selectAll(`.${ctx.classes.cementPad.item}`).remove();
|
|
993
1175
|
if (data.cement_pad && data.cement_pad.thickness && ctx.depthFrom === 0) {
|
|
994
|
-
const cementPad = ctx.groups.cementPadGroup.selectAll("rect").data([data.cement_pad]);
|
|
1176
|
+
const cementPad = ctx.groups.cementPadGroup.selectAll("rect").data([data.cement_pad], () => "cement_pad");
|
|
995
1177
|
cementPad.exit().remove();
|
|
996
1178
|
const newCementPad = cementPad.enter().append("rect").attr("class", ctx.classes.cementPad.item).attr(
|
|
997
1179
|
"x",
|
|
@@ -1006,15 +1188,15 @@ function drawConstructive(ctx, data) {
|
|
|
1006
1188
|
}).attr("fill", ctx.textures.pad.url()).attr("stroke", ctx.theme.cementPad.stroke).attr("stroke-width", ctx.theme.cementPad.strokeWidth);
|
|
1007
1189
|
newCementPad.on("mouseover", ctx.tooltips.cementPad.show).on("mouseout", ctx.tooltips.cementPad.hide);
|
|
1008
1190
|
}
|
|
1009
|
-
const hole = ctx.groups.holeGroup.selectAll(`.${ctx.classes.boreHole.rect}`).data(data.bore_hole);
|
|
1010
|
-
hole.exit().remove();
|
|
1011
|
-
const newHole = hole.enter().append("rect").attr("class", ctx.classes.boreHole.rect).attr("fill", ctx.theme.boreHole.fill).attr("stroke", ctx.theme.boreHole.stroke).attr("opacity", ctx.theme.boreHole.opacity).attr("stroke-width", ctx.theme.boreHole.strokeWidth).attr("stroke-dasharray", ctx.theme.boreHole.strokeDasharray).on("mouseover", ctx.tooltips.hole.show).on("mouseout", ctx.tooltips.hole.hide);
|
|
1191
|
+
const hole = ctx.groups.holeGroup.selectAll(`.${ctx.classes.boreHole.rect}`).data(data.bore_hole, makeIntervalKey("bore_hole"));
|
|
1192
|
+
hole.exit().transition(ctx.transition).attr("height", 0).remove();
|
|
1193
|
+
const newHole = hole.enter().append("rect").attr("class", ctx.classes.boreHole.rect).attr("fill", ctx.theme.boreHole.fill).attr("stroke", ctx.theme.boreHole.stroke).attr("opacity", ctx.theme.boreHole.opacity).attr("stroke-width", ctx.theme.boreHole.strokeWidth).attr("stroke-dasharray", ctx.theme.boreHole.strokeDasharray).on("mouseover", ctx.tooltips.hole.show).on("mouseout", ctx.tooltips.hole.hide).attr("y", yPos).attr("height", 0);
|
|
1012
1194
|
const mergedHole = mergeEnter(newHole, hole).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
|
|
1013
1195
|
withTransition(mergedHole, ctx.transition).attr("y", getYPos).attr("height", getHeight);
|
|
1014
|
-
const surfaceCaseGs = ctx.groups.surfaceCaseGroup.selectAll(`g.${ctx.classes.surfaceCase.rect}`).data(data.surface_case);
|
|
1196
|
+
const surfaceCaseGs = ctx.groups.surfaceCaseGroup.selectAll(`g.${ctx.classes.surfaceCase.rect}`).data(data.surface_case, makeIntervalKey("surface_case"));
|
|
1015
1197
|
surfaceCaseGs.exit().transition(ctx.transition).style("opacity", 0).remove();
|
|
1016
1198
|
const newSC = surfaceCaseGs.enter().append("g").attr("class", ctx.classes.surfaceCase.rect).on("mouseover", ctx.tooltips.surfaceCase.show).on("mouseout", ctx.tooltips.surfaceCase.hide);
|
|
1017
|
-
newSC.append("rect").attr("class", "surface-case-fill").attr("stroke", "none");
|
|
1199
|
+
newSC.append("rect").attr("class", "surface-case-fill").attr("stroke", "none").attr("y", yPos).attr("height", 0);
|
|
1018
1200
|
newSC.append("line").attr("class", "surface-case-side").attr("stroke", ctx.theme.surfaceCase.stroke).attr("stroke-width", ctx.theme.surfaceCase.strokeWidth);
|
|
1019
1201
|
newSC.append("line").attr("class", "surface-case-side").attr("stroke", ctx.theme.surfaceCase.stroke).attr("stroke-width", ctx.theme.surfaceCase.strokeWidth);
|
|
1020
1202
|
const mergedSC = mergeEnter(newSC, surfaceCaseGs);
|
|
@@ -1039,33 +1221,54 @@ function drawConstructive(ctx, data) {
|
|
|
1039
1221
|
"y2",
|
|
1040
1222
|
(d) => getYPos(d) + getHeight(d)
|
|
1041
1223
|
);
|
|
1042
|
-
const holeFill = ctx.groups.holeFillGroup.selectAll(`.${ctx.classes.holeFill.rect}`).data(data.hole_fill);
|
|
1043
|
-
holeFill.exit().remove();
|
|
1044
|
-
const newHoleFill = holeFill.enter().append("rect").attr("class", ctx.classes.holeFill.rect).attr("stroke", ctx.theme.holeFill.stroke).attr("stroke-width", ctx.theme.holeFill.strokeWidth).on("mouseover", ctx.tooltips.holeFill.show).on("mouseout", ctx.tooltips.holeFill.hide);
|
|
1224
|
+
const holeFill = ctx.groups.holeFillGroup.selectAll(`.${ctx.classes.holeFill.rect}`).data(data.hole_fill, makeIntervalKey("hole_fill"));
|
|
1225
|
+
holeFill.exit().transition(ctx.transition).attr("height", 0).remove();
|
|
1226
|
+
const newHoleFill = holeFill.enter().append("rect").attr("class", ctx.classes.holeFill.rect).attr("stroke", ctx.theme.holeFill.stroke).attr("stroke-width", ctx.theme.holeFill.strokeWidth).on("mouseover", ctx.tooltips.holeFill.show).on("mouseout", ctx.tooltips.holeFill.hide).attr("y", yPos).attr("height", 0);
|
|
1045
1227
|
const mergedHoleFill = mergeEnter(newHoleFill, holeFill).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
|
|
1046
1228
|
withTransition(mergedHoleFill, ctx.transition).attr("y", getYPos).attr("height", getHeight).attr("fill", (d) => ctx.textures[d.type].url());
|
|
1047
|
-
const wellCase = ctx.groups.wellCaseGroup.selectAll(`.${ctx.classes.wellCase.rect}`).data(data.well_case);
|
|
1048
|
-
wellCase.exit().remove();
|
|
1049
|
-
const newWellCase = wellCase.enter().append("rect").attr("class", ctx.classes.wellCase.rect).attr("fill", ctx.theme.wellCase.fill).attr("stroke", ctx.theme.wellCase.stroke).attr("stroke-width", ctx.theme.wellCase.strokeWidth).on("mouseover", ctx.tooltips.wellCase.show).on("mouseout", ctx.tooltips.wellCase.hide);
|
|
1229
|
+
const wellCase = ctx.groups.wellCaseGroup.selectAll(`.${ctx.classes.wellCase.rect}`).data(data.well_case, makeIntervalKey("well_case"));
|
|
1230
|
+
wellCase.exit().transition(ctx.transition).attr("height", 0).remove();
|
|
1231
|
+
const newWellCase = wellCase.enter().append("rect").attr("class", ctx.classes.wellCase.rect).attr("fill", ctx.theme.wellCase.fill).attr("stroke", ctx.theme.wellCase.stroke).attr("stroke-width", ctx.theme.wellCase.strokeWidth).on("mouseover", ctx.tooltips.wellCase.show).on("mouseout", ctx.tooltips.wellCase.hide).attr("y", yPos).attr("height", 0);
|
|
1050
1232
|
const mergedWellCase = mergeEnter(newWellCase, wellCase).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
|
|
1051
1233
|
withTransition(mergedWellCase, ctx.transition).attr("y", getYPos).attr("height", getHeight);
|
|
1052
|
-
const wellScreen = ctx.groups.wellScreenGroup.selectAll(`.${ctx.classes.wellScreen.rect}`).data(data.well_screen);
|
|
1053
|
-
wellScreen.exit().remove();
|
|
1054
|
-
const newWellScreen = wellScreen.enter().append("rect").attr("class", ctx.classes.wellScreen.rect).attr("fill", ctx.textures.well_screen.url()).attr("stroke", ctx.theme.wellScreen.stroke).attr("stroke-width", ctx.theme.wellScreen.strokeWidth).on("mouseover", ctx.tooltips.wellScreen.show).on("mouseout", ctx.tooltips.wellScreen.hide);
|
|
1234
|
+
const wellScreen = ctx.groups.wellScreenGroup.selectAll(`.${ctx.classes.wellScreen.rect}`).data(data.well_screen, makeIntervalKey("well_screen"));
|
|
1235
|
+
wellScreen.exit().transition(ctx.transition).attr("height", 0).remove();
|
|
1236
|
+
const newWellScreen = wellScreen.enter().append("rect").attr("class", ctx.classes.wellScreen.rect).attr("fill", ctx.textures.well_screen.url()).attr("stroke", ctx.theme.wellScreen.stroke).attr("stroke-width", ctx.theme.wellScreen.strokeWidth).on("mouseover", ctx.tooltips.wellScreen.show).on("mouseout", ctx.tooltips.wellScreen.hide).attr("y", yPos).attr("height", 0);
|
|
1055
1237
|
const mergedWellScreen = mergeEnter(newWellScreen, wellScreen).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
|
|
1056
1238
|
withTransition(mergedWellScreen, ctx.transition).attr("y", getYPos).attr("height", getHeight);
|
|
1239
|
+
const reductionPoints = (d, yTop, yBot) => {
|
|
1240
|
+
const xTopLeft = (ctx.POCO_CENTER - xScale(d.diam_from)) / 2;
|
|
1241
|
+
const xTopRight = (ctx.POCO_CENTER + xScale(d.diam_from)) / 2;
|
|
1242
|
+
const xBotLeft = (ctx.POCO_CENTER - xScale(d.diam_to)) / 2;
|
|
1243
|
+
const xBotRight = (ctx.POCO_CENTER + xScale(d.diam_to)) / 2;
|
|
1244
|
+
return `${xTopLeft},${yTop} ${xTopRight},${yTop} ${xBotRight},${yBot} ${xBotLeft},${yBot}`;
|
|
1245
|
+
};
|
|
1246
|
+
const reduction = ctx.groups.reductionGroup.selectAll(`.${ctx.classes.reduction.item}`).data(data.reduction, makeIntervalKey("reduction"));
|
|
1247
|
+
reduction.exit().transition(ctx.transition).style("opacity", 0).remove();
|
|
1248
|
+
const collapsedPoints = (d) => {
|
|
1249
|
+
const r = d;
|
|
1250
|
+
const y = getYPos(r);
|
|
1251
|
+
return reductionPoints(r, y, y);
|
|
1252
|
+
};
|
|
1253
|
+
const newReduction = reduction.enter().append("polygon").attr("class", ctx.classes.reduction.item).attr("fill", ctx.theme.reduction.fill).attr("stroke", ctx.theme.reduction.stroke).attr("stroke-width", ctx.theme.reduction.strokeWidth).on("mouseover", ctx.tooltips.reduction.show).on("mouseout", ctx.tooltips.reduction.hide).attr("points", collapsedPoints);
|
|
1254
|
+
const mergedReduction = mergeEnter(newReduction, reduction);
|
|
1255
|
+
withTransition(mergedReduction, ctx.transition).attr(
|
|
1256
|
+
"points",
|
|
1257
|
+
(d) => reductionPoints(d, getYPos(d), getYPos(d) + getHeight(d))
|
|
1258
|
+
);
|
|
1057
1259
|
const conflictAreas = [];
|
|
1058
1260
|
conflictAreas.push(...getConflictAreas(data.well_case, data.well_screen));
|
|
1059
1261
|
conflictAreas.push(...getConflictAreas(data.well_screen, data.well_case));
|
|
1060
1262
|
const mergedConflicts = mergeConflicts(conflictAreas, 1);
|
|
1061
|
-
const conflict = ctx.groups.conflictGroup.selectAll(`.${ctx.classes.conflict.rect}`).data(mergedConflicts);
|
|
1062
|
-
conflict.exit().remove();
|
|
1063
|
-
const newConflict = conflict.enter().append("rect").attr("class", ctx.classes.conflict.rect).attr("fill", ctx.textures.conflict.url()).attr("stroke", ctx.theme.conflict.stroke).attr("stroke-width", ctx.theme.conflict.strokeWidth).on("mouseover", ctx.tooltips.conflict.show).on("mouseout", ctx.tooltips.conflict.hide);
|
|
1263
|
+
const conflict = ctx.groups.conflictGroup.selectAll(`.${ctx.classes.conflict.rect}`).data(mergedConflicts, makeIntervalKey("conflict"));
|
|
1264
|
+
conflict.exit().transition(ctx.transition).attr("height", 0).remove();
|
|
1265
|
+
const newConflict = conflict.enter().append("rect").attr("class", ctx.classes.conflict.rect).attr("fill", ctx.textures.conflict.url()).attr("stroke", ctx.theme.conflict.stroke).attr("stroke-width", ctx.theme.conflict.strokeWidth).on("mouseover", ctx.tooltips.conflict.show).on("mouseout", ctx.tooltips.conflict.hide).attr("y", ctx.yScale(0)).attr("height", 0);
|
|
1064
1266
|
const mergedConflict = mergeEnter(newConflict, conflict).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
|
|
1065
1267
|
withTransition(mergedConflict, ctx.transition).attr("y", ctx.yScale(0)).attr("height", getHeight);
|
|
1066
1268
|
}
|
|
1067
1269
|
|
|
1068
1270
|
// src/renderers/fractures.renderer.ts
|
|
1271
|
+
import * as d34 from "d3";
|
|
1069
1272
|
function wavyLine(rng, steps, baseY, jitter, startInset, endInset) {
|
|
1070
1273
|
const pts = [];
|
|
1071
1274
|
for (let i = 0; i < steps; i++) {
|
|
@@ -1088,19 +1291,23 @@ function drawFractures(ctx, data) {
|
|
|
1088
1291
|
classes,
|
|
1089
1292
|
tooltips
|
|
1090
1293
|
} = ctx;
|
|
1091
|
-
fracturesGroup.selectAll(`g.${classes.fractures.item}`).remove();
|
|
1092
1294
|
const rf = renderConfig.fractures;
|
|
1093
1295
|
const halfWidth = POCO_WIDTH * rf.widthMultiplier / 2;
|
|
1094
1296
|
const xa = pocoCenterX - halfWidth;
|
|
1095
1297
|
const w = halfWidth * 2;
|
|
1096
1298
|
const normToAbsX = (normX) => xa + normX * w;
|
|
1097
|
-
|
|
1299
|
+
const groups = fracturesGroup.selectAll(`g.${classes.fractures.item}`).data(data, makePointKey("fracture"));
|
|
1300
|
+
groups.exit().transition(ctx.transition).style("opacity", 0).remove();
|
|
1301
|
+
const entered = groups.enter().append("g").attr("class", classes.fractures.item).on("mouseover", tooltips.fracture.show).on("mouseout", tooltips.fracture.hide).style("cursor", "pointer").style("opacity", 0);
|
|
1302
|
+
const merged = mergeEnter(entered, groups);
|
|
1303
|
+
merged.attr(
|
|
1304
|
+
"transform",
|
|
1305
|
+
(fracture) => `translate(0,${yScale(fracture.depth)}) rotate(${fracture.dip},${pocoCenterX},0)`
|
|
1306
|
+
);
|
|
1307
|
+
merged.each(function(fracture) {
|
|
1308
|
+
const g = d34.select(this);
|
|
1309
|
+
g.selectAll("*").remove();
|
|
1098
1310
|
const rng = makeSeededPrng(fracture.depth, 7919);
|
|
1099
|
-
const cy = yScale(fracture.depth);
|
|
1100
|
-
const g = fracturesGroup.append("g").attr("class", classes.fractures.item).datum(fracture).attr(
|
|
1101
|
-
"transform",
|
|
1102
|
-
`translate(0,${cy}) rotate(${fracture.dip},${pocoCenterX},0)`
|
|
1103
|
-
).on("mouseover", tooltips.fracture.show).on("mouseout", tooltips.fracture.hide).style("cursor", "pointer");
|
|
1104
1311
|
const hitBuffer = fracture.swarm ? rf.hitBuffer.swarm : rf.hitBuffer.single;
|
|
1105
1312
|
g.append("rect").attr("class", classes.fractures.hitArea).attr("x", xa).attr("y", -hitBuffer).attr("width", w).attr("height", hitBuffer * 2).attr("fill", "transparent").style("pointer-events", "all");
|
|
1106
1313
|
const fractureStroke = fracture.water_intake ? theme.fracture.wetStroke : theme.fracture.dryStroke;
|
|
@@ -1173,10 +1380,11 @@ function drawFractures(ctx, data) {
|
|
|
1173
1380
|
}
|
|
1174
1381
|
}
|
|
1175
1382
|
});
|
|
1383
|
+
merged.transition(ctx.transition).style("opacity", 1);
|
|
1176
1384
|
}
|
|
1177
1385
|
|
|
1178
1386
|
// src/renderers/highlights.renderer.ts
|
|
1179
|
-
import * as
|
|
1387
|
+
import * as d35 from "d3";
|
|
1180
1388
|
import { getProfileDiamValues as getProfileDiamValues3 } from "@welldot/utils";
|
|
1181
1389
|
function drawHighlightItem(ctx, group, x, y, w, h, label) {
|
|
1182
1390
|
if (h <= 0 || w <= 0) return;
|
|
@@ -1237,7 +1445,7 @@ function drawHighlights(ctx, hl) {
|
|
|
1237
1445
|
);
|
|
1238
1446
|
});
|
|
1239
1447
|
const maxXVals = getProfileDiamValues3(ctx.constructionData);
|
|
1240
|
-
const xScaleConstr =
|
|
1448
|
+
const xScaleConstr = d35.scaleLinear().domain([0, d35.max(maxXVals) || 0]).range([0, ctx.POCO_WIDTH]);
|
|
1241
1449
|
const constructionConfig = ctx.renderConfig.construction;
|
|
1242
1450
|
if (hl.cement_pad && ctx.depthFrom === 0 && ctx.constructionData.cement_pad?.thickness) {
|
|
1243
1451
|
const cp = ctx.constructionData.cement_pad;
|
|
@@ -1317,18 +1525,29 @@ function drawHighlights(ctx, hl) {
|
|
|
1317
1525
|
stdX,
|
|
1318
1526
|
stdW
|
|
1319
1527
|
);
|
|
1528
|
+
drawConstrHighlights(
|
|
1529
|
+
hl.reduction,
|
|
1530
|
+
ctx.constructionData.reduction.map((d) => ({
|
|
1531
|
+
from: d.from,
|
|
1532
|
+
to: d.to,
|
|
1533
|
+
diameter: Math.max(d.diam_from, d.diam_to)
|
|
1534
|
+
})),
|
|
1535
|
+
stdX,
|
|
1536
|
+
stdW
|
|
1537
|
+
);
|
|
1320
1538
|
}
|
|
1321
1539
|
|
|
1322
1540
|
// src/renderers/legend.renderer.ts
|
|
1323
|
-
import * as
|
|
1541
|
+
import * as d3module from "d3";
|
|
1324
1542
|
import { defu } from "defu";
|
|
1325
|
-
var
|
|
1543
|
+
var d36 = { ...d3module };
|
|
1326
1544
|
function drawWellLegend(selector, profile, options = {}) {
|
|
1327
1545
|
const fractures = profile.fractures ?? [];
|
|
1328
1546
|
const caves = profile.caves ?? [];
|
|
1329
1547
|
const boreHoles = profile.bore_hole ?? [];
|
|
1330
1548
|
const wellCases = profile.well_case ?? [];
|
|
1331
1549
|
const wellScreens = profile.well_screen ?? [];
|
|
1550
|
+
const reductions = profile.reduction ?? [];
|
|
1332
1551
|
const holeFills = profile.hole_fill ?? [];
|
|
1333
1552
|
const hasSimple = fractures.some((f) => !f.swarm && !f.water_intake);
|
|
1334
1553
|
const hasSwarm = fractures.some((f) => f.swarm);
|
|
@@ -1341,6 +1560,7 @@ function drawWellLegend(selector, profile, options = {}) {
|
|
|
1341
1560
|
const hasHoleFillSeal = holeFills.some((h) => h.type === "seal");
|
|
1342
1561
|
const hasWellCase = wellCases.length > 0;
|
|
1343
1562
|
const hasWellScreen = wellScreens.length > 0;
|
|
1563
|
+
const hasReduction = reductions.length > 0;
|
|
1344
1564
|
const hasCementPad = !!profile.cement_pad?.thickness;
|
|
1345
1565
|
const hasConflict = mergeConflicts(
|
|
1346
1566
|
[
|
|
@@ -1427,13 +1647,19 @@ function drawWellLegend(selector, profile, options = {}) {
|
|
|
1427
1647
|
label: cfg.labels.wellScreen,
|
|
1428
1648
|
subKind: "wellScreen"
|
|
1429
1649
|
});
|
|
1650
|
+
if (hasReduction)
|
|
1651
|
+
items.push({
|
|
1652
|
+
kind: "construction",
|
|
1653
|
+
label: cfg.labels.reduction,
|
|
1654
|
+
subKind: "reduction"
|
|
1655
|
+
});
|
|
1430
1656
|
if (hasConflict)
|
|
1431
1657
|
items.push({
|
|
1432
1658
|
kind: "construction",
|
|
1433
1659
|
label: cfg.labels.conflict,
|
|
1434
1660
|
subKind: "conflict"
|
|
1435
1661
|
});
|
|
1436
|
-
const svgEl =
|
|
1662
|
+
const svgEl = d36.select(selector);
|
|
1437
1663
|
svgEl.selectAll("*").remove();
|
|
1438
1664
|
if (items.length === 0) {
|
|
1439
1665
|
svgEl.attr("width", 0).attr("height", 0);
|
|
@@ -1485,6 +1711,15 @@ function drawWellLegend(selector, profile, options = {}) {
|
|
|
1485
1711
|
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");
|
|
1486
1712
|
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);
|
|
1487
1713
|
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);
|
|
1714
|
+
} else if (item.subKind === "reduction") {
|
|
1715
|
+
const topW = rw * 0.5;
|
|
1716
|
+
const y1 = rowSymY - rh / 2;
|
|
1717
|
+
const y2 = rowSymY + rh / 2;
|
|
1718
|
+
const midX = cx + rw / 2;
|
|
1719
|
+
symG.append("polygon").attr("class", cls.constructionRect).attr(
|
|
1720
|
+
"points",
|
|
1721
|
+
`${midX - topW / 2},${y1} ${midX + topW / 2},${y1} ${cx + rw},${y2} ${cx},${y2}`
|
|
1722
|
+
).attr("fill", theme.reduction.fill).attr("stroke", theme.reduction.stroke).attr("stroke-width", theme.legend.itemStrokeWidth);
|
|
1488
1723
|
} else {
|
|
1489
1724
|
const symMap = {
|
|
1490
1725
|
boreHole: {
|
|
@@ -1542,11 +1777,11 @@ function drawLithology(ctx, data) {
|
|
|
1542
1777
|
from: depthFrom,
|
|
1543
1778
|
to: depthTo
|
|
1544
1779
|
});
|
|
1545
|
-
const rects = lithologyGroup.selectAll(`.${classes.lithology.rect}`).data(data);
|
|
1546
|
-
rects.exit().remove();
|
|
1547
|
-
const newLayers = rects.enter().append("rect").attr("class", classes.lithology.rect).attr("x", geoXLeft).attr("width", geoXRight - geoXLeft).attr("stroke", theme.lithology.stroke).attr("stroke-width", theme.lithology.strokeWidth).on("mouseover", tooltips.geology.show).on("mouseout", tooltips.geology.hide);
|
|
1548
|
-
const merged = mergeEnter(newLayers, rects)
|
|
1549
|
-
withTransition(merged, transition).attr("height", getHeight).attr("fill", getLithologyFill(data, svg, ctx.theme.lithologyTexture));
|
|
1780
|
+
const rects = lithologyGroup.selectAll(`.${classes.lithology.rect}`).data(data, makeIntervalKey("lithology"));
|
|
1781
|
+
rects.exit().transition(transition).attr("height", 0).remove();
|
|
1782
|
+
const newLayers = rects.enter().append("rect").attr("class", classes.lithology.rect).attr("x", geoXLeft).attr("width", geoXRight - geoXLeft).attr("stroke", theme.lithology.stroke).attr("stroke-width", theme.lithology.strokeWidth).on("mouseover", tooltips.geology.show).on("mouseout", tooltips.geology.hide).attr("y", getYPos).attr("height", 0);
|
|
1783
|
+
const merged = mergeEnter(newLayers, rects);
|
|
1784
|
+
withTransition(merged, transition).attr("y", getYPos).attr("height", getHeight).attr("fill", getLithologyFill(data, svg, ctx.theme.lithologyTexture));
|
|
1550
1785
|
}
|
|
1551
1786
|
|
|
1552
1787
|
// src/renderers/unit-labels.renderer.ts
|
|
@@ -1633,20 +1868,26 @@ function buildSvgStyleBlock(theme) {
|
|
|
1633
1868
|
`.wp-annotation-label{font-size:${s(labels.fontSize)}px}`,
|
|
1634
1869
|
`.wp-annotation-header{font-weight:${s(labels.headerFontWeight ?? 600)};font-family:${s(labels.headerFont)};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,
|
|
1635
1870
|
`.wp-annotation-body{font-weight:${s(labels.bodyFontWeight ?? 400)};font-family:${s(labels.bodyFont ?? "sans-serif")};font-size:${s(labels.fontSize)}px;color:${s(labels.bodyColor)}}`,
|
|
1636
|
-
`.wp-depth-tip-text{font-family:${s(labels.bodyFont ?? "sans-serif")};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}
|
|
1871
|
+
`.wp-depth-tip-text{font-family:${s(labels.bodyFont ?? "sans-serif")};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,
|
|
1872
|
+
`.wp-tooltip{position:absolute;z-index:1000;display:flex;flex-direction:column;gap:2px;max-width:240px;padding:8px 10px;border-radius:6px;background:${s(labels.annotationBg)};border:1px solid ${s(labels.annotationBorderColor ?? "rgba(0,0,0,0.08)")};box-shadow:0 4px 12px rgba(0,0,0,0.15);font-family:${s(labels.bodyFont ?? "sans-serif")};line-height:1.45}`,
|
|
1873
|
+
`.wp-tooltip-title{font-family:${s(labels.headerFont)};font-weight:${s(labels.headerFontWeight ?? 600)};font-size:10px;letter-spacing:0.06em;text-transform:uppercase;color:${s(labels.color)}}`,
|
|
1874
|
+
`.wp-tooltip-primary{font-weight:${s(labels.headerFontWeight ?? 600)};font-size:12px;color:${s(labels.color)}}`,
|
|
1875
|
+
`.wp-tooltip-secondary{font-size:11px;color:${s(labels.bodyColor)}}`
|
|
1637
1876
|
].join("");
|
|
1638
1877
|
}
|
|
1639
1878
|
|
|
1640
1879
|
// src/Renderer.ts
|
|
1641
|
-
var
|
|
1880
|
+
var d37 = { ...d3module2, tip: d3tip2 };
|
|
1642
1881
|
var WellRenderer = class {
|
|
1643
1882
|
/**
|
|
1644
1883
|
* @param svgs - One entry per SVG panel; multi-entry for split-panel layouts.
|
|
1645
1884
|
* @param options.classNames - Override default BEM CSS class names.
|
|
1646
1885
|
* @param options.units - Active measurement units (`length` and `diameter`).
|
|
1886
|
+
* @param options.locale - Locale for renderer-drawn text (diameter symbol, and any `RenderConfig` fields resolved via `applyRenderLocale`). Defaults to `'pt'`, matching the package's historical output.
|
|
1647
1887
|
* @param options.renderConfig - Rendering behaviour (zoom, pan, animation, layout). Defaults to `INTERACTIVE_RENDER_CONFIG`.
|
|
1648
1888
|
* @param options.theme - Visual theme overrides. Merged on top of `DEFAULT_WELL_THEME`.
|
|
1649
1889
|
* @param options.onError - Called when a draw error occurs (e.g., a renderer throws). Falls back to `console.error` if omitted.
|
|
1890
|
+
* @param options.onZoom - Called with the current zoom scale (`1` = initial/fit) whenever the user zooms or pans, and whenever `zoomBy`/`resetZoom` are called. No-op if `renderConfig.zoom`/`pan` are both disabled.
|
|
1650
1891
|
*/
|
|
1651
1892
|
constructor(svgs, options = {}) {
|
|
1652
1893
|
this.svgInstances = [];
|
|
@@ -1659,6 +1900,7 @@ var WellRenderer = class {
|
|
|
1659
1900
|
length: "m",
|
|
1660
1901
|
diameter: "mm"
|
|
1661
1902
|
};
|
|
1903
|
+
this.locale = "pt";
|
|
1662
1904
|
if (svgs.length === 0) {
|
|
1663
1905
|
console.warn(
|
|
1664
1906
|
"[WellRenderer] No SVG instances provided. The renderer will be a no-op."
|
|
@@ -1667,6 +1909,7 @@ var WellRenderer = class {
|
|
|
1667
1909
|
}
|
|
1668
1910
|
this.svgInstances = svgs;
|
|
1669
1911
|
if (options.onError) this.onError = options.onError;
|
|
1912
|
+
if (options.onZoom) this.onZoom = options.onZoom;
|
|
1670
1913
|
if (options.classNames) {
|
|
1671
1914
|
this.classes = defu2(
|
|
1672
1915
|
options.classNames,
|
|
@@ -1676,6 +1919,9 @@ var WellRenderer = class {
|
|
|
1676
1919
|
if (options.units) {
|
|
1677
1920
|
this.units = { ...this.units, ...options.units };
|
|
1678
1921
|
}
|
|
1922
|
+
if (options.locale) {
|
|
1923
|
+
this.locale = options.locale;
|
|
1924
|
+
}
|
|
1679
1925
|
if (options.renderConfig) {
|
|
1680
1926
|
this.renderConfig = defu2(
|
|
1681
1927
|
options.renderConfig,
|
|
@@ -1691,7 +1937,7 @@ var WellRenderer = class {
|
|
|
1691
1937
|
const { selector, height, width, margins } = inst;
|
|
1692
1938
|
const svgWidth = width + margins.left + margins.right;
|
|
1693
1939
|
const svgHeight = height + margins.top + margins.bottom;
|
|
1694
|
-
const svg =
|
|
1940
|
+
const svg = d37.select(selector);
|
|
1695
1941
|
svg.selectAll("*").remove();
|
|
1696
1942
|
svg.attr("height", svgHeight).attr("width", svgWidth);
|
|
1697
1943
|
const defs = svg.append("defs");
|
|
@@ -1711,14 +1957,15 @@ var WellRenderer = class {
|
|
|
1711
1957
|
);
|
|
1712
1958
|
const fracturesGroup = poco.append("g").attr("class", this.classes.fractures.group).attr("transform", `translate(${margins.left}, ${margins.top})`).attr("clip-path", `url(#${clipId})`);
|
|
1713
1959
|
fracturesGroup.append("g").attr("class", this.classes.highlights.fracturesGroup);
|
|
1714
|
-
construction.append("g").attr("class", this.classes.constructionLabels.group);
|
|
1715
1960
|
construction.append("g").attr("class", this.classes.cementPad.group);
|
|
1716
1961
|
construction.append("g").attr("class", this.classes.boreHole.group);
|
|
1717
1962
|
construction.append("g").attr("class", this.classes.surfaceCase.group);
|
|
1718
1963
|
construction.append("g").attr("class", this.classes.holeFill.group);
|
|
1719
1964
|
construction.append("g").attr("class", this.classes.wellCase.group);
|
|
1720
1965
|
construction.append("g").attr("class", this.classes.wellScreen.group);
|
|
1966
|
+
construction.append("g").attr("class", this.classes.reduction.group);
|
|
1721
1967
|
construction.append("g").attr("class", this.classes.conflict.group);
|
|
1968
|
+
construction.append("g").attr("class", this.classes.constructionLabels.group);
|
|
1722
1969
|
construction.append("g").attr("class", this.classes.highlights.constructionGroup);
|
|
1723
1970
|
Object.values(this.textures).forEach((texture) => svg.call(texture));
|
|
1724
1971
|
return { svg, height, width, margins, clipId, clipRectId };
|
|
@@ -1732,6 +1979,36 @@ var WellRenderer = class {
|
|
|
1732
1979
|
textures: this.renderConfig.textures
|
|
1733
1980
|
});
|
|
1734
1981
|
}
|
|
1982
|
+
/**
|
|
1983
|
+
* Multiplies the current zoom scale by `factor` (e.g. `1.25` to zoom in,
|
|
1984
|
+
* `1 / 1.25` to zoom out) on every panel. No-op if both `renderConfig.zoom`
|
|
1985
|
+
* and `renderConfig.pan` are disabled (no zoom behavior was attached).
|
|
1986
|
+
*/
|
|
1987
|
+
zoomBy(factor) {
|
|
1988
|
+
for (const state of this.instanceStates) {
|
|
1989
|
+
if (!state.zoomNode) continue;
|
|
1990
|
+
asSvgElement(state.svg).transition().call(state.zoomNode.scaleBy, factor);
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* Resets zoom/pan on every panel back to `renderConfig.zoomLevel`
|
|
1995
|
+
* (defaults to `1`, i.e. the initial fit-to-container view).
|
|
1996
|
+
*/
|
|
1997
|
+
resetZoom() {
|
|
1998
|
+
const target = d37.zoomIdentity.scale(this.renderConfig.zoomLevel ?? 1);
|
|
1999
|
+
for (const state of this.instanceStates) {
|
|
2000
|
+
if (!state.zoomNode) continue;
|
|
2001
|
+
asSvgElement(state.svg).transition().call(state.zoomNode.transform, target);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
/**
|
|
2005
|
+
* Current zoom scale factor of the first panel (`1` = initial/fit).
|
|
2006
|
+
* Returns `1` if zoom/pan is disabled or `prepareSvg()` hasn't run yet.
|
|
2007
|
+
*/
|
|
2008
|
+
getZoomScale() {
|
|
2009
|
+
const node = this.instanceStates[0]?.svg.node();
|
|
2010
|
+
return node ? d37.zoomTransform(node).k : 1;
|
|
2011
|
+
}
|
|
1735
2012
|
/**
|
|
1736
2013
|
* Initialises the SVG DOM structure and preloads FGDC textures.
|
|
1737
2014
|
* Must be called once before the first `draw()`.
|
|
@@ -1746,14 +2023,23 @@ var WellRenderer = class {
|
|
|
1746
2023
|
* Renders the well profile into all configured SVG panels.
|
|
1747
2024
|
* @param profile - The well data to render.
|
|
1748
2025
|
* @param options.units - Override the instance-level measurement units for this render.
|
|
2026
|
+
* @param options.locale - Override the instance-level locale for this render.
|
|
1749
2027
|
* @param options.highlights - Highlight overlays to display on top of the profile.
|
|
1750
2028
|
*/
|
|
1751
2029
|
draw(profile, options = {}) {
|
|
1752
2030
|
if (isWellEmpty(profile)) return;
|
|
2031
|
+
if (profile.version !== 2) {
|
|
2032
|
+
console.warn(
|
|
2033
|
+
`[WellRenderer] Received a .well file with version ${profile.version ?? "unknown"}. Only v2 is supported. Normalize with deserializeWell() from @welldot/core before rendering.`
|
|
2034
|
+
);
|
|
2035
|
+
}
|
|
1753
2036
|
this.units = { ...this.units, ...options.units };
|
|
2037
|
+
if (options.locale) {
|
|
2038
|
+
this.locale = options.locale;
|
|
2039
|
+
}
|
|
1754
2040
|
const highlights = options.highlights ?? {};
|
|
1755
2041
|
const maxValues = getProfileLastItemsDepths(profile);
|
|
1756
|
-
const maxYValues =
|
|
2042
|
+
const maxYValues = d37.max(maxValues) || 0;
|
|
1757
2043
|
if (this.instanceStates.length === 1) {
|
|
1758
2044
|
this.drawLogToInstance(
|
|
1759
2045
|
this.instanceStates[0],
|
|
@@ -1765,7 +2051,7 @@ var WellRenderer = class {
|
|
|
1765
2051
|
return;
|
|
1766
2052
|
}
|
|
1767
2053
|
const totalHeight = this.instanceStates.reduce((s, st) => s + st.height, 0) || 1;
|
|
1768
|
-
const yScaleGlobal =
|
|
2054
|
+
const yScaleGlobal = d37.scaleLinear().domain([0, maxYValues]).range([0, totalHeight]);
|
|
1769
2055
|
let currentDepth = 0;
|
|
1770
2056
|
for (const state of this.instanceStates) {
|
|
1771
2057
|
const maxSvgDepth = yScaleGlobal.invert(
|
|
@@ -1797,6 +2083,7 @@ var WellRenderer = class {
|
|
|
1797
2083
|
const holeFillGroup = svg.select(`.${this.classes.holeFill.group}`);
|
|
1798
2084
|
const wellCaseGroup = svg.select(`.${this.classes.wellCase.group}`);
|
|
1799
2085
|
const wellScreenGroup = svg.select(`.${this.classes.wellScreen.group}`);
|
|
2086
|
+
const reductionGroup = svg.select(`.${this.classes.reduction.group}`);
|
|
1800
2087
|
const conflictGroup = svg.select(`.${this.classes.conflict.group}`);
|
|
1801
2088
|
const constructionLabelsGroup = svg.select(
|
|
1802
2089
|
`.${this.classes.constructionLabels.group}`
|
|
@@ -1817,12 +2104,14 @@ var WellRenderer = class {
|
|
|
1817
2104
|
const POCO_WIDTH = svgWidth * pocoWidthRatio;
|
|
1818
2105
|
const POCO_CENTER = svgWidth * pocoCenterRatio;
|
|
1819
2106
|
const { duration, ease } = this.renderConfig.animation;
|
|
1820
|
-
const transition =
|
|
2107
|
+
const transition = d37.transition().duration(duration).ease(ease);
|
|
1821
2108
|
const tooltips = populateTooltips(
|
|
1822
2109
|
svg,
|
|
1823
2110
|
this.classes,
|
|
1824
2111
|
this.units,
|
|
1825
|
-
this.renderConfig.tooltips
|
|
2112
|
+
this.renderConfig.tooltips,
|
|
2113
|
+
this.renderConfig.tooltipLabels,
|
|
2114
|
+
this.locale
|
|
1826
2115
|
);
|
|
1827
2116
|
const { xLeft: geoXLeft, xRightInset: geoXRightInset } = this.renderConfig.geologic;
|
|
1828
2117
|
const geoXRight = svgWidth - geoXRightInset;
|
|
@@ -1843,11 +2132,14 @@ var WellRenderer = class {
|
|
|
1843
2132
|
fractures: profile.fractures
|
|
1844
2133
|
};
|
|
1845
2134
|
const contentHeight = svgHeight - state.margins.top - state.margins.bottom;
|
|
1846
|
-
const yScaleLocal =
|
|
2135
|
+
const yScaleLocal = d37.scaleLinear().domain([depthFrom, depthTo]).range([0, contentHeight]);
|
|
1847
2136
|
const depthFactor = this.units.length === "ft" ? 3.28084 : 1;
|
|
1848
|
-
const yScaleAxis =
|
|
1849
|
-
const yAxis =
|
|
1850
|
-
(d) => `${d
|
|
2137
|
+
const yScaleAxis = d37.scaleLinear().domain([depthFrom * depthFactor, depthTo * depthFactor]).range([0, contentHeight]);
|
|
2138
|
+
const yAxis = d37.axisLeft(yScaleAxis).tickFormat(
|
|
2139
|
+
(d) => `${formatNumber3(Number(d), {
|
|
2140
|
+
maximumFractionDigits: this.units.length === "ft" ? 1 : 2,
|
|
2141
|
+
locale: this.locale
|
|
2142
|
+
})}${getLengthUnit(this.units.length)}`
|
|
1851
2143
|
);
|
|
1852
2144
|
const gY = svg.select(`.${this.classes.yAxis}`).call(yAxis);
|
|
1853
2145
|
gY.select(".domain").attr("stroke", this.theme.labels.color).attr("fill", "none");
|
|
@@ -1884,6 +2176,7 @@ var WellRenderer = class {
|
|
|
1884
2176
|
holeFillGroup,
|
|
1885
2177
|
wellCaseGroup,
|
|
1886
2178
|
wellScreenGroup,
|
|
2179
|
+
reductionGroup,
|
|
1887
2180
|
conflictGroup,
|
|
1888
2181
|
highlightsGeologicGroup,
|
|
1889
2182
|
highlightsConstructionGroup,
|
|
@@ -1909,6 +2202,7 @@ var WellRenderer = class {
|
|
|
1909
2202
|
classes: this.classes,
|
|
1910
2203
|
textures: this.textures,
|
|
1911
2204
|
units: this.units,
|
|
2205
|
+
locale: this.locale,
|
|
1912
2206
|
constructionData,
|
|
1913
2207
|
groups
|
|
1914
2208
|
};
|
|
@@ -1939,12 +2233,24 @@ var WellRenderer = class {
|
|
|
1939
2233
|
surfaceCaseGroup.selectAll(`g.${this.classes.surfaceCase.rect}`).each((d, i, nodes) => {
|
|
1940
2234
|
if (!d) return;
|
|
1941
2235
|
const sc = d;
|
|
1942
|
-
const g =
|
|
2236
|
+
const g = d37.select(nodes[i]);
|
|
1943
2237
|
const y = transform.applyY(spanY(sc));
|
|
1944
2238
|
const h = transform.k * spanH(sc);
|
|
1945
2239
|
g.select(".surface-case-fill").attr("y", y).attr("height", h);
|
|
1946
2240
|
g.selectAll(".surface-case-side").attr("y1", y).attr("y2", y + h);
|
|
1947
2241
|
});
|
|
2242
|
+
const maxXValsReduction = getProfileDiamValues4(constructionData);
|
|
2243
|
+
const xScaleReduction = d37.scaleLinear().domain([0, d37.max(maxXValsReduction) || 0]).range([0, POCO_WIDTH]);
|
|
2244
|
+
reductionGroup.selectAll(`polygon.${this.classes.reduction.item}`).attr("points", (d) => {
|
|
2245
|
+
const r = d;
|
|
2246
|
+
const yTop = transform.applyY(spanY(r));
|
|
2247
|
+
const yBot = yTop + transform.k * spanH(r);
|
|
2248
|
+
const xTopLeft = (POCO_CENTER - xScaleReduction(r.diam_from)) / 2;
|
|
2249
|
+
const xTopRight = (POCO_CENTER + xScaleReduction(r.diam_from)) / 2;
|
|
2250
|
+
const xBotLeft = (POCO_CENTER - xScaleReduction(r.diam_to)) / 2;
|
|
2251
|
+
const xBotRight = (POCO_CENTER + xScaleReduction(r.diam_to)) / 2;
|
|
2252
|
+
return `${xTopLeft},${yTop} ${xTopRight},${yTop} ${xBotRight},${yBot} ${xBotLeft},${yBot}`;
|
|
2253
|
+
});
|
|
1948
2254
|
fracturesGroup.selectAll(`g.${this.classes.fractures.item}`).attr("transform", (d) => {
|
|
1949
2255
|
if (!d) return null;
|
|
1950
2256
|
const f = d;
|
|
@@ -1966,6 +2272,7 @@ var WellRenderer = class {
|
|
|
1966
2272
|
well_screen: constructionData.well_screen.filter(inDepth)
|
|
1967
2273
|
});
|
|
1968
2274
|
drawHighlights(zoomedCtx, highlights);
|
|
2275
|
+
this.onZoom?.(transform.k);
|
|
1969
2276
|
};
|
|
1970
2277
|
const drawProfile = () => {
|
|
1971
2278
|
drawLithology(ctx, profile.lithology?.filter(inDepth) ?? []);
|
|
@@ -2005,17 +2312,23 @@ var WellRenderer = class {
|
|
|
2005
2312
|
}
|
|
2006
2313
|
const { zoom: zoomEnabled, pan: panEnabled } = this.renderConfig;
|
|
2007
2314
|
if (zoomEnabled || panEnabled) {
|
|
2008
|
-
const zoomNode =
|
|
2315
|
+
const zoomNode = d37.zoom();
|
|
2009
2316
|
if (zoomEnabled || panEnabled) zoomNode.on("zoom", zooming);
|
|
2010
|
-
|
|
2317
|
+
zoomNode.scaleExtent(
|
|
2318
|
+
zoomEnabled ? [
|
|
2319
|
+
this.renderConfig.minZoomScale ?? 0,
|
|
2320
|
+
this.renderConfig.maxZoomScale ?? Infinity
|
|
2321
|
+
] : [1, 1]
|
|
2322
|
+
);
|
|
2011
2323
|
if (!panEnabled)
|
|
2012
2324
|
zoomNode.filter((e) => e.type === "wheel" || e.type === "dblclick");
|
|
2013
2325
|
asSvgElement(svg).call(zoomNode);
|
|
2326
|
+
state.zoomNode = zoomNode;
|
|
2014
2327
|
const initialZoom = this.renderConfig.zoomLevel ?? 1;
|
|
2015
2328
|
if (initialZoom !== 1) {
|
|
2016
2329
|
asSvgElement(svg).call(
|
|
2017
2330
|
zoomNode.transform,
|
|
2018
|
-
|
|
2331
|
+
d37.zoomIdentity.scale(initialZoom)
|
|
2019
2332
|
);
|
|
2020
2333
|
}
|
|
2021
2334
|
}
|
|
@@ -2024,13 +2337,16 @@ var WellRenderer = class {
|
|
|
2024
2337
|
export {
|
|
2025
2338
|
DEFAULT_WELL_THEME,
|
|
2026
2339
|
INTERACTIVE_RENDER_CONFIG,
|
|
2340
|
+
RENDER_LABELS,
|
|
2027
2341
|
STATIC_RENDER_CONFIG,
|
|
2028
2342
|
WellRenderer,
|
|
2343
|
+
applyRenderLocale,
|
|
2029
2344
|
drawWellLegend,
|
|
2030
2345
|
formatDiameter,
|
|
2031
2346
|
formatLength,
|
|
2032
2347
|
getDiameterUnit,
|
|
2033
2348
|
getLengthUnit,
|
|
2034
|
-
importFgdcTextures
|
|
2349
|
+
importFgdcTextures,
|
|
2350
|
+
resolveRenderLabel
|
|
2035
2351
|
};
|
|
2036
2352
|
//# sourceMappingURL=index.js.map
|