This tutorial shows how to create custom component node implementation derived from the RegularComponentNode class.
Note that schematics elements derived from the RegularComponentNode class accept data specified as follows:
# Options
Optional parameters are:
- 'description' - used for labeling (if not set then the registered component name is used as the default value)
- 'offset' - used to move an element across a wellbore axis (if not set then "0" is used as the default value)
Also, a trivial implementation of AbstractComponentNodeFactory is provided that returns the node's class instance in its createComponentNode method call.
General information on how to register your custom component, add a component's data to a wellbore, and visualize it is represented in the General Information tutorial.
# 'Tubing' Schematic Element Implementation
An example of a "tubing" schematic element is implemented:
import { ComponentNodeFactoryRegistry } from "@int/geotoolkit/schematics/factory/ComponentNodeFactoryRegistry.ts";
import { WellBoreData } from "@int/geotoolkit/schematics/data/WellBoreData.ts";
import { WellBoreNode } from "@int/geotoolkit/schematics/scene/WellBoreNode.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Events } from "@int/geotoolkit/scene/Node.ts";
import { MyRegularComponentNode } from "/src/code/Schematics/CustomRegularComponentNode/myRegularComponentNode.ts";
const createScene = (canvas) => {
const componentName = "MyRegularComponent";
const factoryRegistry = new ComponentNodeFactoryRegistry();
factoryRegistry.setFactory(componentName, () => new MyRegularComponentNode());
const wellBoreData = new WellBoreData();
const options = {
"description": componentName,
"geometry": {
"depth": { "from": 50, "to": 100 },
"diameter": { "outer": 50 },
"offset": 0
}
};
wellBoreData.addComponent(componentName, options);
const wellBoreShape = new WellBoreNode({
"data": wellBoreData,
"registry": factoryRegistry
});
const plotMinY = 0, plotMaxY = 250, plotMinX = 0, plotMaxX = 250;
const plotSizeX = plotMaxX - plotMinX;
const plotSizeY = plotMaxY - plotMinY;
const wellBoreShapeBounds = new Rect(
plotMinX + plotSizeX / 4,
plotMinY,
plotMaxX - plotSizeX / 4,
plotMaxY
);
wellBoreShape.setBounds(wellBoreShapeBounds);
const plot = new Plot({
"canvaselement": canvas,
"root": wellBoreShape
});
wellBoreShape.on(Events.Invalidate, () => plot.update());
return plot.setSize(plotSizeX, plotSizeY);
};
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
Compared to just ComponentNode, RegularComponentNode lets the user implement a custom component node more efficiently because one and only one instance of the node class is created and is re-used to render all nodes of the particular type in well bore data.
Note that unlike straight-forward ComponentNode -based implementation, a re-usable (template) shape's geometry is defined in its own coordinate system – the key is just to report its getTemplateBounds() and getTemplateNode() to SchematicsJS – and the library internally translates the template shape to a proper component geometry:
# Gets template bounds
So, getTemplateBounds() is:
# Gets template node
So, getTemplateNode() is: