This tutorial show how to create own simple visual with sinus and circle geometry
To implement a custom visual, perform these steps:
# I. Extend base class. It can be LogAbstractVisual
# Implement rendering method
Implement .renderContent() - the method determines what to draw
# Set up model limits
Override .getModelLimits() if need. By default visual has track's model limits
# Set up serialization
Override .setProperties() and .getProperties() if serialisation is needed
# Provide data
Add data setting via .setData() or constructor. Name and type can vary, it's up to the author.
# II. Adding own tooltip
To add custom tooltip, perform these steps:
# Handle selection in visual
In .renderContent() implement selection
# Add hit test to visual
Add method .hitTest() which creates Selector
# Create new class for Tooltip
Create own tooltip extending NodeTooltip, it should call .hitTest() to get the data
# Register tooltip
Create ToolTipTool instance and register there custom tooltip
# III. Adding own header
To add custom tooltip, perform these steps:
# Create new class for header
Extend new class from LogVisualHeader, implement render() and clone() methods
# Register header
Add custom header to LogVisualHeaderProvider - existing one or new one
# Full example
import { TrackType } from "@int/geotoolkit/welllog/TrackType.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { createWellLogWidget } from "/src/code/WellLog/utils/common.ts";
import { SineVisual } from "/src/code/WellLog/Visuals/CustomVisual/SineVisual.ts";
import { FillStyle } from "@int/geotoolkit/attributes/FillStyle.ts";
import { LineStyle } from "@int/geotoolkit/attributes/LineStyle.ts";
import { LogVisualHeaderProvider } from "@int/geotoolkit/welllog/header/LogVisualHeaderProvider.ts";
import { SineVisualHeader } from "/src/code/WellLog/Visuals/CustomVisual/SineVisualHeader.ts";
import { SineVisualTooltip } from "/src/code/WellLog/Visuals/CustomVisual/SineVisualTooltip.ts";
import { ToolTipTool } from "@int/geotoolkit/controls/tools/ToolTipTool.ts";
import { ToolTipRegistry } from "@int/geotoolkit/controls/tooltip/ToolTipRegistry.ts";
import { DisplayType as HeaderContainerDisplayType } from "@int/geotoolkit/welllog/HeaderContainer.ts";
const COLORS = ["darkgreen", "red", "black", "yellow"];
let i = 0;
const getNextColor = () => COLORS[i++ % COLORS.length];
const lineStyle = new LineStyle({
"color": getNextColor(),
"width": 3
});
const fillStyle = new FillStyle(getNextColor());
function createSinusoidVisual(data) {
return new SineVisual(data).setLineStyle(lineStyle).setFillStyle(fillStyle);
}
let logSinusoid;
let widget;
function createScene(canvas) {
widget = createWellLogWidget().setDepthLimits(1704, 1716);
widget.addTrack(TrackType.IndexTrack);
logSinusoid = createSinusoidVisual({
depth: 1710,
angle: Math.PI / 6
});
const headerProvider = LogVisualHeaderProvider.getDefaultInstance().clone();
headerProvider.registerHeaderProvider(SineVisual.getClassName(), new SineVisualHeader(logSinusoid));
widget.getHeaderContainer().setHeaderProvider(headerProvider);
widget.connectTool(
new ToolTipTool({
"layer": widget,
"registry": new ToolTipRegistry().register(SineVisual.getClassName(), new SineVisualTooltip("Depth: ${depth} <br/> Angle: ${angle}℃"))
})
);
widget.addTrack(TrackType.LinearTrack).setWidth(400).addChild(logSinusoid);
widget.setHeaderHeight("auto");
const plot = new Plot({
"canvaselement": canvas,
"root": widget
});
widget.fitToHeight();
return plot;
}
function changeStyles() {
lineStyle.setColor(getNextColor());
fillStyle.setColor(getNextColor());
}
function changeMicropositions() {
if (logSinusoid.getMicroPositionLeft() === 0)
logSinusoid.setMicroPosition(0.2, 1);
else
logSinusoid.setMicroPosition(0, 1);
}
function addFooter() {
widget.setProperties({
"footer": {
"visible": true,
"displaytype": HeaderContainerDisplayType.Minimized,
"margin": 2,
"padding": 4,
"height": 50
}
});
widget.getFooterContainer().getHeaderProvider().registerHeaderProvider(SineVisual.getClassName(), new SineVisualHeader(logSinusoid));
widget.getFooterContainer().rebuild();
}
function toggleFooter() {
const isVisible = widget.getProperties()["footer"]["visible"];
if (isVisible === "none")
addFooter();
else
widget.setProperties({ "footer": { "visible": !isVisible } });
}
export { changeMicropositions, changeStyles, createScene, toggleFooter };
createScene(document.querySelector('[ref="plot"]'));