In this tutorial, create a log discrete curve and set its attributes. "Discrete" means that the input data is a set of independent discrete values like codes. These discrete values are obtained after interpolation. A discrete curve associates these values and depths with colors or patterns. The FillType enum from geotoolkit/welllog/LogDiscreteCurve decides the type of fill used.
For more information about curve fills, see the Curve Fill tutorial.
# Color Provider Fill
This example uses the DiscreteGradientColorProvider as a fill type to set a gradient fill.
.cg-tooltip-holder {
position: relative;
}
.cg-tooltip {
position: absolute;
display: block;
padding: 2px 12px 3px 7px;
overflow: visible !important;
font-family: Roboto, Helvetica, Arial, sans-serif;
font-size: 13px;
background: white !important;
opacity: 0.9;
color: #333333;
border: solid 1px gray;
border-radius: 5px;
text-align: left;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
border-radius: 5px;
margin: 0 !important;
z-index: 10000;
max-width: 400px;
text-wrap: normal !important;
white-space: normal !important;
}
/* Default setting for tooltip */
.cg-tooltip-container {
position: absolute;
display: block;
overflow: visible !important;
font-family: Roboto, Helvetica, Arial, sans-serif;
font-size: 12px;
padding: 3px 7px;
background: #f7f7f7;
color: #333333;
border: 1px solid #938e8e;
opacity: 0.8;
text-align: left;
box-shadow: 3px 3px 10px #888;
margin: 0 !important;
z-index: 10000;
max-width: 400px;
text-wrap: normal !important;
white-space: normal !important;
user-select: none;
}
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.cg-tooltip-container {
border-radius: 0;
}
}
/* Default left arrow for tooltip */
.cg-tooltip-arrow-left::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 0;
top: 50%;
border: 5px solid transparent;
border-left: 0;
border-right: 5px solid #938e8e;
transform: translate(calc(-100%), -50%);
}
.cg-tooltip-arrow-left::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 0;
top: 50%;
border: 4px solid transparent;
border-left: 0;
border-right: 4px solid #f7f7f7;
transform: translate(calc(-100%), -50%);
}
/* Default top arrow for tooltip */
.cg-tooltip-arrow-top::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
top: 0;
border: 5px solid transparent;
border-top: 0;
border-bottom: 5px solid #938e8e;
transform: translate(-50%, -100%);
}
.cg-tooltip-arrow-top::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
top: 0;
border: 4px solid transparent;
border-top: 0;
border-bottom: 4px solid #f7f7f7;
transform: translate(-50%, -100%);
}
/* Default right arrow for tooltip */
.cg-tooltip-arrow-right::before {
content: '';
position: absolute;
display: block;
width: 0px;
right: 0;
top: 50%;
border: 5px solid transparent;
border-right: 0;
border-left: 5px solid #938e8e;
transform: translate(100%, -50%);
}
.cg-tooltip-arrow-right::after {
content: '';
position: absolute;
display: block;
width: 0px;
right: 0;
top: 50%;
border: 4px solid transparent;
border-right: 0;
border-left: 4px solid #f7f7f7;
transform: translate(100%, -50%);
}
/* Default bottom arrow for tooltip */
.cg-tooltip-arrow-bottom::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
bottom: 0px;
border: 5px solid transparent;
border-bottom: 0;
border-top: 5px solid #938e8e;
transform: translate(-50%, 100%);
z-index: 10000;
}
.cg-tooltip-arrow-bottom::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
bottom: 0;
border: 4px solid transparent;
border-bottom: 0;
border-top: 4px solid #f7f7f7;
transform: translate(-50%, 100%);
z-index: 10000;
}
/* Tooltip item name */
/* Tooltip item value */
/* .cg-tooltip-item-value */
/* Tooltip item value */
.cg-tooltip-item-unit {
text-transform: none;
}
.cg-tooltip-item-name {
text-transform: capitalize;
white-space: nowrap;
vertical-align: middle;
font-size: 13px;
}
.cg-tooltip-row {
display: flex;
flex-direction: row;
align-items: center;
white-space: pre-wrap;
font-size: 12px;
line-height: 100%;
margin: 1px 0;
}
.cg-tooltip-title {
font-size: 13px;
height: 14px;
text-transform: capitalize;
}
.cg-tooltip-title .cg-tooltip-symbol {
margin-right: 0 !important;
}
.cg-tooltip-title-name {
vertical-align: middle;
}
.cg-tooltip-row + .cg-tooltip-row {
margin-top: 4px;
}
.cg-tooltip-row.cg-tooltip-title + .cg-tooltip-row {
margin-top: 5px;
}
.cg-tooltip-item-value + .cg-tooltip-item-unit {
margin-left: 1px;
}
/* Tooltip symbol */
.cg-tooltip-symbol-cell {
display: inline-flex;
min-width: 13px; /* 10px size + 3px margin */
}
.cg-tooltip-symbol {
margin-right: 3px;
background-color: transparent;
display: block;
}
.cg-tooltip-symbol > img {
display: block;
}
.cg-tooltip-list-cell {
display: inline-flex;
}
.cg-tooltip-list-symbol {
display: block;
margin-right: 3px;
width: 6px;
height: 6px;
vertical-align: middle;
border-radius: 50%;
border: 1px solid rgba(0,0,0,.4);
}
.cg-tooltip-symbol-legacy {
border-radius: 4px;
margin-right: 5px;
height: 8px;
width: 8px;
display: inline-block;
}
.cg-tooltip-title-legacy {
font-weight: 900;
}
/* Tooltip symbol circle */
.cg-tooltip-symbol.circle {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 50%;
border: 1px solid rgba(0,0,0,.4);
}
/* Tooltip symbol line */
.cg-tooltip-symbol.line {
height: 10px;
width: 10px;
display: inline-block;
transform: scale(1.2, 0.2);
}
/* Tooltip symbol diamond */
.cg-tooltip-symbol.diamond {
height: 10px;
width: 10px;
display: inline-block;
transform: rotate(45deg);
border-radius: 0px;
}
/* Tooltip symbol square */
.cg-tooltip-symbol.square {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 0px;
border: 1px solid rgba(0,0,0,.4);
}
# Discrete Fill
This example uses the 'discrete' FillType and assigns patterns for each section based on the code value. Each code has an associated name and a fill style along with the color provider.
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { FillType, LogDiscreteCurve } from "@int/geotoolkit/welllog/LogDiscreteCurve.ts";
import { TrackType } from "@int/geotoolkit/welllog/TrackType.ts";
import { LogData } from "@int/geotoolkit/welllog/data/LogData.ts";
import { createPatternFill } from "/src/code/WellLog/Visuals/DiscreteCurve/util.ts";
import { loadResources } from "/src/helpers/resources.ts";
import { createWellLogWidget } from "/src/code/WellLog/utils/common.ts";
loadResources("patterns");
function generateData() {
const data = [0, 2, 5, 28, 26, 30, 15, 12, 10, 7, 19, 21, 22, 8, 11, 25, 27, 10, 3, 5];
const minData = 0, maxData = 30;
const minDepth = 100, maxDepth = 500;
const minValue = 1, maxValue = 7;
return new LogData({
"name": "CALI",
"values": data.map((val) => minValue + Math.floor((maxValue - minValue) * val / (maxData - minData))),
"depths": data.map((val, i) => minDepth + (maxDepth - minDepth) * i / (data.length - 1))
});
}
function createScene(canvas) {
const widget = createWellLogWidget({
"tools": {
"crosshair": {
"enabled": false
}
}
}).setDepthLimits(100, 500);
widget.addTrack(TrackType.IndexTrack);
const datasource = generateData();
const discreteCurve = new LogDiscreteCurve(datasource).setFillInfo({
"type": FillType.Discrete,
"codes": [1, 2, 3, 4, 5, 6, 7],
"names": ["Chert", "Breccia", "Limestone", "Limestone2", "Shale", "Shale2", "Salt"],
"fillstyles": [
createPatternFill("#dcedc8", "chert"),
createPatternFill("#7cb342", "chert"),
createPatternFill("#fdd835", "lime"),
createPatternFill("#fff9c4", "lime"),
createPatternFill("#ef6c00", "shale"),
createPatternFill("#e64a19", "shale"),
createPatternFill("#2196f3", "salt")
]
}).setTextStyle({
"color": "#212121",
"font": "bold 12px Arial"
}).setVisibleText(true);
widget.addTrack(TrackType.LinearTrack).setWidth(300).addChild(discreteCurve);
widget.addTrack(TrackType.IndexTrack);
widget.setHeaderHeight("auto");
return new Plot({
"canvaselement": canvas,
"root": widget
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Continuous Fill
This example uses the 'continuous' FillType and assigns patterns for each section based on a range of values provided.
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { FillType, LogDiscreteCurve } from "@int/geotoolkit/welllog/LogDiscreteCurve.ts";
import { TrackType } from "@int/geotoolkit/welllog/TrackType.ts";
import { LogData } from "@int/geotoolkit/welllog/data/LogData.ts";
import { createPatternFill } from "/src/code/WellLog/Visuals/DiscreteCurve/util.ts";
import { createWellLogWidget } from "/src/code/WellLog/utils/common.ts";
import { loadResources } from "/src/helpers/resources.ts";
loadResources("patterns");
function generateData() {
const data = [0, 2, 5, 28, 26, 30, 15, 12, 10, 7, 19, 21, 22, 8, 11, 25, 27, 10, 3, 5];
const minData = 0, maxData = 30;
const minDepth = 100, maxDepth = 500;
const minValue = 1, maxValue = 7;
return new LogData({
"name": "CALI",
"values": data.map((val) => minValue + (maxValue - minValue) * val / (maxData - minData)),
"depths": data.map((val, i) => minDepth + (maxDepth - minDepth) * i / (data.length - 1))
});
}
function createScene(canvas) {
const widget = createWellLogWidget({
"tools": {
"crosshair": {
"enabled": false
}
}
}).setDepthLimits(100, 500);
widget.addTrack(TrackType.IndexTrack);
const datasource = generateData();
const discreteCurve = new LogDiscreteCurve(datasource, true).setFillInfo({
"type": FillType.Continuous,
"ranges": [
[1, 3],
[3, 5],
[5, 7],
[7, 8]
],
"names": ["Chert", "Limestone", "Shale", "Salt"],
"fillstyles": [
createPatternFill("#7cb342", "chert"),
createPatternFill("#fdd835", "lime"),
createPatternFill("#ef6c00", "shale"),
createPatternFill("#2196f3", "salt")
]
}).setTextStyle({
"color": "#212121",
"font": "bold 12px Arial"
}).setVisibleText(true);
widget.addTrack(TrackType.LinearTrack).setWidth(300).addChild(discreteCurve);
widget.addTrack(TrackType.IndexTrack);
widget.setHeaderHeight("auto");
return new Plot({
"canvaselement": canvas,
"root": widget
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Vertical Text Orientation
This example uses vertical text orientation.
.cg-tooltip-holder {
position: relative;
}
.cg-tooltip {
position: absolute;
display: block;
padding: 2px 12px 3px 7px;
overflow: visible !important;
font-family: Roboto, Helvetica, Arial, sans-serif;
font-size: 13px;
background: white !important;
opacity: 0.9;
color: #333333;
border: solid 1px gray;
border-radius: 5px;
text-align: left;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
border-radius: 5px;
margin: 0 !important;
z-index: 10000;
max-width: 400px;
text-wrap: normal !important;
white-space: normal !important;
}
/* Default setting for tooltip */
.cg-tooltip-container {
position: absolute;
display: block;
overflow: visible !important;
font-family: Roboto, Helvetica, Arial, sans-serif;
font-size: 12px;
padding: 3px 7px;
background: #f7f7f7;
color: #333333;
border: 1px solid #938e8e;
opacity: 0.8;
text-align: left;
box-shadow: 3px 3px 10px #888;
margin: 0 !important;
z-index: 10000;
max-width: 400px;
text-wrap: normal !important;
white-space: normal !important;
user-select: none;
}
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.cg-tooltip-container {
border-radius: 0;
}
}
/* Default left arrow for tooltip */
.cg-tooltip-arrow-left::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 0;
top: 50%;
border: 5px solid transparent;
border-left: 0;
border-right: 5px solid #938e8e;
transform: translate(calc(-100%), -50%);
}
.cg-tooltip-arrow-left::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 0;
top: 50%;
border: 4px solid transparent;
border-left: 0;
border-right: 4px solid #f7f7f7;
transform: translate(calc(-100%), -50%);
}
/* Default top arrow for tooltip */
.cg-tooltip-arrow-top::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
top: 0;
border: 5px solid transparent;
border-top: 0;
border-bottom: 5px solid #938e8e;
transform: translate(-50%, -100%);
}
.cg-tooltip-arrow-top::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
top: 0;
border: 4px solid transparent;
border-top: 0;
border-bottom: 4px solid #f7f7f7;
transform: translate(-50%, -100%);
}
/* Default right arrow for tooltip */
.cg-tooltip-arrow-right::before {
content: '';
position: absolute;
display: block;
width: 0px;
right: 0;
top: 50%;
border: 5px solid transparent;
border-right: 0;
border-left: 5px solid #938e8e;
transform: translate(100%, -50%);
}
.cg-tooltip-arrow-right::after {
content: '';
position: absolute;
display: block;
width: 0px;
right: 0;
top: 50%;
border: 4px solid transparent;
border-right: 0;
border-left: 4px solid #f7f7f7;
transform: translate(100%, -50%);
}
/* Default bottom arrow for tooltip */
.cg-tooltip-arrow-bottom::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
bottom: 0px;
border: 5px solid transparent;
border-bottom: 0;
border-top: 5px solid #938e8e;
transform: translate(-50%, 100%);
z-index: 10000;
}
.cg-tooltip-arrow-bottom::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
bottom: 0;
border: 4px solid transparent;
border-bottom: 0;
border-top: 4px solid #f7f7f7;
transform: translate(-50%, 100%);
z-index: 10000;
}
/* Tooltip item name */
/* Tooltip item value */
/* .cg-tooltip-item-value */
/* Tooltip item value */
.cg-tooltip-item-unit {
text-transform: none;
}
.cg-tooltip-item-name {
text-transform: capitalize;
white-space: nowrap;
vertical-align: middle;
font-size: 13px;
}
.cg-tooltip-row {
display: flex;
flex-direction: row;
align-items: center;
white-space: pre-wrap;
font-size: 12px;
line-height: 100%;
margin: 1px 0;
}
.cg-tooltip-title {
font-size: 13px;
height: 14px;
text-transform: capitalize;
}
.cg-tooltip-title .cg-tooltip-symbol {
margin-right: 0 !important;
}
.cg-tooltip-title-name {
vertical-align: middle;
}
.cg-tooltip-row + .cg-tooltip-row {
margin-top: 4px;
}
.cg-tooltip-row.cg-tooltip-title + .cg-tooltip-row {
margin-top: 5px;
}
.cg-tooltip-item-value + .cg-tooltip-item-unit {
margin-left: 1px;
}
/* Tooltip symbol */
.cg-tooltip-symbol-cell {
display: inline-flex;
min-width: 13px; /* 10px size + 3px margin */
}
.cg-tooltip-symbol {
margin-right: 3px;
background-color: transparent;
display: block;
}
.cg-tooltip-symbol > img {
display: block;
}
.cg-tooltip-list-cell {
display: inline-flex;
}
.cg-tooltip-list-symbol {
display: block;
margin-right: 3px;
width: 6px;
height: 6px;
vertical-align: middle;
border-radius: 50%;
border: 1px solid rgba(0,0,0,.4);
}
.cg-tooltip-symbol-legacy {
border-radius: 4px;
margin-right: 5px;
height: 8px;
width: 8px;
display: inline-block;
}
.cg-tooltip-title-legacy {
font-weight: 900;
}
/* Tooltip symbol circle */
.cg-tooltip-symbol.circle {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 50%;
border: 1px solid rgba(0,0,0,.4);
}
/* Tooltip symbol line */
.cg-tooltip-symbol.line {
height: 10px;
width: 10px;
display: inline-block;
transform: scale(1.2, 0.2);
}
/* Tooltip symbol diamond */
.cg-tooltip-symbol.diamond {
height: 10px;
width: 10px;
display: inline-block;
transform: rotate(45deg);
border-radius: 0px;
}
/* Tooltip symbol square */
.cg-tooltip-symbol.square {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 0px;
border: 1px solid rgba(0,0,0,.4);
}
# Horizontal Widget
This example uses horizontal widget and horizontal text orientation.
.cg-tooltip-holder {
position: relative;
}
.cg-tooltip {
position: absolute;
display: block;
padding: 2px 12px 3px 7px;
overflow: visible !important;
font-family: Roboto, Helvetica, Arial, sans-serif;
font-size: 13px;
background: white !important;
opacity: 0.9;
color: #333333;
border: solid 1px gray;
border-radius: 5px;
text-align: left;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
border-radius: 5px;
margin: 0 !important;
z-index: 10000;
max-width: 400px;
text-wrap: normal !important;
white-space: normal !important;
}
/* Default setting for tooltip */
.cg-tooltip-container {
position: absolute;
display: block;
overflow: visible !important;
font-family: Roboto, Helvetica, Arial, sans-serif;
font-size: 12px;
padding: 3px 7px;
background: #f7f7f7;
color: #333333;
border: 1px solid #938e8e;
opacity: 0.8;
text-align: left;
box-shadow: 3px 3px 10px #888;
margin: 0 !important;
z-index: 10000;
max-width: 400px;
text-wrap: normal !important;
white-space: normal !important;
user-select: none;
}
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.cg-tooltip-container {
border-radius: 0;
}
}
/* Default left arrow for tooltip */
.cg-tooltip-arrow-left::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 0;
top: 50%;
border: 5px solid transparent;
border-left: 0;
border-right: 5px solid #938e8e;
transform: translate(calc(-100%), -50%);
}
.cg-tooltip-arrow-left::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 0;
top: 50%;
border: 4px solid transparent;
border-left: 0;
border-right: 4px solid #f7f7f7;
transform: translate(calc(-100%), -50%);
}
/* Default top arrow for tooltip */
.cg-tooltip-arrow-top::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
top: 0;
border: 5px solid transparent;
border-top: 0;
border-bottom: 5px solid #938e8e;
transform: translate(-50%, -100%);
}
.cg-tooltip-arrow-top::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
top: 0;
border: 4px solid transparent;
border-top: 0;
border-bottom: 4px solid #f7f7f7;
transform: translate(-50%, -100%);
}
/* Default right arrow for tooltip */
.cg-tooltip-arrow-right::before {
content: '';
position: absolute;
display: block;
width: 0px;
right: 0;
top: 50%;
border: 5px solid transparent;
border-right: 0;
border-left: 5px solid #938e8e;
transform: translate(100%, -50%);
}
.cg-tooltip-arrow-right::after {
content: '';
position: absolute;
display: block;
width: 0px;
right: 0;
top: 50%;
border: 4px solid transparent;
border-right: 0;
border-left: 4px solid #f7f7f7;
transform: translate(100%, -50%);
}
/* Default bottom arrow for tooltip */
.cg-tooltip-arrow-bottom::before {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
bottom: 0px;
border: 5px solid transparent;
border-bottom: 0;
border-top: 5px solid #938e8e;
transform: translate(-50%, 100%);
z-index: 10000;
}
.cg-tooltip-arrow-bottom::after {
content: '';
position: absolute;
display: block;
width: 0px;
left: 50%;
bottom: 0;
border: 4px solid transparent;
border-bottom: 0;
border-top: 4px solid #f7f7f7;
transform: translate(-50%, 100%);
z-index: 10000;
}
/* Tooltip item name */
/* Tooltip item value */
/* .cg-tooltip-item-value */
/* Tooltip item value */
.cg-tooltip-item-unit {
text-transform: none;
}
.cg-tooltip-item-name {
text-transform: capitalize;
white-space: nowrap;
vertical-align: middle;
font-size: 13px;
}
.cg-tooltip-row {
display: flex;
flex-direction: row;
align-items: center;
white-space: pre-wrap;
font-size: 12px;
line-height: 100%;
margin: 1px 0;
}
.cg-tooltip-title {
font-size: 13px;
height: 14px;
text-transform: capitalize;
}
.cg-tooltip-title .cg-tooltip-symbol {
margin-right: 0 !important;
}
.cg-tooltip-title-name {
vertical-align: middle;
}
.cg-tooltip-row + .cg-tooltip-row {
margin-top: 4px;
}
.cg-tooltip-row.cg-tooltip-title + .cg-tooltip-row {
margin-top: 5px;
}
.cg-tooltip-item-value + .cg-tooltip-item-unit {
margin-left: 1px;
}
/* Tooltip symbol */
.cg-tooltip-symbol-cell {
display: inline-flex;
min-width: 13px; /* 10px size + 3px margin */
}
.cg-tooltip-symbol {
margin-right: 3px;
background-color: transparent;
display: block;
}
.cg-tooltip-symbol > img {
display: block;
}
.cg-tooltip-list-cell {
display: inline-flex;
}
.cg-tooltip-list-symbol {
display: block;
margin-right: 3px;
width: 6px;
height: 6px;
vertical-align: middle;
border-radius: 50%;
border: 1px solid rgba(0,0,0,.4);
}
.cg-tooltip-symbol-legacy {
border-radius: 4px;
margin-right: 5px;
height: 8px;
width: 8px;
display: inline-block;
}
.cg-tooltip-title-legacy {
font-weight: 900;
}
/* Tooltip symbol circle */
.cg-tooltip-symbol.circle {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 50%;
border: 1px solid rgba(0,0,0,.4);
}
/* Tooltip symbol line */
.cg-tooltip-symbol.line {
height: 10px;
width: 10px;
display: inline-block;
transform: scale(1.2, 0.2);
}
/* Tooltip symbol diamond */
.cg-tooltip-symbol.diamond {
height: 10px;
width: 10px;
display: inline-block;
transform: rotate(45deg);
border-radius: 0px;
}
/* Tooltip symbol square */
.cg-tooltip-symbol.square {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 0px;
border: 1px solid rgba(0,0,0,.4);
}