This Labeling tutorial shows how to add labels to the components of a schematic shape. The default labels can be changed by selecting other labeling modes. Modes allow changing label location, alignment, background color, and numbering and allow the addition of connector lines.
When labeling is required, the geotoolkit/schematics/widgets/SchematicsWidget object must be created for vertical display mode. Correspondingly, geotoolkit/schematics/widgets/DeviatedSchematicsWidget object must be created for deviated display mode, and geotoolkit/schematics/widgets/LShapedSchematicsWidget object must be created for L-shape display mode.
# Labeling Namespace
Schematics geotoolkit/schematics/labeling namespace overview:
I. What components to label:
Abstraction: IComponentsFilter
Implementations: DefaultComponentsFilter
How to reach it: LabelingStrategyBase.prototype.ComponentsFilter
II. Where to put labels for the filtered components:
Abstraction: LabelingStrategy
Implementations: DefaultLabelingStrategy (older default strategy - being deprecated);
VersatileLabelingStrategy (newer default strategy - recommended);
XYLabelingStrategy
DefaultDeviatedStrategy (special implementation for deviated schematics)
How to reach it:
SchematicsWidget.prototype.getOptions (setting is available via the widget's constructor)
III. What information to display in a component label:
This is a function accepting reference to {geotoolkit.schematics.scene.ComponentNode} of interest
Default implementation: returns componentNode.getDescription()
How to reach it: LabelingStrategy.prototype.LabelInfoProvider
# "Docked" Mode (Default Settings)
The default setting for SchematicsWidget labeling is "docked" mode, aligning labels away from and to the right of the wellbore, in a manner similar to a tooltip.
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { WellBoreData } from "@int/geotoolkit/schematics/data/WellBoreData.ts";
import { CompositeSchematicsWidget } from "@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts";
import data from "/src/assets/data/wellBoreData.json?import";
function createScene(canvas) {
function createWellBoreData() {
return new WellBoreData(data);
}
const options = {
"north": {
"title": {
"text": "Schematics Widget"
}
},
"gap": {
"left": {
"size": "30"
},
"right": {
"visible": false
}
},
"annotationssizes": {
"north": 30,
"south": 0
},
"data": {
"elements": createWellBoreData()
}
};
return new Plot({
"canvaselement": canvas,
"root": new CompositeSchematicsWidget(options)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# "Docked" Mode (Custom Settings)
Customizations can be made to the default labeling strategy through setting labeling options in setOptions such as:
'locationMap': Defines locations for label of certain components. In the example, casing, cement, and perforation components are located to the left of the wellbore.'defaultLocation': Set the default anchor location for labels, this setting will be overridden by specifications set in'locationMap'.'defaultAlignment': Labels are aligned against the outer edge of the SchematicsWidgetAlignmentType.Outer, against the borderAlignmentType.Inner, or centeredAlignmentType.Middle.'connectorShape': This option defines the appearance of the line connecting the label to its relevant component in the wellbore, allowing customization of color, width, and line pattern.'labelInfoProvider': This option accepts a callback function that is used to define the content of the label. SchematicsWidget will provide a reference to a node and label content can be customized for each node. SchematicsWidget expects the callback function to return a string.
import { obfuscate } from "@int/geotoolkit/lib.js";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { WellBoreData } from "@int/geotoolkit/schematics/data/WellBoreData.ts";
import { CompositeSchematicsWidget } from "@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts";
import { Alignment } from "@int/geotoolkit/layout/BoxLayout.ts";
import { Patterns } from "@int/geotoolkit/attributes/LineStyle.ts";
import { AlignmentType } from "@int/geotoolkit/schematics/labeling/AlignmentType.ts";
import { LocationType } from "@int/geotoolkit/schematics/labeling/LocationType.ts";
import { LineConnector } from "@int/geotoolkit/schematics/labeling/LineConnector.ts";
import { LabelsFilter } from "@int/geotoolkit/schematics/labeling/LabelsFilter.ts";
import { ComponentUtils } from "@int/geotoolkit/schematics/utils/ComponentUtils.ts";
import data from "/src/assets/data/wellBoreData.json?import";
export class CustomLabelsFilter extends LabelsFilter {
constructor() {
super();
}
labelInfo(node) {
if (node.getName() === "perforation") {
const geom = node.getGeometryData();
return "perforation, MD:<br/>[" + ComponentUtils.getDepthFrom(geom) + " ; " + ComponentUtils.getDepthTo(geom) + "]";
}
return ComponentUtils.getDescriptionString(node.getDescription()) || node.getName();
}
}
obfuscate(CustomLabelsFilter);
function createScene(canvas) {
function createWellBoreData() {
return new WellBoreData(data);
}
const labelingOptions = {
"locationMap": [{
"location": LocationType.Left,
"component": ["casing", "cement", "perforation"]
}],
"defaultLocation": LocationType.Right,
"defaultAlignment": AlignmentType.Outer,
"connectorShape": new LineConnector().setLineStyle({
"pattern": Patterns.ShortDash
}),
"labelsfilter": new CustomLabelsFilter()
};
const options = {
"alignment": Alignment.Center,
"gap": {
"left": {
"size": "50"
},
"right": {
"size": "50"
},
"top": {
"size": "0"
},
"bottom": {
"size": "0"
}
},
"annotationssizes": {
"south": 0
},
"labeling": labelingOptions,
"data": {
"elements": createWellBoreData()
}
};
return new Plot({
"canvaselement": canvas,
"root": new CompositeSchematicsWidget(options)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# "Adjacent" Mode
Unlike "docked" mode, "adjacent" mode places labels next to the components in the wellbore rather than aligned to a particular side away from the wellbore. To reduce clutter, this example also demonstrates the SchematicsWidget's legend. Enabling the legend replaces label text with indexing and creates a legend that matches the indexes with legend text provided through a callback function.
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { WellBoreData } from "@int/geotoolkit/schematics/data/WellBoreData.ts";
import { CompositeSchematicsWidget } from "@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts";
import { SymbolLabelShape } from "@int/geotoolkit/schematics/labeling/SymbolLabelShape.ts";
import { XYLabelingStrategy } from "@int/geotoolkit/schematics/labeling/XYLabelingStrategy.ts";
import { AnnotationLocation } from "@int/geotoolkit/layout/AnnotationLocation.ts";
import { LocationType } from "@int/geotoolkit/schematics/labeling/LocationType.ts";
import { ComponentUtils } from "@int/geotoolkit/schematics/utils/ComponentUtils.ts";
import { CirclePainter } from "@int/geotoolkit/scene/shapes/painters/CirclePainter.ts";
import data from "/src/assets/data/wellBoreData.json?import";
function createScene(canvas) {
function createWellBoreData() {
return new WellBoreData(data);
}
const locationMap = [{
"location": LocationType.Left,
"component": ["casing", "cement", "perforation"]
}];
const options = {
"labelingStrategy": new XYLabelingStrategy({ "locationmap": locationMap }),
"legendalignmentarea": AnnotationLocation.Center,
"legend": {
"width": 200,
"height": 420,
"visible": true,
"legenditem": {
"gettext": (node) => {
if (node.getName() === "tubing") {
const geom = node.getGeometryData();
return "tubing, MD: [" + ComponentUtils.getDepthFrom(geom) + " ; " + ComponentUtils.getDepthTo(geom) + "]";
}
return ComponentUtils.getDescriptionString(node.getDescription()) || node.getName();
}
}
}
};
return new Plot({
"canvaselement": canvas,
"root": new CompositeSchematicsWidget({
"data": {
"elements": createWellBoreData()
},
"annotationssizes": {
"south": 0
},
"gap": {
"left": {
"size": "20"
},
"right": {
"size": "30"
},
"top": {
"size": "0"
},
"bottom": {
"size": "0"
}
},
"labeling": {
"legendmode": true,
"labelshape": new SymbolLabelShape({
"painter": CirclePainter
}),
"connectorshape": null
}
}).setOptions(options)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));