Dual Schematics Widget

This tutorial shows how to create a Dual Schematics Widget, which is convenience class for a user to be able to see "Planned" versus "Actual" schematics comparison. The widget incapsulates two instances of geotoolkit/schematics/widgets/SchematicsWidget (each with its own data) and includes all the representations' default tools.

# Widget Initialization

The following example demonstrates how to create data using WellBoreData and use it to initialize the Dual Schematics Widget. The code snippet shows a few highlights.

import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { LineStyle } from "@int/geotoolkit/attributes/LineStyle.ts";
import { ComponentNode } from "@int/geotoolkit/schematics/scene/ComponentNode.ts";
import { WellBoreData } from "@int/geotoolkit/schematics/data/WellBoreData.ts";
import { FixedTrackWidthStrategy } from "@int/geotoolkit/schematics/FixedTrackWidthStrategy.ts";
import { StyleUtils } from "@int/geotoolkit/schematics/utils/StyleUtils.ts";
import { StylesRenderingHints } from "@int/geotoolkit/schematics/utils/StylesRenderingHints.ts";
import { DualSchematicsWidget } from "@int/geotoolkit/schematics/widgets/DualSchematicsWidget.ts";
import data from "/src/assets/data/wellBoreData.json?import";
function createData() {
  const plannedData = new WellBoreData(data);
  const actualData = new WellBoreData();
  let name, jsonObject;
  data.forEach((object) => {
    name = object["name"];
    jsonObject = {
      "description": object["data"]["description"],
      "geometry": { ...object["data"]["geometry"] }
    };
    if (name === "casing" || name === "cement" || name === "perforation" || jsonObject["geometry"]["depth"]["to"] < 5100) {
      actualData.addComponent(name, jsonObject);
    }
  });
  return {
    "planned": plannedData,
    "actual": actualData
  };
}
function createScene(canvas) {
  const dualData = createData();
  const dualWidget = new DualSchematicsWidget({
    "trackwidthstrategy": new FixedTrackWidthStrategy(230),
    "data": dualData
  });
  setOutline(dualWidget.getPlannedWidget());
  setGreyScale(dualWidget.getActualWidget());
  return new Plot({
    "canvaselement": canvas,
    "root": dualWidget
  });
}
function myGetGrayScaleLineStyle(options) {
  return StyleUtils.getGrayScaleLineStyle(options["shape"].getLineStyle());
}
function myGetGrayScaleFillStyle(options) {
  return StyleUtils.getGrayScaleFillStyle(options["shape"].getFillStyle());
}
function setGreyScale(widget) {
  widget.setOptions({
    "wellborenode": {
      "renderinghints": {
        "perforation": {
          "height": 15,
          "cutoff": true,
          "fillstyle": "rgb(96, 96, 96)"
        },
        "casing": {
          "inner": {
            "fillstyle": "lightgray"
          },
          "outer": {
            "fillstyle": "black",
            "linestyle": "black"
          },
          "shoe": {
            "fillstyle": "black"
          }
        },
        "*": new StylesRenderingHints({
          "getfillstyle": myGetGrayScaleFillStyle,
          "getlinestyle": myGetGrayScaleLineStyle
        })
      }
    }
  });
}
function myFilterOutCollections(node) {
  if (node instanceof ComponentNode)
    return false;
  if (node instanceof Group)
    return false;
  return true;
}
const myNullLineStyle = new LineStyle("gray");
function myGetOutlineLineStyle(options) {
  const dstLineStyle = StyleUtils.getGrayScaleLineStyle(options["shape"].getLineStyle());
  return dstLineStyle ? dstLineStyle : myNullLineStyle;
}
function myGetOutlineFillStyle(options) {
  return null;
}
function setOutline(widget) {
  widget.setOptions({
    "wellborenode": {
      "renderinghints": {
        "perforation": {
          "height": 15,
          "cutoff": true,
          "fillstyle": "rgb(96, 96, 96)"
        },
        "casing": {
          "inner": {
            "fillstyle": null
          },
          "outer": {
            "fillstyle": "black",
            "linestyle": "black"
          },
          "shoe": {
            "fillstyle": "black"
          }
        },
        "*": new StylesRenderingHints({
          "filternode": myFilterOutCollections,
          "getfillstyle": myGetOutlineFillStyle,
          "getlinestyle": myGetOutlineLineStyle
        })
      }
    }
  });
}
function showDualData(dualWidget) {
  dualWidget.setOptions({
    "planned": {
      "north": { "title": { "text": "Planned" } }
    },
    "actual": {
      "north": { "title": { "text": "Actual" } }
    }
  });
  setOutline(dualWidget.getPlannedWidget());
  setGreyScale(dualWidget.getActualWidget());
  const dualData = createData();
  dualWidget.setData({
    "planned": dualData["planned"],
    "actual": dualData["actual"]
  });
}
function showPlannedDataOnly(dualWidget) {
  dualWidget.setOptions({
    "north": { "title": { "text": "Planned" } }
  });
  setOutline(dualWidget.getPlannedWidget());
  setOutline(dualWidget.getActualWidget());
  const dualData = createData();
  dualWidget.setData({
    "planned": dualData["planned"],
    "actual": dualData["planned"]
  });
}
function showActualDataOnly(dualWidget) {
  dualWidget.setOptions({
    "north": { "title": { "text": "Actual" } }
  });
  setGreyScale(dualWidget.getPlannedWidget());
  setGreyScale(dualWidget.getActualWidget());
  const dualData = createData();
  dualWidget.setData({
    "planned": dualData["actual"],
    "actual": dualData["actual"]
  });
}
export { createScene, showActualDataOnly, showDualData, showPlannedDataOnly };

createScene(document.querySelector('[ref="plot"]'));