From 36b85bb1254381a8e8dc83d20c80b0594c6db7c4 Mon Sep 17 00:00:00 2001 From: Denis-Shamakin <160724076+Denis-Shamakin@users.noreply.github.com> Date: Fri, 12 Jul 2024 14:15:42 +0500 Subject: [PATCH] feat: color function (#2054) (#2152) Added the ability to specify a function instead of color tables --------- Co-authored-by: DShamakin --- .../src/WellLogViewer.stories.tsx | 12 ++++++++- .../well-log-viewer/src/WellLogViewer.tsx | 2 +- .../src/components/PlotDialog.tsx | 15 ++++++++--- .../src/components/WellLogView.tsx | 14 +++++++---- .../well-log-viewer/src/utils/color-table.ts | 12 +++++++-- .../src/utils/gradientfill-plot-legend.ts | 25 +++++++++++++------ .../well-log-viewer/src/utils/tracks.ts | 5 +++- 7 files changed, 65 insertions(+), 20 deletions(-) diff --git a/typescript/packages/well-log-viewer/src/WellLogViewer.stories.tsx b/typescript/packages/well-log-viewer/src/WellLogViewer.stories.tsx index 638fa639d..19b08142f 100644 --- a/typescript/packages/well-log-viewer/src/WellLogViewer.stories.tsx +++ b/typescript/packages/well-log-viewer/src/WellLogViewer.stories.tsx @@ -268,13 +268,23 @@ function addTemplateTrack( return templateNew; } +// Custom function to demonstrate the ability to specify a function instead of color tables +function colorTableFunc(v: number): [number, number, number] { + if (v >= 0 && v < 0.25) return [255, 0.0, 0.0]; + else if (v >= 0.25 && v < 0.5) return [182, 182, 0.0]; + else if (v >= 0.5 && v < 0.75) return [0.0, 255, 0.0]; + else if (v >= 0.75 && v < 1) return [0.0, 182, 182]; + else if (v == 1) return [0.0, 0.0, 255]; + else return [0, 0, 0]; +} + export const Default: StoryObj = { args: { id: "Well-Log-Viewer", horizontal: false, welllog: require("../../../../example-data/L898MUD.json")[0], // eslint-disable-line template: require("../../../../example-data/welllog_template_1.json"), // eslint-disable-line - colorTables: colorTables, + colorTables: colorTableFunc, wellpick: wellpick, axisTitles: axisTitles, axisMnemos: axisMnemos, diff --git a/typescript/packages/well-log-viewer/src/WellLogViewer.tsx b/typescript/packages/well-log-viewer/src/WellLogViewer.tsx index e57ee4edf..09fc3d612 100644 --- a/typescript/packages/well-log-viewer/src/WellLogViewer.tsx +++ b/typescript/packages/well-log-viewer/src/WellLogViewer.tsx @@ -278,7 +278,7 @@ WellLogViewer.propTypes = { /** * Prop containing color table data */ - colorTables: PropTypes.array, //.isRequired, + colorTables: PropTypes.any, //.isRequired, /** * Orientation of the track plots on the screen. Default is false diff --git a/typescript/packages/well-log-viewer/src/components/PlotDialog.tsx b/typescript/packages/well-log-viewer/src/components/PlotDialog.tsx index 6bf2af0f4..0adb6c9b5 100644 --- a/typescript/packages/well-log-viewer/src/components/PlotDialog.tsx +++ b/typescript/packages/well-log-viewer/src/components/PlotDialog.tsx @@ -91,6 +91,12 @@ export function createBooleanItems(): ReactNode[] { function createColorTableItems(colorTables: ColorTable[]): ReactNode[] { const nodes: ReactNode[] = []; + + if (typeof colorTables === "function") { + nodes.push(); + return nodes; + } + if (!colorTables) { console.error( "colorTables is missed or empty in createColorTableItems()" @@ -217,7 +223,10 @@ export class PlotPropertiesDialog extends Component { // for 'gradientfill' plot colorTable: - this.props.wellLogView.props.colorTables?.[0]?.name, + typeof this.props.wellLogView.props.colorTables === + "function" + ? "Function" + : this.props.wellLogView.props.colorTables?.[0]?.name, inverseColorTable: undefined, colorScale: undefined, inverseColorScale: undefined, @@ -335,7 +344,7 @@ export class PlotPropertiesDialog extends Component { ]; } else if (type === "gradientfill") { const colorTables = this.props.wellLogView.props.colorTables; - [ + return [ this.createSelectControl( "colorTable", "Fill Color table", @@ -388,7 +397,7 @@ export class PlotPropertiesDialog extends Component { createScaleItems() ), ] - : []} + : []} {this.createSelectControl( "name", diff --git a/typescript/packages/well-log-viewer/src/components/WellLogView.tsx b/typescript/packages/well-log-viewer/src/components/WellLogView.tsx index aa0cafb60..a69817d82 100644 --- a/typescript/packages/well-log-viewer/src/components/WellLogView.tsx +++ b/typescript/packages/well-log-viewer/src/components/WellLogView.tsx @@ -838,10 +838,14 @@ function fillPlotTemplate( inverseColor: options.inverseColor || "", fill: (options1 ? options1.fill : options.fill) || "", fill2: options2 ? options2.fill : "", - colorTable: options.colorTable ? options.colorTable.name : "", - inverseColorTable: options.inverseColorTable - ? options.inverseColorTable.name - : "", + colorTable: + typeof options.colorTable === "function" + ? "Function" + : options.colorTable?.name ?? "", + inverseColorTable: + typeof options.inverseColorTable === "function" + ? "Function" + : options.inverseColorTable?.name ?? "", colorScale: options.colorScale, inverseColorScale: options.inverseColorScale, }; @@ -2098,7 +2102,7 @@ export function _propTypesWellLogView(): Record { /** * Prop containing color table data for discrete well logs */ - colorTables: PropTypes.array, //.isRequired, + colorTables: PropTypes.any, //.isRequired, /** * Well picks data diff --git a/typescript/packages/well-log-viewer/src/utils/color-table.ts b/typescript/packages/well-log-viewer/src/utils/color-table.ts index fde88b729..0d04ea2c7 100644 --- a/typescript/packages/well-log-viewer/src/utils/color-table.ts +++ b/typescript/packages/well-log-viewer/src/utils/color-table.ts @@ -73,11 +73,15 @@ export function getExactColor( get HTML string with interpolated color value in #xxxxxx format */ export function getInterpolatedColor( - colorTable: ColorTable, + colorTable: ColorTable | ((v: number) => [number, number, number]), v: number ): [number, number, number] { // TODO: Do not compute these 3 constants (cNaN, cBelow, cAbove) every time! + if (typeof colorTable === "function") { + return colorTable(v); + } + const cNaN: [number, number, number] = colorTable.colorNaN ? colorTable.colorNaN : [255, 255, 255]; // "white" @@ -115,9 +119,13 @@ export function getInterpolatedColor( get HTML string with interpolated color value in #xxxxxx format */ export function getInterpolatedColorString( - colorTable: ColorTable, + colorTable: ColorTable | ((v: number) => [number, number, number]), v: number ): string { + if (typeof colorTable === "function") { + return colorToString(colorTable(v), "#ffffff"); + } + // TODO: Do not compute these 3 constants (cNaN, cBelow, cAbove) every time! const cNaN = colorToString(colorTable.colorNaN, "#ffffff"); // "white" diff --git a/typescript/packages/well-log-viewer/src/utils/gradientfill-plot-legend.ts b/typescript/packages/well-log-viewer/src/utils/gradientfill-plot-legend.ts index 0cd906dcc..94dbd0ab0 100644 --- a/typescript/packages/well-log-viewer/src/utils/gradientfill-plot-legend.ts +++ b/typescript/packages/well-log-viewer/src/utils/gradientfill-plot-legend.ts @@ -29,7 +29,6 @@ function createGradient( .attr("x2", "100%") //since it's a horizontal linear gradient .attr("y1", "0%") .attr("y2", "0%"); - const colors = colorTable.colors; if (rLogarithmic !== undefined) { const yDelta = Math.log(rLogarithmic); // log(max/min) const d = rLogarithmic - 1; @@ -44,12 +43,24 @@ function createGradient( .style("stop-color", c); } } else { - for (let i = 0; i < colors.length; i++) { - const color = colors[i]; - const c = color4ToString(color); - lg.append("stop") - .attr("offset", color[0] * 100.0 + "%") - .style("stop-color", c); + if (typeof colorTable === "function") { + const nIntervals = 5; + for (let i = 0; i < nIntervals; i++) { + const fraction = i / nIntervals; + const c = getInterpolatedColorString(colorTable, fraction); + lg.append("stop") + .attr("offset", fraction * 100.0 + "%") + .style("stop-color", c); + } + } else { + const colors = colorTable.colors; + for (let i = 0; i < colors.length; i++) { + const color = colors[i]; + const c = color4ToString(color); + lg.append("stop") + .attr("offset", color[0] * 100.0 + "%") + .style("stop-color", c); + } } } return id; diff --git a/typescript/packages/well-log-viewer/src/utils/tracks.ts b/typescript/packages/well-log-viewer/src/utils/tracks.ts index 18fa9b7d6..f86c8389b 100644 --- a/typescript/packages/well-log-viewer/src/utils/tracks.ts +++ b/typescript/packages/well-log-viewer/src/utils/tracks.ts @@ -370,7 +370,10 @@ function getColorTable( return defColorTable; } if (id && colorTables) { - const colorTable = colorTables.find((value) => value.name === id); + const colorTable = + typeof colorTables === "function" + ? colorTables + : colorTables.find((value) => value.name === id); if (colorTable) return colorTable; console.error( "colorTable id='" + id + "' is not found in getColorTable()"