Skip to content

Commit

Permalink
async pattern loading, refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
karbor committed May 11, 2023
1 parent 41fd336 commit cc35618
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 99 deletions.
12 changes: 6 additions & 6 deletions react/src/demo/example-data/discrete-facies-test.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,25 @@
[
1400,
2,
2,
1,
0.247
],
[
2179,
2,
1,
2,
0.247
],
[
2180.6093750344276,
2300.0,
3,
3,
2,
0.137
],
[
3541.6093750344276,
3,
3541.6,
3,
4,
0.237
],
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,47 +50,63 @@ export class LithologyTrack extends StackedTrack {
constructor(id: string | number, props: LithologyTrackOptions) {
super(id, props);
this.lithologyInfo = props.lithologyInfoTable as LithologyInfoTable; // TODO - ensure table is given and valid
setupLithologyInfoMap(this.lithologyInfo);
this.patterns = new Map<string | number, CanvasPattern | string>();
this.loadPatterns = this.loadPatterns.bind(this);
}

loadPatterns(): void {
const { data } = this;
if (!data) return;
async loadPatterns():Promise<void> {
return new Promise<void>(resolve => {
const { data } = this;
if (!data) return;
// Find unique canvas code names in data for this track. Later only load images for used codes
const uniqueCodes = [
...new Set(data.map((item: LithologyTrackDataRow) => item.name)),
] as (string | number)[]; // TODO: why doesn't typescript understand this itself?

// Find unique canvas code names in data for this track. Later only load images for used codes
const uniqueCodes = [
...new Set(data.map((item: LithologyTrackDataRow) => item.name)),
] as (string | number)[]; // TODO: why doesn't typescript understand this itself?
setupLithologyInfoMap(this.lithologyInfo);
uniqueCodes.forEach((code) => {
const pattern = lithologyInfoMap.get(code);
// const pattern = patterns.find(pattern => code === pattern.code)
if (pattern?.patternImage) {
// Check if we have loaded pattern
if (!this.patterns.get(code)) {
// Temporarily set solid color while we get image to avoid fetching multiple times
this.patterns.set(code, "#eee");
// Create pattern
const patternImage = new Image();
patternImage.src = pattern.patternImage;
patternImage.onload = () => {
this.patterns.set(
code,
this.ctx?.createPattern(
patternImage,
"repeat"
) as CanvasPattern
);
};
let numUniquePatternsLoading = uniqueCodes.length;
uniqueCodes.forEach((code) => {
const pattern = lithologyInfoMap.get(code);
// const pattern = patterns.find(pattern => code === pattern.code)
if (pattern?.patternImage) {
// Check if we have loaded pattern
if (!this.patterns.get(code)) {
// Temporarily set solid color while we get image to avoid fetching multiple times
this.patterns.set(code, "#eee");
// Create pattern
const patternImage = new Image();
patternImage.src = pattern.patternImage;
patternImage.onload = () => {
this.patterns.set(
code,
this.ctx?.createPattern(
patternImage,
"repeat"
) as CanvasPattern
);
numUniquePatternsLoading -= 1;
// Resolve on last image.
if (numUniquePatternsLoading <= 0) {
this.isLoading = false;
resolve();
}
};
} else {
numUniquePatternsLoading -= 1;
}
} else {
numUniquePatternsLoading -= 1;
}
});
if (numUniquePatternsLoading <= 0) {
this.isLoading = false;
resolve();
}
});
})
}

plot(): void {
super.plot();
const { ctx, scale: yscale, data, patterns } = this;

if (!ctx || !data) return;
const rectangles = scaleData(yscale, data);
const { width: rectWidth, clientWidth, clientHeight } = ctx.canvas;
Expand Down Expand Up @@ -156,7 +172,8 @@ export class LithologyTrack extends StackedTrack {
options.data().then(
(data: LithologyTrackDataRow[]) => {
this.data = data;
this.plot();
// @ts-ignore
this.loadPatterns().then(this.plot());
},
(error: Error | string) => super.onError(error)
);
Expand Down Expand Up @@ -189,8 +206,8 @@ export class LithologyTrack extends StackedTrack {
this.plot();
}
onDataLoaded(): void {
this.loadPatterns();
this.plot();
// @ts-ignore
this.loadPatterns().then(this.plot());
}
}

Expand Down
94 changes: 35 additions & 59 deletions react/src/lib/components/WellLogViewer/utils/tracks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ import { deepCopy } from "./deepcopy";
import { createPlotType } from "@equinor/videx-wellog";
import { defaultPlotFactory } from "@equinor/videx-wellog";
import {
LithologyInfoTable,
LithologyTrack,
LithologyInfoTable,
LithologyTrackOptions,
} from "../components/LithologyTrack";
export function indexOfElementByName(array: Named[], name: string): number {
Expand Down Expand Up @@ -978,6 +978,28 @@ function createAreaData(
};
}

async function createLithologyData(
data: [number | null, number | string | null][]
) {
// Remove possibly null values for depth
const data_no_null_depths = data.filter((elem) => {
return elem[0] !== null;
});
// Setup areas where value used for interval is taken from the first depth (current code has a bug where value is taken from the last depth)
return data_no_null_depths.map((dataRow, index) => {
const value = dataRow[1] == null ? Number.NaN : dataRow[1].toString();
return {
from: dataRow[0],
to:
index < data.length - 1
? data_no_null_depths[index + 1][0]
: dataRow[0],
name: value,
color: { r: 255, g: 25, b: 25 }, // Apparently, this is needed by the mother class in videx, use dummy for now
};
});
}

async function createStackData(
data: [number | null, number | string | null][],
colorTable: ColorTable | undefined,
Expand Down Expand Up @@ -1290,19 +1312,13 @@ function addGraphTrack(
}
}
function addLithologyTrack(
info: TracksInfo,
welllog: WellLog,
name: string,
currentMinMaxPrimaryAxis: [number, number],
curves: WellLogCurve[],
data: WellLogDataRow[],
iPrimaryAxis: number,
templateTrack: TemplateTrack,
templateStyles?: TemplateStyle[],
colorTables?: ColorTable[],
lithologInfoTable?: LithologyInfoTable
): void {
const templatePlot = templateTrack.plots[0];
const name = templatePlot.name;

): LithologyTrack | undefined {
const iCurve = indexOfElementByName(curves, name);
if (iCurve < 0) return; // curve not found
const curve = curves[iCurve];
Expand All @@ -1311,58 +1327,20 @@ function addLithologyTrack(
if (dimensions !== 1) return;

const plotData = preparePlotData(data, iCurve, iPrimaryAxis);
checkMinMax(info.minmaxPrimaryAxis, plotData.minmaxPrimaryAxis);

// make full props
const templatePlotProps = getTemplatePlotProps(
templatePlot,
templateStyles
);
const templateTrackFullPlot: TemplateTrack = deepCopy(templateTrack);

templateTrackFullPlot.title = makeTrackHeader(welllog, templateTrack);
templateTrackFullPlot.plots[0].type = templatePlotProps.type;

// curve.valueType === "integer", "string"
const logColor = templatePlotProps.colorTable;
let colorTable: ColorTable | undefined = undefined;
if (logColor) {
if (colorTables) {
colorTable = colorTables.find(
(colorTable) => colorTable.name == logColor
);
if (!colorTable)
console.error("Missed '" + logColor + "' color table");
} else {
console.error(
"No color tables file given for '" + logColor + "' color table"
);
}
} else {
console.error("No color table given in template plot props");
}
const meta = getDiscreteMeta(welllog, name);
if (!meta && curve.valueType == "integer")
console.log(
"Discrete meta information for '" +
name +
"' not found. Use default"
);

const showLines = true;
checkMinMax(currentMinMaxPrimaryAxis, plotData.minmaxPrimaryAxis);
const options: LithologyTrackOptions = {
abbr: name, // name of the only plot
legendConfig: stackLegendConfig,
data: createStackData.bind(null, plotData.data, colorTable, meta),
data: createLithologyData.bind(null, plotData.data),
showLabels: true,
showLines: showLines,
showLines: true,
lithologyInfoTable: lithologInfoTable,
};
setStackedTrackOptionFromTemplate(options, templateTrackFullPlot);
const track = new LithologyTrack(undefined as unknown as number, options);
updateStackedTrackScale(track);
info.tracks.push(track);
return track;
}

function addStackedTrack(
info: TracksInfo,
welllog: WellLog,
Expand Down Expand Up @@ -1492,17 +1470,15 @@ export function createTracks(
break;
}
case "canvas": {
addLithologyTrack(
info,
welllog,
const lithologyTrack = addLithologyTrack(
templateTrack.plots[0].name,
info.minmaxPrimaryAxis,
curves,
data,
iPrimaryAxis,
templateTrack,
templateStyles,
colorTables,
lithologyInfoTable
);
if (lithologyTrack) info.tracks.push(lithologyTrack);
break;
}
default: {
Expand Down

0 comments on commit cc35618

Please sign in to comment.