Skip to content

Commit

Permalink
Merge pull request #294 from RENCI/issue278
Browse files Browse the repository at this point in the history
Issue278 - Fixed top end data values missing when selecting intervals colormap type
  • Loading branch information
PhillipsOwen authored Oct 14, 2024
2 parents 9369486 + 65f89d8 commit 461a2a8
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 32 deletions.
23 changes: 11 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@mui/joy": "^5.0.0-beta.48",
"@mui/material": "^6.1.1",
"@mui/x-date-pickers": "^7.18.0",
"@renci/apsviz-geostyler": "15.0.18",
"@renci/apsviz-geostyler": "15.0.21",
"@tanstack/react-query": "^5.56.2",
"@turf/bearing": "^7.1.0",
"@turf/circle": "^7.1.0",
Expand Down
58 changes: 48 additions & 10 deletions src/components/trays/settings/colormaps/colormap-slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SldStyleParser from 'geostyler-sld-parser';
import { Slider, Box } from '@mui/joy';
import { useSettings } from '@context';
import { restoreColorMapType } from '@utils/map-utils';
import { maxSliderValues } from './utils';

const MAXELE = 'maxele';
const MAXWVEL = 'maxwvel';
Expand Down Expand Up @@ -31,22 +32,22 @@ export const ColormapSlider = ({style}) => {
const marks = [];

if (style.name.includes("maxwvel")) {
max_slider_value = 100;
max_slider_value = maxSliderValues[MAXWVEL];
slider_step = 1;
for (let i = 0; i <= max_slider_value; i+=10) {
marks.push({ label: i, value: i });
}
}
else
if (style.name.includes("swan")) {
max_slider_value = 30;
max_slider_value = maxSliderValues[SWAN];
slider_step = 0.5;
for (let i = 0; i <= max_slider_value; i+=5) {
marks.push({ label: i, value: i });
}
}
else { // maxele
max_slider_value = 10;
max_slider_value = maxSliderValues[MAXELE];
slider_step = 0.25;
for (let i = 0; i <= max_slider_value; i++) {
marks.push({ label: i, value: i });
Expand All @@ -59,14 +60,24 @@ export const ColormapSlider = ({style}) => {
setMinSliderValue(0);

const colormapEntries = style.rules[0].symbolizers[0].colorMap.colorMapEntries;
setValue([colormapEntries[colormapEntries.length-1].quantity, colormapEntries[0].quantity]);
setValue([parseFloat(colormapEntries[colormapEntries.length-1].quantity), parseFloat(colormapEntries[0].quantity)]);
};

useEffect(() => {
const getDefaultStyle = async() => {
sldParser
.readStyle(style)
.then((geostylerStyle) => {
// for interval type colormaps, fake out current style with
// label stated max valuein range so we can do the right calculations
// get label max - in format like this: ">= 2.00"
if (geostylerStyle.output.rules[0].symbolizers[0].colorMap.type === "intervals") {
const colorMapEntries = geostylerStyle.output.rules[0].symbolizers[0].colorMap.colorMapEntries;
// now temporarily set that max range for the style
colorMapEntries[colorMapEntries.length-1].quantity =
parseFloat(colorMapEntries[colorMapEntries.length-1].label.match(/[+-]?\d+(\.\d+)?/g)).toFixed(2);
}

setCurrentStyle(geostylerStyle.output);
setSliderParams(geostylerStyle.output);
})
Expand Down Expand Up @@ -100,6 +111,11 @@ export const ColormapSlider = ({style}) => {
for(let i = colormapEntries.length-1; i >= 0; i--) {
dataRange.push(colormapEntries[i].quantity);
}
// if this is an intervals type of colormap, correct last entry in range
if (style.rules[0].symbolizers[0].colorMap.type === "intervals") {
const colorMapEntries = style.rules[0].symbolizers[0].colorMap.colorMapEntries;
dataRange[0] = parseFloat(colorMapEntries[colorMapEntries.length-1].label.match(/[+-]?\d+(\.\d+)?/g)).toFixed(2);
}

return(dataRange.reverse());
};
Expand Down Expand Up @@ -140,28 +156,50 @@ export const ColormapSlider = ({style}) => {
else {
entry.label = range[idx] + " m";
}
// if the colormap type is set to intervals, the last entry is a special case,
// so must change the last entry values
if (style.rules[0].symbolizers[0].colorMap.type === "intervals") {
if ( idx === range.length-1) {
if (style.name.includes("maxwvel")) {
entry.label = ">= " + entry.quantity + " m/s";
}
else {
entry.label = ">= " + entry.quantity + " m";
}
entry.quantity = maxSliderValue;
}
}
}
});
style.rules[0].symbolizers[0].colorMap.colorMapEntries=[...colormapEntries];

// set the style with a top max value to cover all
// possible values at the top of the range


return(style);
};

const handleChange = (event, newValue) => {
// make sure the first thumb value is not >= the second
if (newValue[0] < newValue[1]) {
// and that second is >= sliderStep
if ((newValue[0] < newValue[1]) && (newValue[1] >= sliderStep)) {
setValue(newValue);
}
};

const handleChangeCommitted = (event, newValue) => {
if (newValue[0] < newValue[1]) {
setValue(newValue);
}
else

// prevent overlapping values
if (newValue[0] === newValue[1]) {
setValue([newValue[0]-sliderStep, newValue[1]]);
newValue[0] = newValue[0]-sliderStep;
}
// since min slider value doesn't appear to work, make
// sure lower slider value is never less tha 0
newValue[0] = (newValue[0] < 0) ? 0 : newValue[0];
// also check for 0 upper value - set sliderStep as lowest value
newValue[1] = (newValue[1] < sliderStep) ? sliderStep : newValue[1];
setValue([newValue[0], newValue[1]]);

// now create new style with altered data range
// get current data range values in reverse order
Expand Down
57 changes: 48 additions & 9 deletions src/components/trays/settings/colormaps/style-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SldStyleParser from 'geostyler-sld-parser';
import { ColorMapEditor } from '@renci/apsviz-geostyler';
import { restoreColorMapType } from '@utils/map-utils';
import _cloneDeep from 'lodash/cloneDeep';
import { maxSliderValues } from './utils';

const MAXELE = 'maxele';
const MAXWVEL = 'maxwvel';
Expand Down Expand Up @@ -82,6 +83,7 @@ export const StyleEditor = () => {
(_, i) => (startingNumber + i * (endingNumber - startingNumber) / (maxNumber - 1)).toFixed(2)
);


// handles any change to the colormap properties provided
// by the geostyler package component - ColorMapEdit
// editable properties include colormap type,
Expand All @@ -91,27 +93,49 @@ export const StyleEditor = () => {
// get values changed and update the style accordingly
const newColorMap = _cloneDeep(colormap);

// save the label units for later restoration
let labelUnit = colormap.colorMapEntries[0].label.split("").reverse().join("").split(" ")[0];
// reverse again if this was a m/s unit - whew!
if (labelUnit.length > 1) labelUnit = labelUnit.split("").reverse().join("");

//update type of colorMap
newColorMap.type = value.type? value.type : "ramp";

// check to see number of classes changed
if (colormap.colorMapEntries.length !== value.colorMapEntries.length) {
// changed number of classes, so must rebuild the quantity and label
// values with the colormap range currently defined.
const range =
[Number(colormap.colorMapEntries[0].quantity), Number(colormap.colorMapEntries[colormap.colorMapEntries.length-1].quantity)];

// check to see if this an intervals type of colormap
// must handle weird last entry case, if so
const topRange = (colormap.type === "intervals") ?
Number(colormap.colorMapEntries[colormap.colorMapEntries.length-1].label.match(/[+-]?\d+(\.\d+)?/g))
:
Number(colormap.colorMapEntries[colormap.colorMapEntries.length-1].quantity);

const range = [Number(colormap.colorMapEntries[0].quantity), topRange];
const newRangeList = getRangeList(range[0], range[1], value.colorMapEntries.length);
const newColorMapEntries = value.colorMapEntries.map((entry, index) => {
entry.quantity = newRangeList[index];
entry.label = newRangeList[index];
entry.label = newRangeList[index] + " " + labelUnit;
return (
entry
);
});
newColorMap.colorMapEntries = newColorMapEntries;
}
// otherwise - we can just copy the colorMapEntries into the newColorMap - incase the color ramp changed
// only other thing to look out for, is whether this was previously an intervals colormap type
// and now has been changed to ramp
// in that case we have modify the last colormap entry
else {
if (value.colorMapEntries[value.colorMapEntries.length-1].label.includes(">=")) {
const last = value.colorMapEntries.length-1;
value.colorMapEntries[last].quantity = parseFloat(value.colorMapEntries[last].label.match(/[+-]?\d+(\.\d+)?/g)).toFixed(2);
const labelParts = value.colorMapEntries[last].label.split(" ");
if (labelParts.length >= 3)
value.colorMapEntries[last].label = parseFloat(labelParts[1]).toFixed(2) + " " + labelParts[2];
}
newColorMap.colorMapEntries = value.colorMapEntries.map((entry) => entry);
}

Expand All @@ -125,20 +149,35 @@ export const StyleEditor = () => {
.readStyle(style)
.then((geoStylerStyle) => {
geoStylerStyle.output.rules[0].symbolizers[0].colorMap = colormap;
// if the colormap type is set to intervals, the last entry is a special case,
// so must change the last entry values
const styleName = geoStylerStyle.output.name.split('_')[0];
if (colormap.type === "intervals") {
const lastIndex = colormap.colorMapEntries.length-1;
if (styleName === MAXWVEL) {
geoStylerStyle.output.rules[0].symbolizers[0].colorMap.colorMapEntries[lastIndex].label = ">= " + colormap.colorMapEntries[lastIndex].quantity + " m/s";
}
else {
geoStylerStyle.output.rules[0].symbolizers[0].colorMap.colorMapEntries[lastIndex].label = ">= " + colormap.colorMapEntries[lastIndex].quantity + " m";
}
geoStylerStyle.output.rules[0].symbolizers[0].colorMap.colorMapEntries[lastIndex].quantity = maxSliderValues[styleName];
}

// save colormap type - it seems to get wiped out when the parser
// writes out the text style
const colorMapType = colormap.type;
sldParser.writeStyle(geoStylerStyle.output).then((sldStyle) => {
const updatedStyle = restoreColorMapType(colorMapType, sldStyle.output);
const styleName = geoStylerStyle.output.name;
if (styleName.includes(MAXELE)) {
switch (styleName) {
case MAXELE:
mapStyle.maxele.set(updatedStyle);
} else
if (styleName.includes(MAXWVEL)) {
break;
case MAXWVEL:
mapStyle.maxwvel.set(updatedStyle);
} else
if (styleName.includes(SWAN)) {
break;
case SWAN:
mapStyle.swan.set(updatedStyle);
break;
}
});
});
Expand Down
5 changes: 5 additions & 0 deletions src/components/trays/settings/colormaps/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const maxSliderValues = {
"maxele": 10,
"maxwvel": 100,
"swan": 30
};

0 comments on commit 461a2a8

Please sign in to comment.