This tutorial demonstrates how to create a Navigation view for WellLog widget. The navigation tool (geotoolkit/welllog/widgets/tools/Navigation) is added to the WellLog Widget to create a Navigation widget. Both widgets are created separately and added to one canvas. If these widgets are located in different plots, the scale can be synchronized in a manner similar to plot synchronization.
# WellLog Widget Initialization
The following code shows how to initialize WellLog widget tools. See the WellLog Widget tutorial.
The following code shows how to initialize the Navigation Tools
In the example below, the Navigation widget is displayed on the left. Adding a listener to the WellLog widget will allow the widget to change display on curve selection. Similarly, attaching listenings will allow for WellLog widget visible limits to be updated in real-time in accord with changing visible model limits in the Navigation widget.
import { ColorUtil, KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
import { MathUtil } from "@int/geotoolkit/util/MathUtil.ts";
import { LogData } from "@int/geotoolkit/welllog/data/LogData.ts";
import { LogCurve } from "@int/geotoolkit/welllog/LogCurve.ts";
import { AdaptiveLogCurveVisualHeader, Elements } from "@int/geotoolkit/welllog/header/AdaptiveLogCurveVisualHeader.ts";
import { TrackType as WellLogTrackType } from "@int/geotoolkit/welllog/TrackType.ts";
import { Events as WellLogEvents } from "@int/geotoolkit/welllog/widgets/Events.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { from } from "@int/geotoolkit/selection/from.ts";
import { Events as SelectionEvents } from "@int/geotoolkit/controls/tools/Selection.ts";
import { Axis } from "@int/geotoolkit/axis/Axis.ts";
import { Events as NavigationEvents, Navigation } from "@int/geotoolkit/welllog/widgets/tools/Navigation.ts";
import { Sections } from "@int/geotoolkit/welllog/header/AdaptiveLogVisualHeader.ts";
import { curveData } from "/src/code/WellLog/utils/curveData.ts";
import { createWellLogWidget } from "/src/code/WellLog/utils/common.ts";
import { HorizontalBoxLayout } from "@int/geotoolkit/layout/HorizontalBoxLayout.ts";
function createTestData(from2, step, curveMnemonic) {
const depths = [];
const values = [];
const curveDat = curveData[curveMnemonic];
const amountOfPoints = curveDat.length;
for (let i = 0; i < amountOfPoints; i++) {
depths.push(i * step + from2);
values.push(curveDat[i]);
}
return new LogData({
"name": curveMnemonic,
"depths": depths,
"values": values
});
}
function createCurve(dataSource, color) {
const limits = MathUtil.calculateNeatLimits(dataSource.getMinValue(), dataSource.getMaxValue(), false, false);
return new LogCurve(dataSource).setLineStyle(ColorUtil.parseColor(color)).setNormalizationLimits(limits.getLow(), limits.getHigh());
}
class NavigationView {
constructor() {
this._wellLogWidget = null;
this._navigationWidget = null;
this._dataSources = {
"GR": createTestData(4500, 10, "GR"),
"CALI": createTestData(4500, 10, "CALI"),
"SP": createTestData(4500, 10, "SP")
};
}
initializeWellLog() {
const widget = createWellLogWidget({
"indent": 2
}).setDepthLimits(this._dataSources["GR"].getMinDepth(), this._dataSources["GR"].getMaxDepth());
widget.getHeaderContainer().getHeaderProvider().registerHeaderProvider(
LogCurve.getClassName(),
new AdaptiveLogCurveVisualHeader().setElement([Elements.ScaleFrom, Elements.ScaleTo], { "section": Sections.Top }).setElement(Elements.Tracking, { "section": Sections.Top })
);
widget.addTrack(WellLogTrackType.LinearTrack).addChild([createCurve(this._dataSources["GR"], KnownColors.Green)]);
widget.addTrack(WellLogTrackType.LinearTrack).addChild([createCurve(this._dataSources["CALI"], KnownColors.Orange)]);
widget.addTrack(WellLogTrackType.LinearTrack).addChild([createCurve(this._dataSources["SP"], KnownColors.Blue)]);
widget.addTrack(WellLogTrackType.IndexTrack).setWidth(35);
widget.setHeaderHeight("auto");
widget.getToolByName("splitter").setEnabled(false);
widget.getToolByName("pick").on(SelectionEvents.onSelectionChanged, (evt, sender, eventArgs) => {
eventArgs.getSelection().forEach((selection) => {
if (selection instanceof LogCurve) {
from(this._navigationWidget).where((node) => node instanceof LogCurve).select((curve) => {
curve.setLineStyle(selection.getLineStyle()).setData(selection.getDataSource(), true, true);
});
}
});
});
return widget;
}
initializeNavigation() {
const widget = createWellLogWidget({
"horizontalscrollable": false,
"verticalscrollable": false,
"header": {
"visible": false
},
"border": { "visible": true }
}).setDepthLimits(this._dataSources["GR"].getMinDepth(), this._dataSources["GR"].getMaxDepth());
widget.addTrack(WellLogTrackType.IndexTrack).setWidth(40);
from(widget).where((node) => node instanceof Axis).selectFirst().setLabelPadding(4);
widget.addTrack(WellLogTrackType.LinearTrack).addChild([createCurve(this._dataSources["GR"], KnownColors.Green)]).setWidth(100);
widget.getToolByName("pick").setEnabled(false);
widget.getToolByName("splitter").setEnabled(false);
widget.getToolByName("cross-hair").setEnabled(false);
widget.getToolByName("TrackPanning").setEnabled(false);
return widget;
}
initializeNavigationTools() {
const manipulatorLayer = this._navigationWidget.getToolByName("cross-hair").getManipulatorLayer();
const navigationTool = new Navigation(manipulatorLayer).on(NavigationEvents.DepthRangeChanged, (evt, sender, eventArgs) => {
this._wellLogWidget.setVisibleDepthLimits(eventArgs.getLimits());
});
navigationTool.setVisibleDepthLimits(this._wellLogWidget.getVisibleDepthLimits());
const setVisibleDepthLimits = function() {
navigationTool.setVisibleDepthLimits(this._wellLogWidget.getVisibleDepthLimits());
}.bind(this);
this._wellLogWidget.on(WellLogEvents.DepthRangeChanged, setVisibleDepthLimits);
this._wellLogWidget.on(WellLogEvents.VisibleDepthLimitsChanged, setVisibleDepthLimits);
return navigationTool;
}
disableRubberBand() {
this._wellLogWidget.getToolByName("rubberband").setEnabled(false);
}
zoomIn() {
this._wellLogWidget.scale(5 / 4);
this.disableRubberBand();
}
zoomOut() {
this._wellLogWidget.scale(4 / 5);
this.disableRubberBand();
}
fitToHeight() {
this._wellLogWidget.fitToHeight();
this.disableRubberBand();
}
rubberBandZoom() {
this._wellLogWidget.getToolByName("rubberband").setEnabled(true);
}
init(canvas) {
this._plot = new Plot({
"canvaselement": canvas,
"root": new Group().setAutoModelLimitsMode(true).setLayout(new HorizontalBoxLayout()).addChild([
this._navigationWidget = this.initializeNavigation().setLayoutStyle({
"width": 140
}).setMarginsStyle({ right: "2px" }),
this._wellLogWidget = this.initializeWellLog().setLineStyle("lightgray").setMarginsStyle({ left: "2px" })
])
});
const gr = this._dataSources["GR"];
const minDepth = gr.getMinDepth();
const maxDepth = gr.getMaxDepth();
this._wellLogWidget.setVisibleDepthLimits(minDepth, minDepth + (maxDepth - minDepth) / 4).fitToWidth();
this._navigationWidget.fitToHeight().getTool().add([
this.initializeNavigationTools()
]);
}
getPlot() {
return this._plot;
}
getWidget() {
return this._wellLogWidget;
}
}
function createScene(canvas) {
const app = new NavigationView();
app.init(canvas);
return app;
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));