{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"Track Schematics","description":"Accelerate E&P application development and protect your innovation by consuming our Data and Domain APIs / Platform APIs.","lang":"en-US","meta":[{"name":"robots","content":"noindex"}],"llmstxt":{"hide":true,"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"track-schematics","__idx":0},"children":["Track Schematics"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This section provides a simple demonstration of how to use schematics components in tandem with tracks and other elements."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"component-selection","__idx":1},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/TrackSchematics/trackSchematics#selection"},"children":["#"]}," Component Selection"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A selection tool is used to provide information on highlighting on an outside table element. In addition, table rows can be clicked to highlight the corresponding schematic element. The width of the schematic can be adjusted through drag-and-drop."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"div","attributes":{"label":"main","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"import { ComponentNodeFactoryRegistry } from \"@int/geotoolkit/schematics/factory/ComponentNodeFactoryRegistry.ts\";\nimport { WellLogWidget } from \"@int/geotoolkit/welllog/widgets/WellLogWidget.ts\";\nimport { WellBoreData } from \"@int/geotoolkit/schematics/data/WellBoreData.ts\";\nimport { LogAbstractVisual } from \"@int/geotoolkit/welllog/LogAbstractVisual.ts\";\nimport { ViewMode, WellBoreNode } from \"@int/geotoolkit/schematics/scene/WellBoreNode.ts\";\nimport { TrackType } from \"@int/geotoolkit/welllog/TrackType.ts\";\nimport { HeaderType } from \"@int/geotoolkit/welllog/header/LogAxisVisualHeader.ts\";\nimport { Rect } from \"@int/geotoolkit/util/Rect.ts\";\nimport { LogData } from \"@int/geotoolkit/welllog/data/LogData.ts\";\nimport { LogCurve } from \"@int/geotoolkit/welllog/LogCurve.ts\";\nimport { Group } from \"@int/geotoolkit/scene/Group.ts\";\nimport { Rectangle } from \"@int/geotoolkit/scene/shapes/Rectangle.ts\";\nimport { CssLayout } from \"@int/geotoolkit/layout/CssLayout.ts\";\nimport { Plot } from \"@int/geotoolkit/plot/Plot.ts\";\nimport { Layer } from \"@int/geotoolkit/scene/Layer.ts\";\nimport { Events as SelectionEvents } from \"@int/geotoolkit/controls/tools/Selection.ts\";\nimport { ComponentNode } from \"@int/geotoolkit/schematics/scene/ComponentNode.ts\";\nimport { DataTable } from \"@int/geotoolkit/data/DataTable.ts\";\nimport { DataTableAdapter } from \"@int/geotoolkit/widgets/data/DataTableAdapter.ts\";\nimport { TableView } from \"@int/geotoolkit/widgets/TableView.ts\";\nimport { Dimension } from \"@int/geotoolkit/util/Dimension.ts\";\nimport { LineStyle } from \"@int/geotoolkit/attributes/LineStyle.ts\";\nimport { FillStyle } from \"@int/geotoolkit/attributes/FillStyle.ts\";\nimport { ComponentUtils } from \"@int/geotoolkit/schematics/utils/ComponentUtils.ts\";\nimport { NodeTubingBW } from \"/src/code/Schematics/TrackSchematics/nodes/nodetubing.ts\";\nimport { NodePackerBW } from \"/src/code/Schematics/TrackSchematics/nodes/nodepacker.ts\";\nimport { NodeCementBW } from \"/src/code/Schematics/TrackSchematics/nodes/nodecement.ts\";\nimport { NodePerforationBW } from \"/src/code/Schematics/TrackSchematics/nodes/nodeperforation.ts\";\nimport { NodeCasingBW } from \"/src/code/Schematics/TrackSchematics/nodes/nodecasing.ts\";\nimport { componentsData } from \"/src/code/Schematics/TrackSchematics/data/components.ts\";\nimport curveData from \"/src/helpers/curveData.json?import\";\nlet leftRectangle, rightRectangle;\nconst registerSchematicComponents = (data) => {\n  const components = componentsData.map((component) => {\n    const { name, from, to, outer, inner } = component;\n    data.addComponent(name, {\n      geometry: {\n        depth: { from, to },\n        diameter: { outer, inner }\n      }\n    });\n    return JSON.parse(JSON.stringify(data.getProperties()[\"elements\"].slice(-1)[0]));\n  });\n  return components;\n};\nconst createSchematicTable = (components) => {\n  const rows = [];\n  components.forEach((component) => {\n    const geom = component[\"data\"][\"geometry\"];\n    rows.push([\n      component.name,\n      ComponentUtils.getDepthFrom(geom),\n      ComponentUtils.getDepthTo(geom),\n      ComponentUtils.getOuterDiameter(geom),\n      ComponentUtils.getInnerDiameter(geom) || 0\n    ]);\n  });\n  const dataTable = new DataTable({\n    cols: [\n      { name: \"Type\", type: \"string\" },\n      { name: \"Depth (from)\", type: \"number\" },\n      { name: \"Depth (to)\", type: \"number\" },\n      { name: \"Outer Radius\", type: \"number\" },\n      { name: \"Inner Radius\", type: \"number\" }\n    ],\n    rowsdata: rows\n  });\n  const bridge = new DataTableAdapter({\n    \"datatable\": dataTable\n  });\n  return new TableView({\n    \"horizontalscroll\": \"floating\",\n    \"verticalscroll\": \"floating\",\n    \"cols\": 4,\n    \"defaultcellsize\": new Dimension(80, 30),\n    \"highlightcolumnfillstyle\": FillStyle.Empty\n  }).setData(bridge);\n};\nconst createSchematicRegistry = function() {\n  return new ComponentNodeFactoryRegistry(false).setFactory(\"tubing\", (data) => new NodeTubingBW(data)).setFactory(\"packer\", (data) => new NodePackerBW(data)).setFactory(\"cement\", (data) => new NodeCementBW(data)).setFactory(\"perforation\", (data) => new NodePerforationBW(data)).setFactory(\"casing\", (data) => new NodeCasingBW(data));\n};\nconst getGeometryProperty = (geometry, propertyName) => {\n  if (Array.isArray(geometry)) {\n    geometry = geometry[0];\n  }\n  return geometry[propertyName];\n};\nconst highlightComponentNode = (componentNode, wellBoreNode, highlightLayer) => {\n  if (componentNode === void 0) {\n    return;\n  }\n  let bounds = componentNode.getBounds();\n  const diameters = getGeometryProperty(componentNode.getData()[\"geometry\"], \"diameter\");\n  if (diameters[\"inner\"] === void 0) {\n    bounds = wellBoreNode.getSceneTransform().transform(bounds);\n    bounds = highlightLayer.getSceneTransform().inverseTransform(bounds);\n    leftRectangle.setBounds(bounds);\n    leftRectangle.setVisible(true);\n  } else {\n    const width = (diameters[\"outer\"] - diameters[\"inner\"]) / 2;\n    let leftBounds = new Rect(bounds.getLeft(), bounds.getTop(), bounds.getLeft() + width, bounds.getTop() + bounds.getHeight());\n    let rightBounds = new Rect(bounds.getRight() - width, bounds.getTop(), bounds.getRight(), bounds.getTop() + bounds.getHeight());\n    leftBounds = wellBoreNode.getSceneTransform().transform(leftBounds);\n    leftBounds = highlightLayer.getSceneTransform().inverseTransform(leftBounds);\n    rightBounds = wellBoreNode.getSceneTransform().transform(rightBounds);\n    rightBounds = highlightLayer.getSceneTransform().inverseTransform(rightBounds);\n    leftRectangle.setBounds(leftBounds);\n    rightRectangle.setBounds(rightBounds);\n    leftRectangle.setVisible(true);\n    rightRectangle.setVisible(true);\n  }\n};\nconst createWellLogWidget = function(wellBoreNode) {\n  const widget = new WellLogWidget({\n    \"header\": { \"visible\": true },\n    \"footer\": { \"visible\": false },\n    \"border\": { \"visible\": true },\n    \"horizontalscrollable\": false,\n    \"verticalscrollable\": false,\n    \"nodefilter\": (node) => node instanceof LogAbstractVisual || node instanceof WellBoreNode,\n    \"tools\": {\n      \"cursortracking\": {\n        \"tooltip\": {\n          \"enabled\": true\n        }\n      }\n    }\n  }).setAxisHeaderType(HeaderType.Simple).setHeaderHeight(50).setIndexUnit(\"m\").setDepthLimits(0, 500);\n  widget.addTrack(TrackType.IndexTrack);\n  widget.addTrack(TrackType.LinearTrack).setWidth(175).addChild([wellBoreNode]);\n  const values = curveData[\"CALI\"].slice(0, 500);\n  const depths = [];\n  for (let i = 1; i <= 500; ++i) {\n    depths.push(i);\n  }\n  widget.addTrack(TrackType.LinearTrack).setWidth(175).addChild(\n    new LogCurve(\n      new LogData({\n        \"name\": \"CALI\",\n        \"depths\": depths,\n        \"values\": values\n      })\n    ).setLineStyle(\"orange\")\n  );\n  return widget;\n};\nconst createScene = (canvas) => {\n  const wellBoreData = new WellBoreData();\n  const components = registerSchematicComponents(wellBoreData);\n  const geometryBounds = wellBoreData.getGeometryBounds();\n  const wellBoreNode = new WellBoreNode({\n    \"data\": wellBoreData,\n    \"viewmode\": ViewMode.Regular,\n    \"registry\": createSchematicRegistry()\n  }).setBounds(new Rect(0.2, geometryBounds.getTop(), 0.8, geometryBounds.getBottom()));\n  const wellLogWidget = createWellLogWidget(wellBoreNode);\n  const schematicTable = createSchematicTable(components);\n  const plot = new Plot({\n    \"canvaselement\": canvas,\n    \"autosize\": false,\n    \"root\": new Group().setAutoModelLimitsMode(true).setLayout(new CssLayout()).addChild([\n      wellLogWidget.setLayoutStyle({\n        \"top\": 0,\n        \"left\": 0,\n        \"bottom\": 0,\n        \"width\": 400\n      }),\n      schematicTable.setLayoutStyle({\n        \"top\": 0,\n        \"right\": 0,\n        \"bottom\": 0,\n        \"width\": 400\n      })\n    ])\n  });\n  wellLogWidget.fitToHeight();\n  const highlight = new Layer();\n  const highlightLineStyle = new LineStyle(\"rgba(128,129,128, 0.5)\");\n  const highlightFillStyle = new FillStyle(\"rgba(189,89,89,0.5)\");\n  leftRectangle = new Rectangle({\n    \"linestyle\": highlightLineStyle,\n    \"fillstyle\": highlightFillStyle,\n    \"visible\": false\n  });\n  rightRectangle = new Rectangle({\n    \"linestyle\": highlightLineStyle,\n    \"fillstyle\": highlightFillStyle,\n    \"visible\": false\n  });\n  highlight.addChild([leftRectangle, rightRectangle]);\n  wellLogWidget.getTrackContainer().addLayer(highlight);\n  const selectionOff = () => {\n    schematicTable.setActiveRow(null);\n    leftRectangle.setVisible(false);\n    rightRectangle.setVisible(false);\n  };\n  schematicTable.getToolByName(\"TableViewSelection\").on(SelectionEvents.onPick, () => {\n    leftRectangle.setVisible(false);\n    rightRectangle.setVisible(false);\n    const index = schematicTable.getActiveRows()[0];\n    const componentNode = wellBoreNode.getComponents().toArray()[index];\n    highlightComponentNode(componentNode, wellBoreNode, highlight);\n  });\n  wellLogWidget.getToolByName(\"pick\").setNodeFilter((nodes) => nodes.filter((node) => node instanceof ComponentNode)).on(SelectionEvents.onPick, (evt, sender, eventArgs) => {\n    selectionOff();\n    const nodes = eventArgs.getSelection();\n    if (nodes && nodes.length > 0) {\n      const componentNode = nodes[nodes.length - 1];\n      highlightComponentNode(componentNode, wellBoreNode, highlight);\n      const id = componentNode.getId();\n      let index = -1;\n      for (let i = 0; i < components.length; ++i) {\n        if (components[i].data.id === id) {\n          index = i;\n          break;\n        }\n      }\n      schematicTable.setActiveRow(index);\n    }\n  });\n  return plot;\n};\nexport { createScene };\n\ncreateScene(document.querySelector('[ref=\"plot\"]'));\n\n","lang":"ts"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"label":"css","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"css","header":{"controls":{"copy":{}}},"source":"\n.cg-tooltip-holder {\n  position: relative;\n}\n\n.cg-tooltip {\n  position: absolute;\n  display: block;\n  padding: 2px 12px 3px 7px;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 13px;\n  background: white !important;\n  opacity: 0.9;\n  color: #333333;\n  border: solid 1px gray;\n  border-radius: 5px;\n  text-align: left;\n  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n  border-radius: 5px;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n}\n/* Default setting for tooltip */\n.cg-tooltip-container {\n  position: absolute;\n  display: block;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  padding: 3px 7px;\n  background: #f7f7f7;\n  color: #333333;\n  border: 1px solid #938e8e;\n  opacity: 0.8;\n  text-align: left;\n  box-shadow: 3px 3px 10px #888;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n  user-select: none;\n}\n@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {\n  .cg-tooltip-container {\n    border-radius: 0;\n  }\n}\n/* Default left arrow for tooltip */\n.cg-tooltip-arrow-left::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-left: 0;\n  border-right: 5px solid  #938e8e;\n  transform: translate(calc(-100%), -50%);\n}\n.cg-tooltip-arrow-left::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-left: 0;\n  border-right: 4px solid #f7f7f7;\n  transform: translate(calc(-100%), -50%);\n}\n/* Default top arrow for tooltip */\n.cg-tooltip-arrow-top::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 5px solid transparent;\n  border-top: 0;\n  border-bottom: 5px solid #938e8e;\n  transform: translate(-50%, -100%);\n}\n.cg-tooltip-arrow-top::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 4px solid transparent;\n  border-top: 0;\n  border-bottom: 4px solid #f7f7f7;\n  transform: translate(-50%, -100%);\n}\n/* Default right arrow for tooltip */\n.cg-tooltip-arrow-right::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-right: 0;\n  border-left: 5px solid #938e8e;\n  transform: translate(100%, -50%);\n}\n.cg-tooltip-arrow-right::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-right: 0;\n  border-left: 4px solid #f7f7f7;\n  transform: translate(100%, -50%);\n}\n/* Default bottom arrow for tooltip */\n.cg-tooltip-arrow-bottom::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0px;\n  border: 5px solid transparent;\n  border-bottom: 0;\n  border-top: 5px solid #938e8e;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n.cg-tooltip-arrow-bottom::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0;\n  border: 4px solid transparent;\n  border-bottom: 0;\n  border-top: 4px solid #f7f7f7;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n/* Tooltip item name */\n/* Tooltip item value */\n/* .cg-tooltip-item-value */\n/* Tooltip item value */\n.cg-tooltip-item-unit {\n  text-transform: none;\n}\n\n.cg-tooltip-item-name {\n    text-transform: capitalize;\n    white-space: nowrap;\n    vertical-align: middle;\n    font-size: 13px;\n}\n.cg-tooltip-row {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  white-space: pre-wrap;\n  font-size: 12px;\n  line-height: 100%;\n  margin: 1px 0;\n}\n.cg-tooltip-title {\n  font-size: 13px;\n  height: 14px;\n  text-transform: capitalize;\n}\n.cg-tooltip-title .cg-tooltip-symbol {\n  margin-right: 0 !important;\n}\n.cg-tooltip-title-name {\n  vertical-align: middle;\n}\n.cg-tooltip-row + .cg-tooltip-row {\n  margin-top: 4px;\n}\n.cg-tooltip-row.cg-tooltip-title + .cg-tooltip-row {\n  margin-top: 5px;\n}\n.cg-tooltip-item-value + .cg-tooltip-item-unit {\n    margin-left: 1px;\n}\n/* Tooltip symbol */\n.cg-tooltip-symbol-cell {\n  display: inline-flex;\n  min-width: 13px; /* 10px size + 3px margin */\n}\n.cg-tooltip-symbol {\n  margin-right: 3px;\n  background-color: transparent;\n  display: block;\n}\n.cg-tooltip-symbol > img {\n  display: block;\n}\n.cg-tooltip-list-cell {\n  display: inline-flex;\n}\n.cg-tooltip-list-symbol {\n  display: block;\n  margin-right: 3px;\n  width: 6px;\n  height: 6px;\n  vertical-align: middle;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n.cg-tooltip-symbol-legacy {\n  border-radius: 4px;\n  margin-right: 5px;\n  height: 8px;\n  width: 8px;\n  display: inline-block;\n}\n.cg-tooltip-title-legacy {\n  font-weight: 900;\n}\n\n/* Tooltip symbol circle */\n.cg-tooltip-symbol.circle {\n  height: 10px;\n  width: 10px;\n  display: inline-block;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n/* Tooltip symbol line */\n.cg-tooltip-symbol.line {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: scale(1.2, 0.2);\n}\n/* Tooltip symbol diamond */\n.cg-tooltip-symbol.diamond {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: rotate(45deg);\n    border-radius: 0px;\n}\n/* Tooltip symbol square */\n.cg-tooltip-symbol.square {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    border-radius: 0px;\n    border: 1px solid rgba(0,0,0,.4);\n}\n\n","lang":"css"},"children":[]}]}]},{"$$mdtype":"Tag","name":"iframe","attributes":{"src":"https://dc2-documentation.s3.amazonaws.com/documentation/slb-docs-test/5.0/examples/vue/tutorials/index.html#/Schematics/TrackSchematics/trackSchematics?section=selection&extract=true","width":"100%","height":"679.5px","style":{"border":"none"}},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"schematics-components","__idx":2},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/TrackSchematics/trackSchematics#schematics"},"children":["#"]}," Schematics Components"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The tutorial demonstrates how to incorporate a WellBoreNode into WellLogJS's track container. Please refer to the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/Basics/introduction"},"children":["WellLogJS Introduction"]}," tutorial and the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/Basics/Tracks/tracks"},"children":["Tracks"]}," tutorial for more details on WellLogs, Tracks and Track Containers.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"In this tutorial, depth/index tracks are paired with linear tracks so the schematic element can be analyzed easily. The WellBoreNode shape is created using the WellBoreData, then it is added to a linear track as a child. Log Curves are also added to the tracks for a realistic visual comparison.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"Also, this tutorial shows how to incorporate dragging and dropping schematics components to the track and how to highlight schematics elements."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"div","attributes":{"label":"main","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"import { Plot } from \"@int/geotoolkit/plot/Plot.ts\";\nimport { WellLogWidget } from \"@int/geotoolkit/welllog/widgets/WellLogWidget.ts\";\nimport { AnnotatedWidget } from \"@int/geotoolkit/widgets/AnnotatedWidget.ts\";\nimport { ComponentNodeFactoryRegistry } from \"@int/geotoolkit/schematics/factory/ComponentNodeFactoryRegistry.ts\";\nimport { SVGComponentsLoader } from \"@int/geotoolkit/schematics/factory/SVGComponentsLoader.ts\";\nimport { Selector } from \"@int/geotoolkit/selection/Selector.ts\";\nimport { LogData } from \"@int/geotoolkit/welllog/data/LogData.ts\";\nimport { WellBoreData } from \"@int/geotoolkit/schematics/data/WellBoreData.ts\";\nimport { Group } from \"@int/geotoolkit/scene/Group.ts\";\nimport { Rect } from \"@int/geotoolkit/util/Rect.ts\";\nimport { RestrictVisibleModelLimitsStrategy } from \"@int/geotoolkit/scene/RestrictVisibleModelLimitsStrategy.ts\";\nimport { WellBoreNode } from \"@int/geotoolkit/schematics/scene/WellBoreNode.ts\";\nimport { DefaultLabelingStrategy } from \"@int/geotoolkit/schematics/labeling/DefaultLabelingStrategy.ts\";\nimport { LocationType } from \"@int/geotoolkit/schematics/labeling/LocationType.ts\";\nimport { WellBoreWithLabels } from \"@int/geotoolkit/schematics/scene/WellBoreWithLabels.ts\";\nimport { ComponentNode } from \"@int/geotoolkit/schematics/scene/ComponentNode.ts\";\nimport { TrackType } from \"@int/geotoolkit/welllog/TrackType.ts\";\nimport { LogCurve } from \"@int/geotoolkit/welllog/LogCurve.ts\";\nimport { SymbolShape } from \"@int/geotoolkit/scene/shapes/SymbolShape.ts\";\nimport { AnchorType } from \"@int/geotoolkit/util/AnchorType.ts\";\nimport { Node } from \"@int/geotoolkit/scene/Node.ts\";\nimport { CirclePainter } from \"@int/geotoolkit/scene/shapes/painters/CirclePainter.ts\";\nimport { DragAndDrop, Events as DragEvents } from \"@int/geotoolkit/controls/tools/DragAndDrop.ts\";\nimport { ComponentNodeProxy } from \"@int/geotoolkit/schematics/scene/ComponentNodeProxy.ts\";\nimport { KnownColors } from \"@int/geotoolkit/util/ColorUtil.ts\";\nimport { SymbolLabelShape } from \"@int/geotoolkit/schematics/labeling/SymbolLabelShape.ts\";\nimport { SquarePainter } from \"@int/geotoolkit/scene/shapes/painters/SquarePainter.ts\";\nimport { HorizontalBoxLayout } from \"@int/geotoolkit/layout/HorizontalBoxLayout.ts\";\nimport { FitScaleScrollStrategy, Mode } from \"@int/geotoolkit/scene/FitScaleScrollStrategy.ts\";\nimport { Events as DomEvents } from \"@int/geotoolkit/dom.ts\";\nimport { Layer } from \"@int/geotoolkit/scene/Layer.ts\";\nimport { Rectangle } from \"@int/geotoolkit/scene/shapes/Rectangle.ts\";\nimport { Events as SelectionEvents, Selection } from \"@int/geotoolkit/controls/tools/Selection.ts\";\nimport { PointerMode } from \"@int/geotoolkit/controls/tools/PointerMode.ts\";\nimport curveData from \"/src/helpers/curveData.json?import\";\nimport { createWellBoreData } from \"/src/code/Schematics/TrackSchematics/data/wellboredata.ts\";\nimport { arWellCompletion } from \"/src/code/Schematics/TrackSchematics/data/arWellCompletion.ts\";\nimport { SchematicsComponentToolTip } from \"/src/code/Schematics/TrackSchematics/schematisToolTip.ts\";\nconst minDepth = 0;\nlet maxDepth = 14589;\nconst createLogData = (logName) => {\n  const data = curveData[logName];\n  const dDepth = (maxDepth - minDepth) / (data.length - 1);\n  const depthData = [];\n  for (let iValue = 0; iValue < data.length; ++iValue) {\n    depthData.push(minDepth + iValue * dDepth);\n  }\n  return new LogData(logName).setValues(depthData, data);\n};\nconst addWellBoreData = (componentName) => {\n  const wellBoreData = new WellBoreData();\n  const from = 0;\n  const getDescription = (name) => \" \" + name.replace(/ /g, \" <br/> \") + \" \";\n  const curData = {\n    \"description\": getDescription(componentName),\n    \"geometry\": { \"depth\": { \"from\": from, \"to\": from + 85 }, \"diameter\": { \"outer\": 200, \"inner\": 160 } }\n  };\n  if (componentName === \"drilling fluid\") {\n    const range = curData[\"geometry\"];\n    range[\"level\"] = {\n      \"from\": from + 25,\n      \"to\": from + 85\n    };\n  }\n  wellBoreData.addComponent(componentName, curData);\n  return wellBoreData;\n};\nconst initializeCompontensList = (componentNames, registry) => {\n  const componentHeight = 100;\n  const heightBounds = 85;\n  const wellBoreWidth = 70;\n  const labels = [];\n  for (let iCanvas = 0; iCanvas < componentNames.length; iCanvas++) {\n    const item = componentNames[iCanvas];\n    const wellBoreData = addWellBoreData(item);\n    const wellBoreNode = new WellBoreNode({\n      \"data\": wellBoreData,\n      \"registry\": registry\n    });\n    const labelingStrategy = new DefaultLabelingStrategy({\n      \"defaultlocation\": LocationType.Right,\n      \"connectorshape\": null\n    });\n    const label = new WellBoreWithLabels({\n      \"wellborenode\": wellBoreNode,\n      \"labeling\": {\n        \"strategy\": labelingStrategy,\n        \"labelshape\": new SymbolLabelShape({\n          \"painter\": SquarePainter,\n          \"textstyle\": {\n            \"font\": \"12px Roboto\"\n          }\n        }),\n        \"connectorshape\": null\n      }\n    });\n    const ml = label.getModelLimits();\n    const boundsWB = new Rect(ml.getLeft(), ml.getTop(), ml.getLeft() + wellBoreWidth, ml.getBottom());\n    wellBoreNode.setBounds(boundsWB);\n    const position = componentHeight * iCanvas;\n    label.setBounds(new Rect(0, position, 200, position + heightBounds));\n    labels.push(label);\n  }\n  const dragAndDrop = initializeDragAndDrop();\n  return new AnnotatedWidget({\n    \"border\": null,\n    \"tools\": {\n      \"crosshair\": {\n        \"enabled\": false\n      },\n      \"verticalscroll\": {\n        \"size\": 10,\n        \"options\": {\n          \"rounded\": true\n        }\n      }\n    },\n    \"model\": new Group().setModelLimits(new Rect(0, 0, 160, componentNames.length * componentHeight)).addChild(labels),\n    \"annotationssizes\": {\n      \"north\": 0,\n      \"south\": 0,\n      \"west\": 0,\n      \"east\": 15\n    }\n  }).setScaleScrollStrategy(new RestrictVisibleModelLimitsStrategy()).scaleModel(1, 16).connectTool(dragAndDrop);\n};\nconst createSchematicsHighlightingLayer = (widget, wellBoreNode) => {\n  const layer = new Layer();\n  const selectedRectangle = new Rectangle({\n    \"linestyle\": {\n      \"color\": \"rgba(128,129,128, 0.5)\"\n    },\n    \"fillstyle\": {\n      \"color\": \"rgba(189,89,89,0.5)\"\n    },\n    \"visible\": false\n  });\n  layer.addChild(selectedRectangle);\n  widget.getTrackContainer().addLayer(layer);\n  const onPick = (evt, sender, event) => {\n    const nodes = event.getSelection();\n    if (nodes == null || nodes.length < 1) {\n      return;\n    }\n    const node = nodes[nodes.length - 1];\n    if (node) {\n      let rect = node.getBounds();\n      rect = wellBoreNode.getSceneTransform().transform(rect);\n      rect = layer.getSceneTransform().inverseTransform(rect);\n      selectedRectangle.setBounds(rect);\n      selectedRectangle.setVisible(true);\n    }\n  };\n  const onSelectionEnd = (evt, sender) => {\n    const nodes = sender.getSelection();\n    if (nodes == null || nodes.length === 0) {\n      selectedRectangle.setVisible(false);\n    }\n  };\n  const selectionTool = new Selection(layer).setPointerMode(PointerMode.Hover).setNodeFilter((nodes) => nodes.filter((node) => node instanceof ComponentNode)).on(SelectionEvents.onPick, onPick).on(SelectionEvents.onSelectionEnd, onSelectionEnd);\n  widget.getTool().add(selectionTool);\n  return layer;\n};\nconst createWellLogWidget = function(wellBoreNode) {\n  const logGR = createLogData(\"GR\");\n  const logCALI = createLogData(\"CALI\");\n  const wellLogWidget = new WellLogWidget({\n    \"header\": { \"visible\": false },\n    \"footer\": { \"visible\": false },\n    \"border\": { \"visible\": true },\n    \"verticalscrollable\": false,\n    \"horizontalscrollable\": false\n  }).setScaleScrollStrategy(new FitScaleScrollStrategy({\n    \"mode\": Mode.FitVertical\n  })).setDepthLimits(minDepth, maxDepth);\n  wellLogWidget.addTrack(TrackType.IndexTrack).setWidth(50);\n  wellLogWidget.addTrack(TrackType.LinearTrack).setWidth(100).addChild([\n    new LogCurve(logGR).setLineStyle({\n      \"color\": KnownColors.Orange\n    })\n  ]);\n  wellLogWidget.addTrack(TrackType.LinearTrack).setWidth(250).addChild([wellBoreNode, new LogCurve(logCALI).setLineStyle(\"blue\").setMicroPosition(0.05, 0.45).setNormalizationLimits(logCALI.getMaxValue(), logCALI.getMinValue()), new LogCurve(logCALI).setLineStyle(\"green\").setMicroPosition(0.55, 0.95)]);\n  wellLogWidget.addTrack(TrackType.IndexTrack).setWidth(50);\n  wellLogWidget.getToolByName(\"splitter\").setEnabled(false);\n  wellLogWidget.getToolByName(\"tooltip\").setEnabled(true);\n  createSchematicsHighlightingLayer(wellLogWidget, wellBoreNode);\n  return wellLogWidget;\n};\nconst initializeCustomToolTip = function(wellLogWidget, wellBoreNode) {\n  let handle;\n  wellLogWidget.getTrackManipulatorLayer().addChild([\n    handle = new SymbolShape({\n      \"width\": 8,\n      \"height\": 8,\n      \"alignment\": AnchorType.Center,\n      \"sizeisindevicespace\": true,\n      \"painter\": CirclePainter,\n      \"linestyle\": \"#1565C0\",\n      \"fillstyle\": \"#C1E3E8\",\n      \"visible\": false\n    })\n  ]);\n  wellLogWidget.getToolByName(\"tooltip\").getRegistry().register(ComponentNode.getClassName(), new SchematicsComponentToolTip());\n  const updateHandle = (plot, plotPoint) => {\n    const nodes = Selector.select(plot.getRoot(), plotPoint, 2).filter((node) => node instanceof ComponentNode || node instanceof LogCurve);\n    if (nodes.length === 0) {\n      handle.setVisible(false);\n      return;\n    }\n    const selection = nodes[0];\n    const wellLogWidget2 = Node.findParent(selection, WellLogWidget);\n    const manipulatorPoint = wellLogWidget2.getTrackManipulatorLayer().getSceneTransform().inverseTransformPoint(plotPoint);\n    const color = selection instanceof LogCurve ? selection.getLineStyle().getColor() : \"#C1E3E8\";\n    handle.setAnchor(manipulatorPoint).setFillStyle(color, true).setVisible(true);\n  };\n  wellLogWidget.on(DomEvents.Hover, (event, sender, eventArgs) => updateHandle(eventArgs.getPlot(), eventArgs.getPlotPoint()));\n  return wellLogWidget;\n};\nconst initializeDragAndDrop = function() {\n  const dragFilter = (nodes) => {\n    for (let j = nodes.length - 1; j >= 0; j--) {\n      if (nodes[j] instanceof ComponentNodeProxy) {\n        return nodes[j];\n      }\n    }\n    return null;\n  };\n  const onDrop = (evt, source, args) => {\n    const plotPoint = args.getPlotPoint();\n    const componentName = args.getElements()[0].getName();\n    const nodes = Selector.select(args.getPlot().getRoot(), plotPoint.x, plotPoint.y, 2);\n    let wellLogWidget;\n    let wellBoreNode;\n    let isTrackSchematics = false;\n    for (let i = nodes.length - 1; i >= 0; i--) {\n      const node = nodes[i];\n      if (node instanceof WellLogWidget) {\n        wellLogWidget = node;\n      }\n      if (node instanceof WellBoreNode) {\n        wellBoreNode = node;\n        isTrackSchematics = true;\n      }\n    }\n    if (wellLogWidget == null || !isTrackSchematics) {\n      return;\n    }\n    const modelPos = wellBoreNode.getSceneTransform().inverseTransform(plotPoint);\n    const depthModel = modelPos.getY();\n    const from = depthModel;\n    let length = 500;\n    const sLength = Number(prompt(\"Please enter length of component\", length.toString()));\n    if (sLength != null && sLength > 0) {\n      length = sLength;\n      wellBoreNode.getWellBoreData().addComponent(componentName, {\n        geometry: {\n          depth: { from, to: from + length },\n          diameter: { outer: 2.5 }\n        }\n      });\n      maxDepth += length;\n      wellBoreNode.setBounds(new Rect(0.25, minDepth, 0.75, maxDepth));\n      wellLogWidget.setDepthLimits(minDepth, maxDepth);\n    }\n    if (sLength != null && sLength <= 0) {\n      alert(\"Invalid length of component\");\n    }\n  };\n  const dragAndDrop = new DragAndDrop({\n    \"enabled\": true,\n    \"nodefilters\": [{\n      \"drag\": dragFilter\n    }]\n  }).on(DragEvents.onDrop, onDrop);\n  return dragAndDrop;\n};\nconst createScene = async (canvas) => {\n  const registry = new ComponentNodeFactoryRegistry();\n  const loader = new SVGComponentsLoader({\n    \"registry\": registry,\n    \"path\": RESOURCES + \"svg/components.json\"\n  });\n  const registryJS = new ComponentNodeFactoryRegistry();\n  await loader.load();\n  registry.setFactory(\"perforation\", registryJS.getFactory(\"perforation\"));\n  registry.setFactory(\"cement\", registryJS.getFactory(\"cement\"));\n  const compontensList = initializeCompontensList(arWellCompletion, registry);\n  const wellBoreData = createWellBoreData();\n  const wellBoreNode = new WellBoreNode({\n    \"data\": wellBoreData,\n    \"registry\": registry\n  }).setBounds(new Rect(0.25, minDepth, 0.75, maxDepth));\n  const wellLogWidget = createWellLogWidget(wellBoreNode);\n  initializeCustomToolTip(wellLogWidget, wellBoreNode);\n  const plot = new Plot({\n    \"canvaselement\": canvas,\n    \"root\": new Group().setLayout(new HorizontalBoxLayout()).addChild([\n      compontensList.setLayoutStyle({\n        \"width\": \"200px\"\n      }).setMarginsStyle({ right: \"2px\" }),\n      wellLogWidget.setMarginsStyle({ left: \"2px\" })\n    ])\n  });\n  wellLogWidget.fitToHeight().fitToWidth();\n  return plot;\n};\nexport { createScene };\n\ncreateScene(document.querySelector('[ref=\"plot\"]'));\n\n","lang":"ts"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"label":"css","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"css","header":{"controls":{"copy":{}}},"source":"\n.cg-tooltip-holder {\n  position: relative;\n}\n\n.cg-tooltip {\n  position: absolute;\n  display: block;\n  padding: 2px 12px 3px 7px;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 13px;\n  background: white !important;\n  opacity: 0.9;\n  color: #333333;\n  border: solid 1px gray;\n  border-radius: 5px;\n  text-align: left;\n  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n  border-radius: 5px;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n}\n/* Default setting for tooltip */\n.cg-tooltip-container {\n  position: absolute;\n  display: block;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  padding: 3px 7px;\n  background: #f7f7f7;\n  color: #333333;\n  border: 1px solid #938e8e;\n  opacity: 0.8;\n  text-align: left;\n  box-shadow: 3px 3px 10px #888;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n  user-select: none;\n}\n@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {\n  .cg-tooltip-container {\n    border-radius: 0;\n  }\n}\n/* Default left arrow for tooltip */\n.cg-tooltip-arrow-left::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-left: 0;\n  border-right: 5px solid  #938e8e;\n  transform: translate(calc(-100%), -50%);\n}\n.cg-tooltip-arrow-left::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-left: 0;\n  border-right: 4px solid #f7f7f7;\n  transform: translate(calc(-100%), -50%);\n}\n/* Default top arrow for tooltip */\n.cg-tooltip-arrow-top::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 5px solid transparent;\n  border-top: 0;\n  border-bottom: 5px solid #938e8e;\n  transform: translate(-50%, -100%);\n}\n.cg-tooltip-arrow-top::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 4px solid transparent;\n  border-top: 0;\n  border-bottom: 4px solid #f7f7f7;\n  transform: translate(-50%, -100%);\n}\n/* Default right arrow for tooltip */\n.cg-tooltip-arrow-right::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-right: 0;\n  border-left: 5px solid #938e8e;\n  transform: translate(100%, -50%);\n}\n.cg-tooltip-arrow-right::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-right: 0;\n  border-left: 4px solid #f7f7f7;\n  transform: translate(100%, -50%);\n}\n/* Default bottom arrow for tooltip */\n.cg-tooltip-arrow-bottom::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0px;\n  border: 5px solid transparent;\n  border-bottom: 0;\n  border-top: 5px solid #938e8e;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n.cg-tooltip-arrow-bottom::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0;\n  border: 4px solid transparent;\n  border-bottom: 0;\n  border-top: 4px solid #f7f7f7;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n/* Tooltip item name */\n/* Tooltip item value */\n/* .cg-tooltip-item-value */\n/* Tooltip item value */\n.cg-tooltip-item-unit {\n  text-transform: none;\n}\n\n.cg-tooltip-item-name {\n    text-transform: capitalize;\n    white-space: nowrap;\n    vertical-align: middle;\n    font-size: 13px;\n}\n.cg-tooltip-row {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  white-space: pre-wrap;\n  font-size: 12px;\n  line-height: 100%;\n  margin: 1px 0;\n}\n.cg-tooltip-title {\n  font-size: 13px;\n  height: 14px;\n  text-transform: capitalize;\n}\n.cg-tooltip-title .cg-tooltip-symbol {\n  margin-right: 0 !important;\n}\n.cg-tooltip-title-name {\n  vertical-align: middle;\n}\n.cg-tooltip-row + .cg-tooltip-row {\n  margin-top: 4px;\n}\n.cg-tooltip-row.cg-tooltip-title + .cg-tooltip-row {\n  margin-top: 5px;\n}\n.cg-tooltip-item-value + .cg-tooltip-item-unit {\n    margin-left: 1px;\n}\n/* Tooltip symbol */\n.cg-tooltip-symbol-cell {\n  display: inline-flex;\n  min-width: 13px; /* 10px size + 3px margin */\n}\n.cg-tooltip-symbol {\n  margin-right: 3px;\n  background-color: transparent;\n  display: block;\n}\n.cg-tooltip-symbol > img {\n  display: block;\n}\n.cg-tooltip-list-cell {\n  display: inline-flex;\n}\n.cg-tooltip-list-symbol {\n  display: block;\n  margin-right: 3px;\n  width: 6px;\n  height: 6px;\n  vertical-align: middle;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n.cg-tooltip-symbol-legacy {\n  border-radius: 4px;\n  margin-right: 5px;\n  height: 8px;\n  width: 8px;\n  display: inline-block;\n}\n.cg-tooltip-title-legacy {\n  font-weight: 900;\n}\n\n/* Tooltip symbol circle */\n.cg-tooltip-symbol.circle {\n  height: 10px;\n  width: 10px;\n  display: inline-block;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n/* Tooltip symbol line */\n.cg-tooltip-symbol.line {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: scale(1.2, 0.2);\n}\n/* Tooltip symbol diamond */\n.cg-tooltip-symbol.diamond {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: rotate(45deg);\n    border-radius: 0px;\n}\n/* Tooltip symbol square */\n.cg-tooltip-symbol.square {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    border-radius: 0px;\n    border: 1px solid rgba(0,0,0,.4);\n}\n\n","lang":"css"},"children":[]}]}]},{"$$mdtype":"Tag","name":"iframe","attributes":{"src":"https://dc2-documentation.s3.amazonaws.com/documentation/slb-docs-test/5.0/examples/vue/tutorials/index.html#/Schematics/TrackSchematics/trackSchematics?section=schematics&extract=true","width":"100%","height":"688.5px","style":{"border":"none"}},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"adding-the-wellbore-shape-to-welllog-widget","__idx":3},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/TrackSchematics/trackSchematics#addShape"},"children":["#"]}," Adding the WellBore shape to WellLog widget"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This code sample shows how to add the WellBore shape to the WellLog Widget."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"drag-and-drop-functionality","__idx":4},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/TrackSchematics/trackSchematics#dragndrop"},"children":["#"]}," Drag and Drop Functionality"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This example shows how to create a Schematic Builder to edit a bottom hole assembly. The drag and drop functionality is implemented through the use of mouse event listeners. Use the mouse to drag and drop the schematic components in the following canvas."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"div","attributes":{"label":"main","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"import { ComponentNodeFactoryRegistry } from \"@int/geotoolkit/schematics/factory/ComponentNodeFactoryRegistry.ts\";\nimport { SVGComponentsLoader } from \"@int/geotoolkit/schematics/factory/SVGComponentsLoader.ts\";\nimport { WellBoreData } from \"@int/geotoolkit/schematics/data/WellBoreData.ts\";\nimport { Group } from \"@int/geotoolkit/scene/Group.ts\";\nimport { WellBoreNode } from \"@int/geotoolkit/schematics/scene/WellBoreNode.ts\";\nimport { Plot } from \"@int/geotoolkit/plot/Plot.ts\";\nimport { DragAndDrop, Events as DragEvents } from \"@int/geotoolkit/controls/tools/DragAndDrop.ts\";\nimport { ComponentNodeProxy } from \"@int/geotoolkit/schematics/scene/ComponentNodeProxy.ts\";\nimport { CssLayout } from \"@int/geotoolkit/layout/CssLayout.ts\";\nimport { Tools } from \"@int/geotoolkit/controls/tools/Tools.ts\";\nimport { init } from \"@int/geotoolkit/base.js\";\nimport { ComponentUtils } from \"@int/geotoolkit/schematics/utils/ComponentUtils.ts\";\nimport { dragndropArray } from \"/src/code/Schematics/TrackSchematics/data/dragndrop.ts\";\ninit({ \"imports\": [Tools] });\nconst updateComponents = (components) => {\n  const data = new WellBoreData();\n  let start = 0;\n  for (let i = 0; i < components.length; ++i) {\n    const length = components[i][\"length\"];\n    data.addComponent(\n      components[i][\"name\"],\n      {\n        \"description\": components[i][\"description\"],\n        \"geometry\": {\n          \"depth\": { \"from\": start, \"to\": start + length },\n          \"diameter\": {\n            \"outer\": components[i][\"diameter\"][\"outer\"],\n            \"inner\": components[i][\"diameter\"][\"inner\"]\n          }\n        }\n      }\n    );\n    start += length;\n  }\n  return data;\n};\nconst createScene = async (canvas) => {\n  const registry = new ComponentNodeFactoryRegistry();\n  const loader = new SVGComponentsLoader({\n    \"registry\": registry,\n    \"path\": RESOURCES + \"svg/components.json\"\n  });\n  await loader.load();\n  const componentArray = dragndropArray;\n  const data = new WellBoreData();\n  let start = 0;\n  for (let i = 0; i < componentArray.length; i++) {\n    data.addComponent(\n      componentArray[i][\"name\"],\n      {\n        \"description\": componentArray[i][\"description\"],\n        \"geometry\": {\n          \"depth\": {\n            \"from\": start,\n            \"to\": start + componentArray[i][\"length\"]\n          },\n          \"diameter\": {\n            \"outer\": componentArray[i][\"diameter\"][\"outer\"],\n            \"inner\": componentArray[i][\"diameter\"][\"inner\"]\n          }\n        }\n      }\n    );\n    start += componentArray[i][\"length\"];\n  }\n  let targetComponent = null;\n  const placeholder = {\n    \"name\": \"empty\",\n    \"description\": \"empty\",\n    \"length\": 25,\n    \"diameter\": {\n      \"outer\": 0.5,\n      \"inner\": 0\n    }\n  };\n  let wellBoreNode;\n  const rootGroup = new Group().setAutoModelLimitsMode(true).setLayout(new CssLayout()).addChild([\n    wellBoreNode = new WellBoreNode({\n      \"data\": data,\n      \"registry\": registry\n    }).setLayoutStyle({\n      \"left\": 65,\n      \"top\": 0,\n      \"width\": 35,\n      \"bottom\": 0\n    })\n  ]);\n  const plot = new Plot({\n    \"canvaselement\": canvas,\n    \"root\": rootGroup\n  });\n  const onDrag = (nodes) => {\n    let component;\n    for (let j = 0; j < nodes.length; ++j) {\n      const node = nodes[j];\n      if (node instanceof ComponentNodeProxy) {\n        component = node;\n      }\n    }\n    if (!component)\n      return null;\n    const entity = component.getGeometryData();\n    const componentFrom = ComponentUtils.getDepthFrom(entity);\n    const componentTo = ComponentUtils.getDepthTo(entity);\n    const nodeFilter = (element) => ComponentUtils.getDepthFrom(element[\"data\"][\"geometry\"]) === componentFrom && ComponentUtils.getDepthTo(element[\"data\"][\"geometry\"]) === componentTo;\n    for (let k = nodes.length - 1; k >= 0; k--) {\n      const node = nodes[k];\n      if (node instanceof WellBoreNode) {\n        const components = node.getWellBoreData().getProperties()[\"elements\"];\n        const index = components.findIndex(nodeFilter);\n        if (index >= 0) {\n          targetComponent = componentArray[index];\n          componentArray.splice(index, 1, placeholder);\n        }\n        break;\n      }\n    }\n    return component;\n  };\n  const onDropTool = () => {\n    if (targetComponent == null)\n      return;\n    const index = componentArray.findIndex((element) => element[\"name\"] === \"empty\");\n    if (index < 0)\n      return;\n    componentArray.splice(index, 1, targetComponent);\n    wellBoreNode.setWellBoreData(updateComponents(componentArray));\n    targetComponent = null;\n  };\n  const onDragTool = (event, source, args) => {\n    const pt = args.getPlotPoint();\n    const components = data.getProperties()[\"elements\"];\n    if (targetComponent !== null) {\n      const index = components.findIndex((element) => ComponentUtils.getDepthFrom(element[\"data\"][\"geometry\"]) >= pt.getY());\n      if (index >= 0) {\n        const emptyIndex = componentArray.findIndex((element) => element[\"name\"] === \"empty\");\n        if (emptyIndex >= 0)\n          componentArray.splice(emptyIndex, 1);\n        componentArray.splice(index, 0, placeholder);\n        wellBoreNode.setWellBoreData(updateComponents(componentArray));\n      }\n    }\n  };\n  const dragAndDrop = new DragAndDrop({\n    \"nodefilters\": [{\n      \"drag\": onDrag\n    }]\n  }).setEnabled(true).on(DragEvents.onDrop, onDropTool).on(DragEvents.onDrag, onDragTool);\n  plot.getTool().add(dragAndDrop);\n  return plot;\n};\nexport { createScene };\n\ncreateScene(document.querySelector('[ref=\"plot\"]'));\n\n","lang":"ts"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"label":"css","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"css","header":{"controls":{"copy":{}}},"source":"\n.cg-tooltip-holder {\n  position: relative;\n}\n\n.cg-tooltip {\n  position: absolute;\n  display: block;\n  padding: 2px 12px 3px 7px;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 13px;\n  background: white !important;\n  opacity: 0.9;\n  color: #333333;\n  border: solid 1px gray;\n  border-radius: 5px;\n  text-align: left;\n  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n  border-radius: 5px;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n}\n/* Default setting for tooltip */\n.cg-tooltip-container {\n  position: absolute;\n  display: block;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  padding: 3px 7px;\n  background: #f7f7f7;\n  color: #333333;\n  border: 1px solid #938e8e;\n  opacity: 0.8;\n  text-align: left;\n  box-shadow: 3px 3px 10px #888;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n  user-select: none;\n}\n@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {\n  .cg-tooltip-container {\n    border-radius: 0;\n  }\n}\n/* Default left arrow for tooltip */\n.cg-tooltip-arrow-left::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-left: 0;\n  border-right: 5px solid  #938e8e;\n  transform: translate(calc(-100%), -50%);\n}\n.cg-tooltip-arrow-left::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-left: 0;\n  border-right: 4px solid #f7f7f7;\n  transform: translate(calc(-100%), -50%);\n}\n/* Default top arrow for tooltip */\n.cg-tooltip-arrow-top::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 5px solid transparent;\n  border-top: 0;\n  border-bottom: 5px solid #938e8e;\n  transform: translate(-50%, -100%);\n}\n.cg-tooltip-arrow-top::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 4px solid transparent;\n  border-top: 0;\n  border-bottom: 4px solid #f7f7f7;\n  transform: translate(-50%, -100%);\n}\n/* Default right arrow for tooltip */\n.cg-tooltip-arrow-right::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-right: 0;\n  border-left: 5px solid #938e8e;\n  transform: translate(100%, -50%);\n}\n.cg-tooltip-arrow-right::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-right: 0;\n  border-left: 4px solid #f7f7f7;\n  transform: translate(100%, -50%);\n}\n/* Default bottom arrow for tooltip */\n.cg-tooltip-arrow-bottom::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0px;\n  border: 5px solid transparent;\n  border-bottom: 0;\n  border-top: 5px solid #938e8e;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n.cg-tooltip-arrow-bottom::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0;\n  border: 4px solid transparent;\n  border-bottom: 0;\n  border-top: 4px solid #f7f7f7;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n/* Tooltip item name */\n/* Tooltip item value */\n/* .cg-tooltip-item-value */\n/* Tooltip item value */\n.cg-tooltip-item-unit {\n  text-transform: none;\n}\n\n.cg-tooltip-item-name {\n    text-transform: capitalize;\n    white-space: nowrap;\n    vertical-align: middle;\n    font-size: 13px;\n}\n.cg-tooltip-row {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  white-space: pre-wrap;\n  font-size: 12px;\n  line-height: 100%;\n  margin: 1px 0;\n}\n.cg-tooltip-title {\n  font-size: 13px;\n  height: 14px;\n  text-transform: capitalize;\n}\n.cg-tooltip-title .cg-tooltip-symbol {\n  margin-right: 0 !important;\n}\n.cg-tooltip-title-name {\n  vertical-align: middle;\n}\n.cg-tooltip-row + .cg-tooltip-row {\n  margin-top: 4px;\n}\n.cg-tooltip-row.cg-tooltip-title + .cg-tooltip-row {\n  margin-top: 5px;\n}\n.cg-tooltip-item-value + .cg-tooltip-item-unit {\n    margin-left: 1px;\n}\n/* Tooltip symbol */\n.cg-tooltip-symbol-cell {\n  display: inline-flex;\n  min-width: 13px; /* 10px size + 3px margin */\n}\n.cg-tooltip-symbol {\n  margin-right: 3px;\n  background-color: transparent;\n  display: block;\n}\n.cg-tooltip-symbol > img {\n  display: block;\n}\n.cg-tooltip-list-cell {\n  display: inline-flex;\n}\n.cg-tooltip-list-symbol {\n  display: block;\n  margin-right: 3px;\n  width: 6px;\n  height: 6px;\n  vertical-align: middle;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n.cg-tooltip-symbol-legacy {\n  border-radius: 4px;\n  margin-right: 5px;\n  height: 8px;\n  width: 8px;\n  display: inline-block;\n}\n.cg-tooltip-title-legacy {\n  font-weight: 900;\n}\n\n/* Tooltip symbol circle */\n.cg-tooltip-symbol.circle {\n  height: 10px;\n  width: 10px;\n  display: inline-block;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n/* Tooltip symbol line */\n.cg-tooltip-symbol.line {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: scale(1.2, 0.2);\n}\n/* Tooltip symbol diamond */\n.cg-tooltip-symbol.diamond {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: rotate(45deg);\n    border-radius: 0px;\n}\n/* Tooltip symbol square */\n.cg-tooltip-symbol.square {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    border-radius: 0px;\n    border: 1px solid rgba(0,0,0,.4);\n}\n\n","lang":"css"},"children":[]}]}]},{"$$mdtype":"Tag","name":"iframe","attributes":{"src":"https://dc2-documentation.s3.amazonaws.com/documentation/slb-docs-test/5.0/examples/vue/tutorials/index.html#/Schematics/TrackSchematics/trackSchematics?section=dragndrop&extract=true","width":"100%","height":"438.5px","style":{"border":"none"}},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"drag-and-drop-configure","__idx":5},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/TrackSchematics/trackSchematics#draginit"},"children":["#"]}," Drag and Drop configure"]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[]}]},"headings":[{"value":"Track Schematics","id":"track-schematics","depth":1},{"value":"Component Selection","id":"component-selection","depth":3},{"value":"Schematics Components","id":"schematics-components","depth":3},{"value":"Adding the WellBore shape to WellLog widget","id":"adding-the-wellbore-shape-to-welllog-widget","depth":3},{"value":"Drag and Drop Functionality","id":"drag-and-drop-functionality","depth":3},{"value":"Drag and Drop configure","id":"drag-and-drop-configure","depth":3}],"frontmatter":{"title":"Track Schematics","seo":{"title":"Track Schematics"}},"lastModified":"2026-02-11T19:54:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/solutions/geotoolkit/tutorials/schematics/track-schematics","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}