This tutorial shows how to create a custom component node implementation derived from the FlippedComponentNode class.
Note that schematics elements derived from the FlippedComponentNode 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)
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.
# 'Perforation' schematic element implementation
An example of a "perforation" schematic element is shown below:
import { ComponentNodeFactoryRegistry } from "@int/geotoolkit/schematics/factory/ComponentNodeFactoryRegistry.ts";
import { MyFlippedComponentNode } from "/src/code/Schematics/CustomFlippedComponentNode/myFlippedComponentNode.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";
const createScene = (canvas) => {
const componentName = "MyFlippedComponent";
const factoryRegistry = new ComponentNodeFactoryRegistry();
factoryRegistry.setFactory(componentName, () => new MyFlippedComponentNode());
const wellBoreData = new WellBoreData();
const options = {
"description": componentName,
"geometry": {
"depth": { "from": 50, "to": 100 },
"diameter": { "outer": 50, "inner": 25 },
"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, FlippedComponentNode lets the user implement a custom component node more efficiently because only the "positive half" of a node's geometry class has to be created; it is reused to render the "negative half" of the shape internally (as well as all other 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: