{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"PDF 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":"pdf-schematics","__idx":0},"children":["PDF Schematics"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This section provides a simple demonstration of how to export schematics components to PDF."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"vertical-schematics-widget","__idx":1},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/PDFSchematics/pdfSchematics#verticalSchematicsScene"},"children":["#"]}," Vertical Schematics Widget"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This code creates vertical schematic widget and table widget."]},{"$$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 { Group } from \"@int/geotoolkit/scene/Group.ts\";\nimport { HorizontalBoxLayout } from \"@int/geotoolkit/layout/HorizontalBoxLayout.ts\";\nimport { CompositeSchematicsWidget } from \"@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts\";\nimport { Events as SchematicsNodeEvents } from \"@int/geotoolkit/schematics/scene/WellBoreNode.ts\";\nimport { TableView } from \"@int/geotoolkit/widgets/TableView.ts\";\nimport { Dimension } from \"@int/geotoolkit/util/Dimension.ts\";\nimport { DataTable } from \"@int/geotoolkit/data/DataTable.ts\";\nimport { DataTableAdapter } from \"@int/geotoolkit/widgets/data/DataTableAdapter.ts\";\nimport { FixedTrackWidthStrategy } from \"@int/geotoolkit/schematics/FixedTrackWidthStrategy.ts\";\nimport { AlignmentStyle, BaseLineStyle, TextStyle } from \"@int/geotoolkit/attributes/TextStyle.ts\";\nimport { AnnotationLocation } from \"@int/geotoolkit/layout/AnnotationLocation.ts\";\nimport { TableView as TableShapeView } from \"@int/geotoolkit/controls/shapes/tableview/TableView.ts\";\nconst CellStyle = TableShapeView.CellStyle;\nimport { obfuscate } from \"@int/geotoolkit/lib.js\";\nimport { Application, loadSchematicsData } from \"/src/code/Schematics/PDFSchematics/wellBore2pdf.ts\";\nconst createSchematicTable = (rows) => {\n  const dataTable = new DataTable({\n    cols: [\n      { name: \"Type\", type: \"string\" },\n      { name: \"From\", type: \"number\" },\n      { name: \"To\", type: \"number\" },\n      { name: \"Radius (out)\", type: \"number\" },\n      { name: \"Radius (in)\", type: \"number\" },\n      { name: \"Description\", type: \"string\" }\n    ],\n    rowsdata: rows\n  });\n  const generalTextStyle = TextStyle.fromObject({\n    \"color\": \"#6b6b6b\",\n    \"alignment\": AlignmentStyle.Right,\n    \"baseline\": BaseLineStyle.Middle,\n    \"font\": \"12px Courier\"\n  });\n  const descriptionTextStyle = TextStyle.fromObject({\n    \"color\": \"#6b6b6b\",\n    \"alignment\": AlignmentStyle.Left,\n    \"baseline\": BaseLineStyle.Middle,\n    \"font\": \"12px Courier\"\n  });\n  const dataProvider = new (obfuscate(class extends DataTableAdapter {\n    constructor(props) {\n      super(props);\n    }\n    getContentFormat(column, row, cellStyle) {\n      cellStyle[\"text\"][\"bounds\"].inflate(-5, 0);\n      cellStyle[\"text\"][\"textstyle\"] = column === 5 ? descriptionTextStyle : generalTextStyle;\n      return cellStyle;\n    }\n  }))({\n    \"datatable\": dataTable\n  });\n  const table = new TableView({\n    \"horizontalscroll\": \"floating\",\n    \"verticalscroll\": \"floating\",\n    \"defaultcellsize\": new Dimension(80, 30),\n    \"fitborder\": true,\n    \"border\": {\n      \"pixelsnapmode\": true,\n      \"color\": \"#C0C0C0\"\n    }\n  }).setData(dataProvider).setColumnsSize(0, 90).setColumnsSize(1, 60).setColumnsSize(2, 60).setColumnsSize(5, 250);\n  return table;\n};\nconst loadSchematicsWidget = async () => {\n  const schematicsData = await loadSchematicsData();\n  const registry = schematicsData.registry;\n  const componentRows = schematicsData.componentRows;\n  const wellBoreData = schematicsData.wellBoreData;\n  const schematicsWidget = new CompositeSchematicsWidget({\n    \"gap\": {\n      \"left\": {\n        \"size\": \"0\"\n      },\n      \"right\": {\n        \"size\": \"0\"\n      },\n      \"top\": {\n        \"size\": \"0\"\n      },\n      \"bottom\": {\n        \"size\": \"0\"\n      }\n    },\n    \"annotationssizes\": {\n      \"south\": 0\n    },\n    \"trackwidthstrategy\": new FixedTrackWidthStrategy(150),\n    \"north\": { \"title\": { \"text\": \"Schematics Widget\" } },\n    \"wellborenode\": {\n      \"registry\": registry\n    },\n    \"data\": {\n      \"elements\": wellBoreData\n    }\n  });\n  return {\n    schematicsWidget,\n    wellBoreData,\n    componentRows\n  };\n};\nconst createScene = async (plotElement) => {\n  const schematicsScene = await loadSchematicsWidget();\n  const schematicsWidget = schematicsScene.schematicsWidget;\n  const wellBoreData = schematicsScene.wellBoreData;\n  const schematicTable = createSchematicTable(schematicsScene.componentRows);\n  const plot = new Plot({\n    \"divelement\": plotElement,\n    \"autosize\": true,\n    \"root\": new Group().setAutoModelLimitsMode(true).setLayout(new HorizontalBoxLayout()).addChild([\n      schematicsWidget.setLayoutStyle({\n        \"width\": 390\n      }).setMarginsStyle({ right: \"2px\" }),\n      schematicTable.setMarginsStyle({ left: \"2px\" })\n    ])\n  });\n  schematicsWidget.getAnnotation(AnnotationLocation.Center).setVisible(false);\n  schematicsWidget.on(SchematicsNodeEvents.ComponentsLoaded, () => {\n    schematicsWidget.getAnnotation(AnnotationLocation.Center).setVisible(true);\n    schematicsWidget.fitToBounds();\n  });\n  return new Application({\n    plot,\n    widget: schematicsWidget,\n    wellBoreData\n  });\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/PDFSchematics/pdfSchematics?section=verticalSchematicsScene&extract=true","width":"100%","height":"734px","style":{"border":"none"}},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Close"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"deviated-schematics-widget","__idx":2},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/PDFSchematics/pdfSchematics#deviatedSchematicsScene"},"children":["#"]}," Deviated Schematics Widget"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This code creates deviated schematic widget."]},{"$$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 { ScalesRatioMode } from \"@int/geotoolkit/schematics/scene/MultiLateralWellBoreNode.ts\";\nimport { Trajectory2d } from \"@int/geotoolkit/deviation/Trajectory2d.ts\";\nimport { Mode } from \"@int/geotoolkit/schematics/labeling/Mode.ts\";\nimport { LocationType } from \"@int/geotoolkit/schematics/labeling/LocationType.ts\";\nimport { CompositeSchematicsWidget, DisplayMode } from \"@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts\";\nimport { Application, loadSchematicsData } from \"/src/code/Schematics/PDFSchematics/wellBore2pdf.ts\";\nconst loadSchematicsWidget = async () => loadSchematicsData().then((schematicsData) => {\n  const wellBoreData = schematicsData.wellBoreData;\n  const geometryBounds = wellBoreData.getGeometryBounds();\n  const minDepth = geometryBounds.getTop();\n  const maxDepth = geometryBounds.getBottom();\n  const trajectory = new Trajectory2d({\n    \"data\": {\n      \"x\": [0, 0, 200],\n      \"y\": [0, 250, 500],\n      \"d\": [minDepth, (minDepth + maxDepth) / 2, maxDepth]\n    }\n  });\n  const options = {\n    \"north\": {\n      \"title\": {\n        \"text\": \"Deviated Schematics Widget\"\n      }\n    },\n    \"scalesratiomode\": ScalesRatioMode.Free,\n    \"labeling\": {\n      \"mode\": Mode.Trajectory,\n      \"defaultLocation\": LocationType.Auto\n    },\n    \"annotationssizes\": {\n      \"north\": 50,\n      \"west\": 70,\n      \"south\": 75\n    },\n    \"gap\": {\n      \"left\": {\n        \"size\": \"230px\"\n      },\n      \"right\": {\n        \"size\": \"180px\"\n      },\n      \"top\": {\n        \"size\": \"10px\"\n      },\n      \"bottom\": {\n        \"size\": \"20px\"\n      }\n    },\n    \"data\": {\n      \"elements\": wellBoreData,\n      \"trajectory\": trajectory\n    }\n  };\n  const schematicsWidget = new CompositeSchematicsWidget(options);\n  schematicsWidget.setDisplayMode(DisplayMode.Deviated);\n  return {\n    schematicsWidget,\n    wellBoreData,\n    trajectory\n  };\n});\nconst createScene = async (canvas) => {\n  const schematicsScene = await loadSchematicsWidget();\n  const schematicsWidget = schematicsScene.schematicsWidget;\n  const wellBoreData = schematicsScene.wellBoreData;\n  const plot = new Plot({\n    \"canvaselement\": canvas,\n    \"autosize\": false,\n    \"root\": schematicsWidget\n  });\n  schematicsWidget.fitToBounds();\n  return new Application({\n    plot,\n    widget: schematicsWidget,\n    wellBoreData,\n    trajectory: schematicsScene.trajectory\n  });\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/PDFSchematics/pdfSchematics?section=deviatedSchematicsScene&extract=true","width":"100%","height":"1348.5px","style":{"border":"none"}},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Close"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"composite-schematics-document","__idx":3},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/PDFSchematics/pdfSchematics#compositeSchematicsDocument"},"children":["#"]}," Composite Schematics Document"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This code does not create any schematic widget, it's just export WellBoreData to PDF."]},{"$$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 { Application, loadSchematicsData } from \"/src/code/Schematics/PDFSchematics/wellBore2pdf.ts\";\nimport { createTrajectory2d } from \"/src/code/Schematics/PDFSchematics/data/trajectory2d.ts\";\nconst createScene = async (canvas) => {\n  const schematicsData = await loadSchematicsData();\n  const wellBoreData = schematicsData.wellBoreData;\n  const geometryBounds = wellBoreData.getGeometryBounds();\n  const minDepth = geometryBounds.getTop();\n  const maxDepth = geometryBounds.getBottom();\n  const trajectory2d = createTrajectory2d(minDepth, maxDepth);\n  return new Application({\n    wellBoreData,\n    trajectory: trajectory2d\n  });\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/PDFSchematics/pdfSchematics?section=compositeSchematicsDocument&extract=true","width":"100%","height":"134px","style":{"border":"none"}},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Close"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"export-schematics-and-table-to-pdf","__idx":4},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/PDFSchematics/pdfSchematics#exportToPDF"},"children":["#"]}," Export Schematics and Table to PDF"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This code shows how to export the Schematics Widget and Table Widget to PDF using Reports.JS. XML template defines layout of widgets. This code shows preprocessing of document to fill necessary fields."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"export-schematics-to-pdf-via-nodejs","__idx":5},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/Schematics/PDFSchematics/pdfSchematics#nodeJS2pdf"},"children":["#"]}," Export Schematics to PDF via NodeJS"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This section provides a simple demonstration of how to export schematics components to PDF via NodeJS.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},"To do this:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Go to the the PDFSchematics folder and run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["npm install"]},". Check to ensure node.js is installed. Supported version of node.js can be found in package.json."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["npm start"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To run server-side code, install the following prerequisites:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://nodejs.org"},"children":["node.js"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://www.npmjs.com/package/canvas"},"children":["node-canvas"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The file ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nodeJS-pdf-schematics.js"]}," contains a standard initialization for ReportJS, loading custom fonts if necessary and export to PDF."]},{"$$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 fsPromises from 'fs/promises';\nimport path from 'path';\nimport Canvas from 'canvas';\n\nimport '@int/geotoolkit/environment';\nimport {log} from '@int/geotoolkit/base';\n\nimport {FontSubType} from '@int/geotoolkit/pdf/FontSubType';\nimport {PaperOrientation} from '@int/geotoolkit/scene/exports/PaperOrientation';\nimport {ScalingOptions} from '@int/geotoolkit/scene/exports/ScalingOptions';\nimport {PaperFormatFactory} from '@int/geotoolkit/scene/exports/PaperFormatFactory';\nimport {UnitFactory} from '@int/geotoolkit/util/UnitFactory';\n\nimport {createWellBoreData} from './../data/wellboredata';\nimport {createTrajectory2d} from './../data/trajectory2d';\n\nimport {NodeStream} from './utils/stream';\nimport {SchematicsSession} from './session';\nimport {SchematicsApplication} from './application';\n\n// we need to register real fonts on Canvas to measure it properly, as well as on PDF context\nconst __dirname = './';\nCanvas.registerFont(path.join(__dirname, './fonts', 'roboto.ttf'), {family: 'Roboto'});\nCanvas.registerFont(path.join(__dirname, './fonts', 'roboto-bold.ttf'), {family: 'Roboto', weight: 'bold'});\n\nexportToPdf('./templates/composite-template.xml', 'nodejs-pdf-schematics.pdf');\n\ntype EmbededFontOptions = {\n    'fontName': string;\n    'fontUrl'?: string;\n    'subType'?: FontSubType;\n    'fontWeight'?: string;\n    'fontStyle'?: string;\n    'fontBase64EncodedFile'?: string | ArrayBuffer;\n    'encoding'?: string;\n};\n\nfunction loadFonts (embeddedFonts: EmbededFontOptions[], exportFonts: EmbededFontOptions[]) {\n    const embeddedFontsFontFiles: Promise<void>[] = [];\n    embeddedFonts\n        .forEach((font: EmbededFontOptions) => {\n            const fontFilePath = font['fontUrl'];\n            const fontFilePromise: Promise<void> = fsPromises.readFile(fontFilePath)\n                .then((result) => {\n                    exportFonts\n                        .push({\n                            'subType': FontSubType.TrueType,\n                            'fontName': font['fontName'],\n                            'fontWeight': font['fontWeight'] || 'normal',\n                            'fontStyle': font['fontStyle'] || 'normal',\n                            'fontBase64EncodedFile': result.toString('base64'),\n                            'encoding': 'Identity-H'\n                        });\n                }, (error) => log(error));\n            embeddedFontsFontFiles.push(fontFilePromise);\n        });\n    return Promise.all(embeddedFontsFontFiles);\n}\n\nfunction exportToPdf (reportFileName: string, resultFileName: string) {\n    const onFail = function (reason: Error) {\n        log('Error : ' + reason);\n    };\n    fsPromises.readFile(reportFileName)\n        .then((reportTemplateBuffer) => {\n            const reportTemplateSrc = reportTemplateBuffer.toString();\n\n            const unitFactory = UnitFactory.getInstance();\n            const px = unitFactory.getUnit('px');\n\n            const printSettings = {\n                'paperFormat': PaperFormatFactory.getInstance().getPaper('Letter', px, PaperOrientation.Portrait),\n                's1caling': ScalingOptions.FitWidth,\n                'keepaspectratio': false,\n                'continuous': false,\n                'drawwesttoeast': false,\n                'top': 0.5,\n                'bottom': 0.5,\n                'left': 0.5,\n                'right': 0.5,\n                'units': 'cm'\n            };\n\n            const stream = new NodeStream(resultFileName);\n            const pdfOptions = {\n                'output': 'Widget',\n                'printsettings': printSettings, // uppercase\n                'pdfstream': stream,\n                'embededfonts': [] as EmbededFontOptions[]\n            };\n\n            const robotoFonts: EmbededFontOptions[] = [{\n                'fontUrl': './assets/fonts/roboto.ttf',\n                'fontName': 'Roboto'\n            }, {\n                'fontUrl': './assets/fonts/roboto-bold.ttf',\n                'fontName': 'Roboto',\n                'fontWeight': 'bold'\n            }];\n            loadFonts(robotoFonts, pdfOptions['embededfonts']) // lowercase\n                .then(() => {\n                    const wellBoreData = createWellBoreData();\n                    const geometryBounds = wellBoreData.getGeometryBounds();\n                    const minDepth = geometryBounds.getTop();\n                    const maxDepth = geometryBounds.getBottom();\n                    const trajectory2d = createTrajectory2d(minDepth, maxDepth);\n                    const sessionData = new SchematicsSession(wellBoreData, trajectory2d);\n                    const application = new SchematicsApplication(sessionData);\n\n                    application.exportToPdf(reportTemplateSrc, pdfOptions)\n                        .then(() => end(application), (reason) => {\n                            onFail(reason);\n                            end(application);\n                        });\n                });\n        });\n}\n\nfunction end (application: SchematicsApplication) {\n    if (application) application.dispose();\n    process.exit();\n}\n","lang":"ts"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Close"]}]},"headings":[{"value":"PDF Schematics","id":"pdf-schematics","depth":1},{"value":"Vertical Schematics Widget","id":"vertical-schematics-widget","depth":3},{"value":"Deviated Schematics Widget","id":"deviated-schematics-widget","depth":3},{"value":"Composite Schematics Document","id":"composite-schematics-document","depth":3},{"value":"Export Schematics and Table to PDF","id":"export-schematics-and-table-to-pdf","depth":3},{"value":"Export Schematics to PDF via NodeJS","id":"export-schematics-to-pdf-via-nodejs","depth":3}],"frontmatter":{"title":"PDF Schematics","seo":{"title":"PDF Schematics"}},"lastModified":"2026-02-11T19:54:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/solutions/geotoolkit/tutorials/schematics/pdf-schematics","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}