@welldot/render 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -832,9 +832,6 @@ var DEFAULT_COMPONENTS_CLASS_NAMES = {
832
832
  var import_textures2 = __toESM(require("textures"), 1);
833
833
 
834
834
  // src/utils/d3.utils.ts
835
- function mergeEnter(enter, update) {
836
- return enter.merge(update);
837
- }
838
835
  function withTransition(selection, transition) {
839
836
  return selection.transition(transition);
840
837
  }
@@ -852,6 +849,18 @@ var getYAxisFunctions = (yScale, clamp) => {
852
849
  getYPos: ({ from }) => yScale(Math.max(from, clampFrom))
853
850
  };
854
851
  };
852
+ function hashStr(s) {
853
+ let h = 5381;
854
+ for (let i = 0; i < s.length; i++) {
855
+ h = Math.imul(h, 33) ^ s.charCodeAt(i);
856
+ }
857
+ return (h >>> 0).toString(36);
858
+ }
859
+ function stableLayerKey(d) {
860
+ const { from: _f, to: _t, ...rest } = d;
861
+ const sortedKeys = Object.keys(rest).sort();
862
+ return hashStr(JSON.stringify(rest, sortedKeys));
863
+ }
855
864
  function filterByDepth(depthFrom, depthTo) {
856
865
  return (l) => !(l.to <= depthFrom || l.from >= depthTo);
857
866
  }
@@ -904,10 +913,11 @@ var import_d3_tip = __toESM(require("d3-tip"), 1);
904
913
  var import_sanitize_html = __toESM(require("sanitize-html"), 1);
905
914
  var d3 = Object.assign(d3module, { tip: import_d3_tip.default });
906
915
  var esc = (v) => (0, import_sanitize_html.default)(String(v ?? ""), { allowedTags: [], allowedAttributes: {} });
