{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"Auxiliary Chart","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":"auxiliary-chart","__idx":0},"children":["Auxiliary Chart"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial demonstrates how to display seismic trace headers as an Auxiliary graph. The graph displays values for the selected headers from the XSection window."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"display-seismic-trace-headers-as-auxiliary-graph","__idx":1},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Seismic/auxiliaryChart#auxiliaryGraph"},"children":["#"]}," Display Seismic Trace Headers as Auxiliary Graph"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The first step is to create a seismic MemoryReader which has three trace headers, 'CDPX', 'CDPY' and 'TraceNumber'. Then, create a Seismic widget with a previously defined pipeline, which internally generates the AuxiliaryChart using the headers and other options."]},{"$$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 { SeismicWidget } from \"@int/geotoolkit/seismic/widgets/SeismicWidget.ts\";\nimport { MemoryReader } from \"@int/geotoolkit/seismic/data/MemoryReader.ts\";\nimport { SeismicColors } from \"@int/geotoolkit/seismic/util/SeismicColors.ts\";\nimport { SeismicPipeline } from \"@int/geotoolkit/seismic/pipeline/SeismicPipeline.ts\";\nimport { TraceHeaderChartWidget } from \"@int/geotoolkit/seismic/widgets/TraceHeaderChartWidget.ts\";\nimport { ToolTipTool } from \"@int/geotoolkit/controls/tools/ToolTipTool.ts\";\nimport { LineChart } from \"@int/geotoolkit/controls/shapes/LineChart.ts\";\nimport { TickPosition } from \"@int/geotoolkit/axis/TickInfo.ts\";\nimport { Range } from \"@int/geotoolkit/util/Range.ts\";\nimport { Point } from \"@int/geotoolkit/util/Point.ts\";\nimport { MathUtil } from \"@int/geotoolkit/util/MathUtil.ts\";\nimport { Node } from \"@int/geotoolkit/scene/Node.ts\";\nimport { Axis } from \"@int/geotoolkit/axis/Axis.ts\";\nimport { Selector } from \"@int/geotoolkit/selection/Selector.ts\";\nimport { from } from \"@int/geotoolkit/selection/from.ts\";\nimport { FieldDesc } from \"@int/geotoolkit/seismic/data/FieldDesc.ts\";\nimport { ColorUtil, KnownColors } from \"@int/geotoolkit/util/ColorUtil.ts\";\nimport { AutoNumberFormat } from \"@int/geotoolkit/util/AutoNumberFormat.ts\";\nconst createPipeline = function(reader) {\n  const pipeline = new SeismicPipeline({\n    \"name\": \"MemorySeismic\",\n    \"reader\": reader,\n    \"statistics\": reader.getStatistics()\n  });\n  const colorProvider = SeismicColors.getDefault();\n  pipeline.setOptions({\n    \"colors\": {\n      \"colormap\": colorProvider.createNamedColorMap(\"RedWhiteBlue\")\n    },\n    \"plot\": {\n      \"type\": {\n        \"wiggle\": true,\n        \"interpolateddensity\": true\n      },\n      \"decimationspacing\": 5\n    }\n  });\n  return pipeline;\n};\nconst createSeismicReader = function() {\n  const sampleRate = 1;\n  const sampleCount = 350;\n  const traceCount = 500;\n  const cdpyCount = 55;\n  const cdpxCount = 5;\n  const reader = new MemoryReader({\n    \"numberoftraces\": traceCount,\n    \"numberofsamples\": sampleCount,\n    \"samplerate\": sampleRate\n  }).setTraceProcessor({\n    \"getTraceData\": function(reader2, trace, traceId) {\n      const thickness = 30;\n      const start = 80;\n      for (let i = start; i < start + thickness; i++) {\n        trace[i + Math.round(thickness * Math.cos(traceId / 64))] = Math.cos(i / 2);\n      }\n    },\n    \"getDataStatistics\": function() {\n      return {\n        \"average\": 0,\n        \"min\": -1,\n        \"max\": 1,\n        \"rms\": Math.sqrt(2) / 2\n      };\n    },\n    \"getTraceHeaderFields\": function() {\n      return [\n        new FieldDesc(0, \"TraceNumber\"),\n        new FieldDesc(1, \"CDPX\"),\n        new FieldDesc(2, \"CDPY\")\n      ];\n    },\n    \"getTraceHeader\": function(reader2, header, headerData, traceId) {\n      headerData[0] = traceId;\n      headerData[1] = 50 + Math.round(traceId / cdpxCount) * cdpxCount;\n      if (traceId === 499)\n        headerData[1] = 10;\n      if (traceId === 6)\n        headerData[1] = 600;\n      headerData[2] = 5 + traceId % cdpyCount;\n    }\n  });\n  return reader;\n};\nfunction initializeAuxiliaryTooltip(seismicWidget) {\n  const selector = new Selector();\n  const multiLineToolTip = true;\n  const format = new AutoNumberFormat();\n  seismicWidget.getAuxiliaryChart().connectTool(\n    new ToolTipTool({\n      \"autoflip\": true,\n      \"callback\": function(pt) {\n        const x = pt.getX();\n        const y = pt.getY();\n        if (isNaN(x) || isNaN(y))\n          return \"\";\n        let toolTipText = '<span class=\"tooltip-title\">Auxiliary chart</span><br>';\n        let selection = selector.select(seismicWidget.getRoot(), x, y, 2);\n        const axes = selection.filter(\n          (item) => item instanceof Axis && Node.findParent(item, TraceHeaderChartWidget) != null\n        );\n        if (axes.length !== 0) {\n          const axis = axes[0];\n          const min = format.format(axis.getModelLimits().getTop());\n          const max = format.format(axis.getModelLimits().getBottom());\n          toolTipText += \"<span style='color: \" + axis.getTitleTextStyle().getColor() + \";'>\" + axis.getTitle() + \": </span>\";\n          toolTipText += \"[\" + min + \" : \" + max + \"]<br>\";\n          return toolTipText;\n        }\n        selection = selection.filter((item) => item instanceof LineChart);\n        if (selection.length === 0) {\n          return \"\";\n        }\n        const lineCharts = from(seismicWidget.getAuxiliaryChart()).where((node) => node instanceof LineChart).selectToArray();\n        let xValue = lineCharts[0].getSceneTransform().inverseTransformPoint(pt).x;\n        xValue = Math.round(xValue);\n        let chartData = lineCharts[0].getData();\n        let traceIndex = MathUtil.findIndex(xValue, chartData.x);\n        if (traceIndex < 0) {\n          traceIndex = ~traceIndex;\n          if (traceIndex > 0) {\n            --traceIndex;\n          }\n        }\n        toolTipText += \"Trace # \" + chartData.x[traceIndex] + \"<br>\";\n        const hitTestRadius = 4;\n        const hitTestPoint = new Point(x, y);\n        for (let i = 0; i < lineCharts.length; ++i) {\n          let yValue = null;\n          chartData = lineCharts[i].getData();\n          if (!multiLineToolTip) {\n            const selectedPoint = lineCharts[i].hitTest(hitTestPoint, hitTestRadius);\n            if (selectedPoint.length > 0 && selectedPoint[0][\"points\"].length > 0) {\n              yValue = selectedPoint[0][\"points\"][0][\"y\"];\n            }\n          } else {\n            yValue = chartData[\"y\"][traceIndex];\n          }\n          if (yValue !== null && !Number.isNaN(yValue)) {\n            const color = chartData.linestyles.length > i ? chartData.linestyles[i].getColor() : \"black\";\n            toolTipText += \"<span style='color: \" + color + \";'>\" + lineCharts[i].getId() + \": </span>\" + Math.round(yValue * 100) / 100 + \"<br>\";\n          }\n        }\n        return toolTipText;\n      }\n    })\n  );\n}\nfunction createSeismicWidget(pipeline) {\n  const formatter = (tickGenerator, parent, orientation, tickInfo, tickIndex, value) => value != null ? (value + 1).toString() : \"\";\n  const widget = new SeismicWidget({\n    \"pipeline\": pipeline,\n    \"colorbar\": {\n      \"axis\": {\n        \"tickgenerator\": {\n          \"edge\": {\n            \"tickvisible\": false,\n            \"labelvisible\": false\n          }\n        }\n      }\n    },\n    \"auxiliarychart\": {\n      \"size\": 120,\n      \"title\": {\n        \"text\": \"Auxiliary Chart\",\n        \"textstyle\": {\n          \"font\": \"16px Roboto\",\n          \"color\": \"gray\"\n        },\n        \"size\": 20\n      },\n      \"charts\": [\n        {\n          \"name\": \"CDPY\",\n          \"linestyle\": KnownColors.Green\n        },\n        {\n          \"name\": \"CDPX\",\n          \"range\": new Range(0, 650),\n          \"neatlimits\": false,\n          \"axis\": {\n            \"linestyle\": \"blue\"\n          },\n          \"chart\": {\n            \"linestyle\": KnownColors.Blue\n          }\n        }\n      ]\n    },\n    \"layouttype\": \"inside\",\n    \"statusbar\": {\n      \"visible\": false\n    },\n    \"table\": {\n      \"visible\": false,\n      \"size\": 100\n    },\n    \"tools\": {\n      \"colorbar\": {\n        \"enabled\": true\n      }\n    }\n  }).setScaleOptions({\n    \"tracescale\": 30,\n    \"samplescale\": 40,\n    \"deviceunit\": \"in\",\n    \"sampleunit\": \"ms\"\n  });\n  const headerFields = pipeline.getReader().getTraceHeaderFields();\n  for (let i = 0; i < headerFields.length; i++) {\n    const header = headerFields[i];\n    const headerInfo = widget.setTraceHeaderVisible(header, header.getName() === \"TraceNumber\");\n    if (headerInfo) {\n      headerInfo[\"label\"].getTextStyle().setColor(\"gray\");\n      headerInfo[\"axis\"].setTickPosition(TickPosition.TopAndBottom).getTickGenerator().setTickStyle(\"major\", \"gray\").setLabelStyle(\"major\", { \"color\": \"gray\" });\n      if (header.getName() === \"TraceNumber\") {\n        headerInfo[\"axis\"].getTickGenerator().setFormatLabelHandler(formatter);\n      }\n    }\n  }\n  return widget;\n}\nfunction toggleChartByName(plot, chartName) {\n  const widget = plot.getRoot();\n  const chartOptions = widget.getOptions()[\"auxiliarychart\"];\n  const charts = chartOptions[\"charts\"];\n  let chartIndex = -1;\n  for (let i = 0; i < charts.length; i++) {\n    const chart = charts[i];\n    if (chart[\"name\"] === chartName) {\n      chartIndex = i;\n      break;\n    }\n  }\n  if (chartIndex === -1) {\n    charts.push({\n      \"name\": chartName,\n      \"linestyle\": ColorUtil.getRandomColorRgb(22)\n    });\n  } else {\n    charts.splice(chartIndex, 1);\n  }\n  widget.setOptions({\n    \"auxiliarychart\": {\n      \"charts\": charts\n    }\n  });\n}\nfunction toggleChart(plot) {\n  const widget = plot.getRoot();\n  const chartOptions = widget.getOptions()[\"auxiliarychart\"];\n  const isChartVisible = chartOptions[\"visible\"] === true;\n  widget.setOptions({\n    \"auxiliarychart\": {\n      \"visible\": !isChartVisible\n    }\n  });\n  let headerInfo = widget.getTraceHeaderAxis(\"TraceNumber\");\n  if (headerInfo == null) {\n    const headerField = widget.getTraceHeader(\"TraceNumber\");\n    headerInfo = widget.getTraceHeaderAxis(headerField);\n  }\n  if (headerInfo != null) {\n    headerInfo[\"axis\"].setTickPosition(!isChartVisible ? TickPosition.TopAndBottom : TickPosition.Bottom);\n  }\n}\nfunction createScene(canvas) {\n  const seismicReader = createSeismicReader();\n  const pipeline = createPipeline(seismicReader);\n  const seismicWidget = createSeismicWidget(pipeline);\n  initializeAuxiliaryTooltip(seismicWidget);\n  seismicWidget.getAuxiliaryChart().getToolByName(\"cross-hair\").setVerticalLineStyle({\n    \"color\": \"red\",\n    \"width\": 2,\n    \"pixelsnapmode\": true\n  });\n  seismicWidget.getToolByName(\"cross-hair\").setLineStyle({\n    \"color\": \"red\",\n    \"width\": 2,\n    \"pixelsnapmode\": true\n  });\n  return new Plot({\n    \"canvaselement\": canvas,\n    \"root\": seismicWidget\n  });\n}\nexport { createScene, toggleChart, toggleChartByName };\n\ncreateScene(document.querySelector('[ref=\"plot\"]'), () => {\n            this.setRubberBandEnabled(false);\n        });\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#/Seismic/auxiliaryChart?section=auxiliaryGraph&extract=true","width":"100%","height":"748.5px","style":{"border":"none"}},"children":[]}]},"headings":[{"value":"Auxiliary Chart","id":"auxiliary-chart","depth":1},{"value":"Display Seismic Trace Headers as Auxiliary Graph","id":"display-seismic-trace-headers-as-auxiliary-graph","depth":3}],"frontmatter":{"title":"Auxiliary Chart","seo":{"title":"Auxiliary Chart"}},"lastModified":"2026-02-11T19:54:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/solutions/geotoolkit/tutorials/seismic/auxiliary-chart","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}