{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"Proxy Track","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":"proxy-track","__idx":0},"children":["Proxy Track"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial demonstrates how to share single well template for different well tracks."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial assumes familiarity with the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/MultiWell/Introduction/multiWellCorrelation"},"children":["MultiWell Introduction"]}," tutorials."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-a-datasource","__idx":1},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/MultiWell/ProxyTrack/proxyTrack#createDataSource"},"children":["#"]}," Create a DataSource"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The first step is to create a a data source to be applied for each proxy track. It contains two parts: data binding, data source. Data Binding is associate visuals like LogCurve with provided data. DataSource is a container of your data for the current well. It is passed to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bind"]}," method of data binding with instance of visual to apply data."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-a-template","__idx":2},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/MultiWell/ProxyTrack/proxyTrack#createTemplate"},"children":["#"]}," Create a Template"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The next step is to create a template to be used as prototype for well tracks. The well track API supports adding and removing tracks and provides options to initialize the well from the JSON template. See the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/DataAndTemplates/DataConnection/dataConnection"},"children":["WellLog–Data Connection"]}," tutorial. This template can be loaded with method ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loadTemplate"]}," of WellTrack or can be created programmatically as code below. It contains index track and log track with two curves."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"create-wells","__idx":3},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/MultiWell/ProxyTrack/proxyTrack#createWells"},"children":["#"]}," Create Wells"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In the next step, create proxy well tracks and provide created template as prototype."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"add-data","__idx":4},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/MultiWell/ProxyTrack/proxyTrack#addData"},"children":["#"]}," Add Data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In the next step, add data source and data binding for each created well."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"result","__idx":5},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/MultiWell/ProxyTrack/proxyTrack#result"},"children":["#"]}," Result"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This WellLog–Multi Well Correlation widget can display well tracks and correlation tracks between them. A Well Track can have the different set of tracks and curves, which is named as a template. Often the same template is used for all wells in the display to see correlation between the different wells. In this case usage of a normal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WellTrack"]}," cannot be efficient for big amount of wells, because it has a copy of tracks and curves and the own set of tools. In this case it is better to use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ProxyWellTrack"]}," for read only displays."]},{"$$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 { obfuscate } from \"@int/geotoolkit/lib.js\";\nimport { MultiWellWidget } from \"@int/geotoolkit/welllog/multiwell/MultiWellWidget.ts\";\nimport { ProxyTrackHighlightTool } from \"@int/geotoolkit/welllog/multiwell/tools/ProxyTrackHighlightTool.ts\";\nimport { Range } from \"@int/geotoolkit/util/Range.ts\";\nimport { TrackType as MultiWellTrackType } from \"@int/geotoolkit/welllog/multiwell/TrackType.ts\";\nimport { TrackType as WellLogTrackType } from \"@int/geotoolkit/welllog/TrackType.ts\";\nimport { KnownColors } from \"@int/geotoolkit/util/ColorUtil.ts\";\nimport { MathUtil } from \"@int/geotoolkit/util/MathUtil.ts\";\nimport { LogCurve } from \"@int/geotoolkit/welllog/LogCurve.ts\";\nimport { LineStyle } from \"@int/geotoolkit/attributes/LineStyle.ts\";\nimport { LogMarker } from \"@int/geotoolkit/welllog/LogMarker.ts\";\nimport { AlignmentStyle, TextStyle } from \"@int/geotoolkit/attributes/TextStyle.ts\";\nimport { AnchorType } from \"@int/geotoolkit/util/AnchorType.ts\";\nimport { CorrelationMarker } from \"@int/geotoolkit/welllog/multiwell/correlation/CorrelationMarker.ts\";\nimport { Plot } from \"@int/geotoolkit/plot/Plot.ts\";\nimport { LogData } from \"@int/geotoolkit/welllog/data/LogData.ts\";\nimport { DataBinding } from \"@int/geotoolkit/data/DataBinding.ts\";\nimport { DataSource } from \"@int/geotoolkit/data/DataSource.ts\";\nimport { DataBindingRegistry } from \"@int/geotoolkit/data/DataBindingRegistry.ts\";\nimport curvesData from \"/src/code/WellLog/MultiWell/data/data.json?import\";\nimport { ProxyTrackActivationTool } from \"@int/geotoolkit/welllog/multiwell/tools/ProxyTrackActivationTool.ts\";\nconst bindingFunctions = [];\nclass CurveBinding extends DataBinding {\n  constructor() {\n    super();\n  }\n  accept(node) {\n    return node instanceof LogCurve;\n  }\n  bind(curve, data) {\n    if (data == null) {\n      return;\n    }\n    const id = curve.getName();\n    const source = data.getCurveSource(id);\n    if (source != null) {\n      const limits = MathUtil.calculateNeatLimits(source.getMinValue(), source.getMaxValue());\n      if (curve.isCustomLimits() === true) {\n        curve.setData(source, false, true);\n      } else {\n        curve.setData(source, true, true).setNormalizationLimits(limits.getLow(), limits.getHigh());\n      }\n    }\n  }\n  unbind(curve, data) {\n  }\n}\nobfuscate(CurveBinding);\nclass LogDataSource extends DataSource {\n  constructor(startDepth) {\n    super();\n    this._sources = {};\n    this._startDepth = startDepth;\n    this._step = 10;\n  }\n  getCurveSource(curveMnemonic) {\n    if (this._sources[curveMnemonic]) {\n      return this._sources[curveMnemonic];\n    }\n    const data = new LogData(curveMnemonic);\n    const depths = [];\n    const values = [];\n    const curveData = getCurveData(curveMnemonic);\n    const amountOfPoints = curveData.length;\n    for (let i = 0; i < amountOfPoints; i++) {\n      depths.push(i * this._step + this._startDepth);\n      values.push(curveData[i]);\n    }\n    data.setValues(depths, values);\n    this._sources[curveMnemonic] = data;\n    return data;\n  }\n}\nobfuscate(LogDataSource);\nfunction getCurveData(curveMnemonic) {\n  const curveNames = curvesData.curveNames;\n  const curveData = curvesData.curveData;\n  for (let i = 0; i < curveNames.length; i++) {\n    if (curveNames[i] === curveMnemonic)\n      return curveData[i];\n  }\n  return null;\n}\nfunction createWidget() {\n  const widget = new MultiWellWidget({\n    \"verticalscrollable\": \"auto\",\n    \"horizontalscrollable\": \"auto\",\n    \"tools\": {\n      \"cursortracking\": {\n        \"tooltip\": {\n          \"enabled\": true\n        }\n      }\n    }\n  });\n  widget.getTool().insert(0, [\n    new ProxyTrackHighlightTool(widget.getOverlayLayer(), widget.getTrackContainer()),\n    new ProxyTrackActivationTool(widget)\n  ]);\n  const template = createTemplate(widget);\n  const well1 = widget.addTrack(MultiWellTrackType.ProxyTrack, {\n    \"name\": \"Proxy Well #1\",\n    \"track\": template,\n    \"range\": new Range(0, 500),\n    \"welllog\": {\n      \"range\": new Range(4500, 5e3)\n    },\n    \"tools\": {\n      \"navigation\": true\n    }\n  });\n  const correlationTrack1 = widget.addTrack(MultiWellTrackType.CorrelationTrack, {\n    \"width\": 50\n  });\n  const well2 = widget.addTrack(MultiWellTrackType.ProxyTrack, {\n    \"name\": \"Proxy Well #2\",\n    \"track\": template,\n    \"range\": new Range(50, 300),\n    \"welllog\": {\n      \"range\": new Range(2500, 5e3)\n    },\n    \"tools\": {\n      \"navigation\": true\n    }\n  });\n  const correlationTrack2 = widget.addTrack(MultiWellTrackType.CorrelationTrack, {\n    \"width\": 50\n  });\n  const well3 = widget.addTrack(MultiWellTrackType.ProxyTrack, {\n    \"name\": \"Proxy Well #3\",\n    \"track\": template,\n    \"range\": new Range(25, 400),\n    \"welllog\": {\n      \"range\": new Range(4700, 5e3)\n    },\n    \"tools\": {\n      \"navigation\": true\n    }\n  });\n  addWellData(well1, 4500);\n  addWellData(well2, 2500);\n  addWellData(well3, 4700);\n  function addWellData(well, startDepth) {\n    const data = new LogDataSource(startDepth);\n    const bindingFunc = new CurveBinding();\n    bindingFunctions.push(bindingFunc);\n    well.getDataBinding().add(bindingFunc);\n    well.setData(data);\n  }\n  addTops(well1, \"Tarbert\", 4750, KnownColors.DarkRed);\n  addTops(well2, \"Tarbert\", 3e3, KnownColors.DarkRed);\n  addTops(well3, \"Tarbert\", 4800, KnownColors.DarkRed);\n  addTopsCorrelation(correlationTrack1, 4750, 3e3, KnownColors.DarkRed);\n  addTopsCorrelation(correlationTrack2, 3e3, 4800, KnownColors.DarkRed);\n  return widget;\n}\nfunction createTemplate(widget) {\n  const well = widget.createTrack(MultiWellTrackType.WellTrack, {\n    \"name\": \"Well Prototype\",\n    \"welllog\": {\n      \"range\": new Range(4700, 5e3)\n    }\n  });\n  well.addTrack(WellLogTrackType.IndexTrack);\n  well.addTrack(WellLogTrackType.LinearTrack).addChild([\n    createEmptyCurve(\"GR\").setLineStyle(KnownColors.Green),\n    createEmptyCurve(\"CALI\").setLineStyle(KnownColors.Orange)\n  ]);\n  return well;\n}\nfunction createEmptyCurve(name) {\n  return new LogCurve().setName(name);\n}\nfunction addTops(well, name, depth, color) {\n  well.getMarkerLayer().addChild(\n    new LogMarker(depth).setLineStyle(LineStyle.fromObject({ \"color\": color })).setTextStyle(TextStyle.fromObject({\n      \"color\": color,\n      \"alignment\": AlignmentStyle.Left,\n      \"font\": \"12px sans-serif\"\n    })).setNameLabel(name).setNameLabelPosition(AnchorType.TopCenter).setDepthLabel(depth + \"\").setDepthLabelPosition(AnchorType.BottomCenter)\n  );\n}\nfunction addTopsCorrelation(track, leftDepth, rightDepth, color) {\n  track.addChild(\n    new CorrelationMarker({\n      \"linestyle\": {\n        \"color\": color,\n        \"width\": 2,\n        \"pixelsnapmode\": { \"x\": true, \"y\": true }\n      },\n      \"leftdepth\": leftDepth,\n      \"rightdepth\": rightDepth\n    })\n  );\n}\nfunction createScene(canvas) {\n  const widget = createWidget();\n  const plot = new Plot({\n    \"canvaselement\": canvas,\n    \"root\": widget\n  });\n  widget.setHeaderHeight(\"auto\").fitToHeight();\n  return plot;\n}\nfunction dispose() {\n  bindingFunctions.forEach((bindingFunc) => DataBindingRegistry.getInstance().remove(bindingFunc));\n}\nexport { createScene, dispose };\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#/WellLog/MultiWell/ProxyTrack/proxyTrack?section=result&extract=true","width":"100%","height":"613.5px","style":{"border":"none"}},"children":[]}]},"headings":[{"value":"Proxy Track","id":"proxy-track","depth":1},{"value":"Create a DataSource","id":"create-a-datasource","depth":3},{"value":"Create a Template","id":"create-a-template","depth":3},{"value":"Create Wells","id":"create-wells","depth":3},{"value":"Add Data","id":"add-data","depth":3},{"value":"Result","id":"result","depth":3}],"frontmatter":{"title":"Proxy Track","seo":{"title":"Proxy Track"}},"lastModified":"2026-02-11T19:54:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/solutions/geotoolkit/tutorials/well-log/multi-well/proxy-track","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}