Skip to content

Commit cc35618

Browse files
committed
async pattern loading, refactor
1 parent 41fd336 commit cc35618

File tree

3 files changed

+92
-99
lines changed

3 files changed

+92
-99
lines changed

react/src/demo/example-data/discrete-facies-test.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,25 @@
4747
[
4848
1400,
4949
2,
50-
2,
50+
1,
5151
0.247
5252
],
5353
[
5454
2179,
55-
2,
5655
1,
56+
2,
5757
0.247
5858
],
5959
[
60-
2180.6093750344276,
60+
2300.0,
61+
3,
6162
3,
62-
2,
6363
0.137
6464
],
6565
[
66-
3541.6093750344276,
67-
3,
66+
3541.6,
6867
3,
68+
4,
6969
0.237
7070
],
7171
[

react/src/lib/components/WellLogViewer/components/LithologyTrack.tsx

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -50,47 +50,63 @@ export class LithologyTrack extends StackedTrack {
5050
constructor(id: string | number, props: LithologyTrackOptions) {
5151
super(id, props);
5252
this.lithologyInfo = props.lithologyInfoTable as LithologyInfoTable; // TODO - ensure table is given and valid
53+
setupLithologyInfoMap(this.lithologyInfo);
5354
this.patterns = new Map<string | number, CanvasPattern | string>();
55+
this.loadPatterns = this.loadPatterns.bind(this);
5456
}
5557

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

60-
// Find unique canvas code names in data for this track. Later only load images for used codes
61-
const uniqueCodes = [
62-
...new Set(data.map((item: LithologyTrackDataRow) => item.name)),
63-
] as (string | number)[]; // TODO: why doesn't typescript understand this itself?
64-
setupLithologyInfoMap(this.lithologyInfo);
65-
uniqueCodes.forEach((code) => {
66-
const pattern = lithologyInfoMap.get(code);
67-
// const pattern = patterns.find(pattern => code === pattern.code)
68-
if (pattern?.patternImage) {
69-
// Check if we have loaded pattern
70-
if (!this.patterns.get(code)) {
71-
// Temporarily set solid color while we get image to avoid fetching multiple times
72-
this.patterns.set(code, "#eee");
73-
// Create pattern
74-
const patternImage = new Image();
75-
patternImage.src = pattern.patternImage;
76-
patternImage.onload = () => {
77-
this.patterns.set(
78-
code,
79-
this.ctx?.createPattern(
80-
patternImage,
81-
"repeat"
82-
) as CanvasPattern
83-
);
84-
};
67+
let numUniquePatternsLoading = uniqueCodes.length;
68+
uniqueCodes.forEach((code) => {
69+
const pattern = lithologyInfoMap.get(code);
70+
// const pattern = patterns.find(pattern => code === pattern.code)
71+
if (pattern?.patternImage) {
72+
// Check if we have loaded pattern
73+
if (!this.patterns.get(code)) {
74+
// Temporarily set solid color while we get image to avoid fetching multiple times
75+
this.patterns.set(code, "#eee");
76+
// Create pattern
77+
const patternImage = new Image();
78+
patternImage.src = pattern.patternImage;
79+
patternImage.onload = () => {
80+
this.patterns.set(
81+
code,
82+
this.ctx?.createPattern(
83+
patternImage,
84+
"repeat"
85+
) as CanvasPattern
86+
);
87+
numUniquePatternsLoading -= 1;
88+
// Resolve on last image.
89+
if (numUniquePatternsLoading <= 0) {
90+
this.isLoading = false;
91+
resolve();
92+
}
93+
};
94+
} else {
95+
numUniquePatternsLoading -= 1;
96+
}
97+
} else {
98+
numUniquePatternsLoading -= 1;
8599
}
100+
});
101+
if (numUniquePatternsLoading <= 0) {
102+
this.isLoading = false;
103+
resolve();
86104
}
87-
});
105+
})
88106
}
89107

90108
plot(): void {
91-
super.plot();
92109
const { ctx, scale: yscale, data, patterns } = this;
93-
94110
if (!ctx || !data) return;
95111
const rectangles = scaleData(yscale, data);
96112
const { width: rectWidth, clientWidth, clientHeight } = ctx.canvas;
@@ -156,7 +172,8 @@ export class LithologyTrack extends StackedTrack {
156172
options.data().then(
157173
(data: LithologyTrackDataRow[]) => {
158174
this.data = data;
159-
this.plot();
175+
// @ts-ignore
176+
this.loadPatterns().then(this.plot());
160177
},
161178
(error: Error | string) => super.onError(error)
162179
);
@@ -189,8 +206,8 @@ export class LithologyTrack extends StackedTrack {
189206
this.plot();
190207
}
191208
onDataLoaded(): void {
192-
this.loadPatterns();
193-
this.plot();
209+
// @ts-ignore
210+
this.loadPatterns().then(this.plot());
194211
}
195212
}
196213

react/src/lib/components/WellLogViewer/utils/tracks.ts

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ import { deepCopy } from "./deepcopy";
6060
import { createPlotType } from "@equinor/videx-wellog";
6161
import { defaultPlotFactory } from "@equinor/videx-wellog";
6262
import {
63-
LithologyInfoTable,
6463
LithologyTrack,
64+
LithologyInfoTable,
6565
LithologyTrackOptions,
6666
} from "../components/LithologyTrack";
6767
export function indexOfElementByName(array: Named[], name: string): number {
@@ -978,6 +978,28 @@ function createAreaData(
978978
};
979979
}
980980

981+
async function createLithologyData(
982+
data: [number | null, number | string | null][]
983+
) {
984+
// Remove possibly null values for depth
985+
const data_no_null_depths = data.filter((elem) => {
986+
return elem[0] !== null;
987+
});
988+
// 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)
989+
return data_no_null_depths.map((dataRow, index) => {
990+
const value = dataRow[1] == null ? Number.NaN : dataRow[1].toString();
991+
return {
992+
from: dataRow[0],
993+
to:
994+
index < data.length - 1
995+
? data_no_null_depths[index + 1][0]
996+
: dataRow[0],
997+
name: value,
998+
color: { r: 255, g: 25, b: 25 }, // Apparently, this is needed by the mother class in videx, use dummy for now
999+
};
1000+
});
1001+
}
1002+
9811003
async function createStackData(
9821004
data: [number | null, number | string | null][],
9831005
colorTable: ColorTable | undefined,
@@ -1290,19 +1312,13 @@ function addGraphTrack(
12901312
}
12911313
}
12921314
function addLithologyTrack(
1293-
info: TracksInfo,
1294-
welllog: WellLog,
1315+
name: string,
1316+
currentMinMaxPrimaryAxis: [number, number],
12951317
curves: WellLogCurve[],
12961318
data: WellLogDataRow[],
12971319
iPrimaryAxis: number,
1298-
templateTrack: TemplateTrack,
1299-
templateStyles?: TemplateStyle[],
1300-
colorTables?: ColorTable[],
13011320
lithologInfoTable?: LithologyInfoTable
1302-
): void {
1303-
const templatePlot = templateTrack.plots[0];
1304-
const name = templatePlot.name;
1305-
1321+
): LithologyTrack | undefined {
13061322
const iCurve = indexOfElementByName(curves, name);
13071323
if (iCurve < 0) return; // curve not found
13081324
const curve = curves[iCurve];
@@ -1311,58 +1327,20 @@ function addLithologyTrack(
13111327
if (dimensions !== 1) return;
13121328

13131329
const plotData = preparePlotData(data, iCurve, iPrimaryAxis);
1314-
checkMinMax(info.minmaxPrimaryAxis, plotData.minmaxPrimaryAxis);
1315-
1316-
// make full props
1317-
const templatePlotProps = getTemplatePlotProps(
1318-
templatePlot,
1319-
templateStyles
1320-
);
1321-
const templateTrackFullPlot: TemplateTrack = deepCopy(templateTrack);
1322-
1323-
templateTrackFullPlot.title = makeTrackHeader(welllog, templateTrack);
1324-
templateTrackFullPlot.plots[0].type = templatePlotProps.type;
1325-
1326-
// curve.valueType === "integer", "string"
1327-
const logColor = templatePlotProps.colorTable;
1328-
let colorTable: ColorTable | undefined = undefined;
1329-
if (logColor) {
1330-
if (colorTables) {
1331-
colorTable = colorTables.find(
1332-
(colorTable) => colorTable.name == logColor
1333-
);
1334-
if (!colorTable)
1335-
console.error("Missed '" + logColor + "' color table");
1336-
} else {
1337-
console.error(
1338-
"No color tables file given for '" + logColor + "' color table"
1339-
);
1340-
}
1341-
} else {
1342-
console.error("No color table given in template plot props");
1343-
}
1344-
const meta = getDiscreteMeta(welllog, name);
1345-
if (!meta && curve.valueType == "integer")
1346-
console.log(
1347-
"Discrete meta information for '" +
1348-
name +
1349-
"' not found. Use default"
1350-
);
1351-
1352-
const showLines = true;
1330+
checkMinMax(currentMinMaxPrimaryAxis, plotData.minmaxPrimaryAxis);
13531331
const options: LithologyTrackOptions = {
13541332
abbr: name, // name of the only plot
13551333
legendConfig: stackLegendConfig,
1356-
data: createStackData.bind(null, plotData.data, colorTable, meta),
1334+
data: createLithologyData.bind(null, plotData.data),
13571335
showLabels: true,
1358-
showLines: showLines,
1336+
showLines: true,
13591337
lithologyInfoTable: lithologInfoTable,
13601338
};
1361-
setStackedTrackOptionFromTemplate(options, templateTrackFullPlot);
13621339
const track = new LithologyTrack(undefined as unknown as number, options);
13631340
updateStackedTrackScale(track);
1364-
info.tracks.push(track);
1341+
return track;
13651342
}
1343+
13661344
function addStackedTrack(
13671345
info: TracksInfo,
13681346
welllog: WellLog,
@@ -1492,17 +1470,15 @@ export function createTracks(
14921470
break;
14931471
}
14941472
case "canvas": {
1495-
addLithologyTrack(
1496-
info,
1497-
welllog,
1473+
const lithologyTrack = addLithologyTrack(
1474+
templateTrack.plots[0].name,
1475+
info.minmaxPrimaryAxis,
14981476
curves,
14991477
data,
15001478
iPrimaryAxis,
1501-
templateTrack,
1502-
templateStyles,
1503-
colorTables,
15041479
lithologyInfoTable
15051480
);
1481+
if (lithologyTrack) info.tracks.push(lithologyTrack);
15061482
break;
15071483
}
15081484
default: {

0 commit comments

Comments
 (0)