916
+ var _tooltipCache = /* @__PURE__ */ new WeakMap();
907
917
  var populateTooltips = (svg, customClasses, units, tooltipConfig) => {
908
918
  const svgEl = typeof svg.node === "function" ? svg.node() : null;
909
- if (svgEl?.getAttribute("data-tooltips-init") === "true") {
910
- return {};
919
+ if (svgEl && _tooltipCache.has(svgEl)) {
920
+ return _tooltipCache.get(svgEl);
911
921
  }
912
922
  const tipsText = {
913
923
  geology: (_, d) => `
@@ -1003,6 +1013,7 @@ var populateTooltips = (svg, customClasses, units, tooltipConfig) => {
1003
1013
  );
1004
1014
  });
1005
1015
  svgEl?.setAttribute("data-tooltips-init", "true");
1016
+ if (svgEl) _tooltipCache.set(svgEl, tooltips);
1006
1017
  return tooltips;
1007
1018
  };
1008
1019
 
@@ -1020,13 +1031,20 @@ var preloadFgdcTextures = () => {
1020
1031
  var getLithologicalFillList = (data, opts) => {
1021
1032
  const uniqueTextureCodes = [...new Set(data.map((d) => d.fgdc_texture))];
1022
1033
  const texturesLoaded = Object.fromEntries(
1023
- uniqueTextureCodes.filter((code) => _fgdcTextures[code]).map((code) => [code, _fgdcTextures[code]])
1034
+ uniqueTextureCodes.filter((code) => {
1035
+ const path = _fgdcTextures[code];
1036
+ return path && path !== "-" && /^[Mm]/.test(path);
1037
+ }).map((code) => [code, _fgdcTextures[code]])
1024
1038
  );
1025
1039
  return Object.fromEntries(
1026
- data.map((d) => [
1027
- `${d.fgdc_texture}.${d.from}`,
1028
- import_textures2.default.paths().d(() => texturesLoaded[d.fgdc_texture]).size(opts.size).strokeWidth(opts.strokeWidth).stroke(opts.stroke).background(d.color)
1029
- ])
1040
+ data.map((d) => {
1041
+ const pathData = texturesLoaded[d.fgdc_texture];
1042
+ if (!pathData) return [`${d.fgdc_texture}.${d.from}`, d.color];
1043
+ return [
1044
+ `${d.fgdc_texture}.${d.from}`,
1045
+ import_textures2.default.paths().d(() => pathData).size(opts.size).strokeWidth(opts.strokeWidth).stroke(opts.stroke).background(d.color)
1046
+ ];
1047
+ })
1030
1048
  );
1031
1049
  };
1032
1050
  var getLithologyFill = (geologyData, svg, opts) => {
@@ -1342,19 +1360,36 @@ function drawConstructive(ctx, data) {
1342
1360
  }).attr("fill", ctx.textures.pad.url()).attr("stroke", ctx.theme.cementPad.stroke).attr("stroke-width", ctx.theme.cementPad.strokeWidth);
1343
1361
  newCementPad.on("mouseover", ctx.tooltips.cementPad.show).on("mouseout", ctx.tooltips.cementPad.hide);
1344
1362
  }
1345
- const hole = ctx.groups.holeGroup.selectAll(`.${ctx.classes.boreHole.rect}`).data(data.bore_hole);
1346
- hole.exit().remove();
1347
- 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);
1348
- const mergedHole = mergeEnter(newHole, hole).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1349
- withTransition(mergedHole, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1350
- const surfaceCaseGs = ctx.groups.surfaceCaseGroup.selectAll(`g.${ctx.classes.surfaceCase.rect}`).data(data.surface_case);
1363
+ const hole = ctx.groups.holeGroup.selectAll(`.${ctx.classes.boreHole.rect}`).data(data.bore_hole, stableLayerKey);
1364
+ hole.exit().transition(ctx.transition).attr("height", 0).remove();
1365
+ 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("stroke-width", ctx.theme.boreHole.strokeWidth).attr("stroke-dasharray", ctx.theme.boreHole.strokeDasharray).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter)).attr("y", getYPos).attr("height", getHeight).attr("opacity", 0).on("mouseover", ctx.tooltips.hole.show).on("mouseout", ctx.tooltips.hole.hide);
1366
+ withTransition(newHole, ctx.transition).attr(
1367
+ "opacity",
1368
+ ctx.theme.boreHole.opacity
1369
+ );
1370
+ hole.attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1371
+ withTransition(hole, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1372
+ const surfaceCaseGs = ctx.groups.surfaceCaseGroup.selectAll(`g.${ctx.classes.surfaceCase.rect}`).data(data.surface_case, stableLayerKey);
1351
1373
  surfaceCaseGs.exit().transition(ctx.transition).style("opacity", 0).remove();
1352
- const newSC = surfaceCaseGs.enter().append("g").attr("class", ctx.classes.surfaceCase.rect).on("mouseover", ctx.tooltips.surfaceCase.show).on("mouseout", ctx.tooltips.surfaceCase.hide);
1374
+ const newSC = surfaceCaseGs.enter().append("g").attr("class", ctx.classes.surfaceCase.rect).style("opacity", 0).on("mouseover", ctx.tooltips.surfaceCase.show).on("mouseout", ctx.tooltips.surfaceCase.hide);
1353
1375
  newSC.append("rect").attr("class", "surface-case-fill").attr("stroke", "none");
1354
1376
  newSC.append("line").attr("class", "surface-case-side").attr("stroke", ctx.theme.surfaceCase.stroke).attr("stroke-width", ctx.theme.surfaceCase.strokeWidth);
1355
1377
  newSC.append("line").attr("class", "surface-case-side").attr("stroke", ctx.theme.surfaceCase.stroke).attr("stroke-width", ctx.theme.surfaceCase.strokeWidth);
1356
- const mergedSC = mergeEnter(newSC, surfaceCaseGs);
1357
- mergedSC.each((d, i, nodes) => {
1378
+ newSC.each((d, i, nodes) => {
1379
+ const x = (ctx.POCO_CENTER - xScale(
1380
+ d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio
1381
+ )) / 2;
1382
+ const w = xScale(
1383
+ d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio
1384
+ );
1385
+ const g = d33.select(nodes[i]);
1386
+ g.select(".surface-case-fill").attr("x", x).attr("width", w).attr("fill", ctx.textures.surface_case.url()).attr("y", getYPos(d)).attr("height", getHeight(d));
1387
+ const sideNodes = g.selectAll(".surface-case-side").nodes();
1388
+ d33.select(sideNodes[0]).attr("x1", x).attr("x2", x).attr("y1", getYPos(d)).attr("y2", getYPos(d) + getHeight(d));
1389
+ d33.select(sideNodes[1]).attr("x1", x + w).attr("x2", x + w).attr("y1", getYPos(d)).attr("y2", getYPos(d) + getHeight(d));
1390
+ });
1391
+ withTransition(newSC, ctx.transition).style("opacity", 1);
1392
+ surfaceCaseGs.each((d, i, nodes) => {
1358
1393
  const x = (ctx.POCO_CENTER - xScale(
1359
1394
  d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio
1360
1395
  )) / 2;
@@ -1368,37 +1403,44 @@ function drawConstructive(ctx, data) {
1368
1403
  d33.select(sideNodes[1]).attr("x1", x + w).attr("x2", x + w);
1369
1404
  });
1370
1405
  withTransition(
1371
- mergedSC.select(".surface-case-fill"),
1406
+ surfaceCaseGs.select(".surface-case-fill"),
1372
1407
  ctx.transition
1373
1408
  ).attr("y", (d) => getYPos(d)).attr("height", (d) => getHeight(d));
1374
- mergedSC.selectAll(".surface-case-side").attr("y1", (d) => getYPos(d)).attr(
1409
+ withTransition(
1410
+ surfaceCaseGs.selectAll(".surface-case-side"),
1411
+ ctx.transition
1412
+ ).attr("y1", (d) => getYPos(d)).attr(
1375
1413
  "y2",
1376
1414
  (d) => getYPos(d) + getHeight(d)
1377
1415
  );
1378
- const holeFill = ctx.groups.holeFillGroup.selectAll(`.${ctx.classes.holeFill.rect}`).data(data.hole_fill);
1379
- holeFill.exit().remove();
1380
- 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);
1381
- const mergedHoleFill = mergeEnter(newHoleFill, holeFill).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1382
- withTransition(mergedHoleFill, ctx.transition).attr("y", getYPos).attr("height", getHeight).attr("fill", (d) => ctx.textures[d.type].url());
1383
- const wellCase = ctx.groups.wellCaseGroup.selectAll(`.${ctx.classes.wellCase.rect}`).data(data.well_case);
1384
- wellCase.exit().remove();
1385
- 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);
1386
- const mergedWellCase = mergeEnter(newWellCase, wellCase).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1387
- withTransition(mergedWellCase, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1388
- const wellScreen = ctx.groups.wellScreenGroup.selectAll(`.${ctx.classes.wellScreen.rect}`).data(data.well_screen);
1389
- wellScreen.exit().remove();
1390
- 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);
1391
- const mergedWellScreen = mergeEnter(newWellScreen, wellScreen).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1392
- withTransition(mergedWellScreen, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1416
+ const holeFill = ctx.groups.holeFillGroup.selectAll(`.${ctx.classes.holeFill.rect}`).data(data.hole_fill, stableLayerKey);
1417
+ holeFill.exit().transition(ctx.transition).attr("height", 0).remove();
1418
+ 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).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter)).attr("y", getYPos).attr("height", getHeight).attr("fill", (d) => ctx.textures[d.type].url()).attr("opacity", 0).on("mouseover", ctx.tooltips.holeFill.show).on("mouseout", ctx.tooltips.holeFill.hide);
1419
+ withTransition(newHoleFill, ctx.transition).attr("opacity", 1);
1420
+ holeFill.attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter)).attr("fill", (d) => ctx.textures[d.type].url());
1421
+ withTransition(holeFill, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1422
+ const wellCase = ctx.groups.wellCaseGroup.selectAll(`.${ctx.classes.wellCase.rect}`).data(data.well_case, stableLayerKey);
1423
+ wellCase.exit().transition(ctx.transition).attr("height", 0).remove();
1424
+ 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).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter)).attr("y", getYPos).attr("height", getHeight).attr("opacity", 0).on("mouseover", ctx.tooltips.wellCase.show).on("mouseout", ctx.tooltips.wellCase.hide);
1425
+ withTransition(newWellCase, ctx.transition).attr("opacity", 1);
1426
+ wellCase.attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1427
+ withTransition(wellCase, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1428
+ const wellScreen = ctx.groups.wellScreenGroup.selectAll(`.${ctx.classes.wellScreen.rect}`).data(data.well_screen, stableLayerKey);
1429
+ wellScreen.exit().transition(ctx.transition).attr("height", 0).remove();
1430
+ 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).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter)).attr("y", getYPos).attr("height", getHeight).attr("opacity", 0).on("mouseover", ctx.tooltips.wellScreen.show).on("mouseout", ctx.tooltips.wellScreen.hide);
1431
+ withTransition(newWellScreen, ctx.transition).attr("opacity", 1);
1432
+ wellScreen.attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1433
+ withTransition(wellScreen, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1393
1434
  const conflictAreas = [];
1394
1435
  conflictAreas.push(...getConflictAreas(data.well_case, data.well_screen));
1395
1436
  conflictAreas.push(...getConflictAreas(data.well_screen, data.well_case));
1396
1437
  const mergedConflicts = mergeConflicts(conflictAreas, 1);
1397
- const conflict = ctx.groups.conflictGroup.selectAll(`.${ctx.classes.conflict.rect}`).data(mergedConflicts);
1398
- conflict.exit().remove();
1399
- 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);
1400
- const mergedConflict = mergeEnter(newConflict, conflict).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1401
- withTransition(mergedConflict, ctx.transition).attr("y", ctx.yScale(0)).attr("height", getHeight);
1438
+ const conflict = ctx.groups.conflictGroup.selectAll(`.${ctx.classes.conflict.rect}`).data(mergedConflicts, (d) => `${d.from}_${d.to}_${d.diameter}`);
1439
+ conflict.exit().transition(ctx.transition).attr("height", 0).remove();
1440
+ 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).attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter)).attr("y", getYPos).attr("height", getHeight).attr("opacity", 0).on("mouseover", ctx.tooltips.conflict.show).on("mouseout", ctx.tooltips.conflict.hide);
1441
+ withTransition(newConflict, ctx.transition).attr("opacity", 1);
1442
+ conflict.attr("x", (d) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2).attr("width", (d) => xScale(d.diameter));
1443
+ withTransition(conflict, ctx.transition).attr("y", getYPos).attr("height", getHeight);
1402
1444
  }
1403
1445
 
1404
1446
  // src/renderers/fractures.renderer.ts
@@ -1878,11 +1920,13 @@ function drawLithology(ctx, data) {
1878
1920
  from: depthFrom,
1879
1921
  to: depthTo
1880
1922
  });
1881
- const rects = lithologyGroup.selectAll(`.${classes.lithology.rect}`).data(data);
1882
- rects.exit().remove();
1883
- 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);
1884
- const merged = mergeEnter(newLayers, rects).attr("y", getYPos);
1885
- withTransition(merged, transition).attr("height", getHeight).attr("fill", getLithologyFill(data, svg, ctx.theme.lithologyTexture));
1923
+ const fillFn = getLithologyFill(data, svg, ctx.theme.lithologyTexture);
1924
+ const rects = lithologyGroup.selectAll(`.${classes.lithology.rect}`).data(data, stableLayerKey);
1925
+ rects.exit().transition(transition).attr("height", 0).remove();
1926
+ 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).attr("y", getYPos).attr("height", getHeight).attr("fill", fillFn).attr("opacity", 0).on("mouseover", tooltips.geology.show).on("mouseout", tooltips.geology.hide);
1927
+ withTransition(newLayers, transition).attr("opacity", 1);
1928
+ rects.attr("fill", fillFn);
1929
+ withTransition(rects, transition).attr("y", getYPos).attr("height", getHeight);
1886
1930
  }
1887
1931
 
1888
1932
  // src/renderers/unit-labels.renderer.ts