Skip to content

Commit

Permalink
Adjusting rescale value for small/large numbers (#1272)
Browse files Browse the repository at this point in the history
**Related Ticket:**
https://github.com/orgs/NASA-IMPACT/projects/17?pane=issue&itemId=85258058&issue=NASA-IMPACT%7Cveda-ui%7C1226

### Description of Changes
- Adjusting the text input to be wider. 
- Cleaning out colorRangeSlider component, creating util file, creating
initial tests.
- Creating dynamic step calculation functionality

### Notes & Questions About Changes
When observing a value in either the max or min inputs if that value has
a character count of 6 or greater the component will convert that number
into scientific notation as a display value.

### Validation / Testing
Run this branch on the veda-config code base, navigate to the E&A page
and select the difference CO2 dataset. This is an extreme data set that
should display all changes in this component.
- Confirm that the middle range identifier is always at halfway mark. 
- Confirm that the numbers are displaying in scientific notation.
  • Loading branch information
snmln authored Dec 4, 2024
2 parents 515e129 + dad42ea commit a35a28e
Show file tree
Hide file tree
Showing 15 changed files with 842 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface RasterPaintLayerProps extends BaseGeneratorParams {
colorMap?: string | undefined;
tileParams: Record<string, any>;
generatorPrefix?: string;
reScale?: { min: number; max: number };
}

export function RasterPaintLayer(props: RasterPaintLayerProps) {
Expand All @@ -24,16 +25,20 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) {
hidden,
opacity,
colorMap,
generatorPrefix = 'raster',
reScale,
generatorPrefix = 'raster'
} = props;

const { updateStyle } = useMapStyle();
const [minZoom] = zoomExtent ?? [0, 20];
const generatorId = `${generatorPrefix}-${id}`;

const updatedTileParams = useMemo(() => {
return { ...tileParams, ...colorMap && {colormap_name: colorMap}};
}, [tileParams, colorMap]);
return {
...tileParams,
...(colorMap && { colormap_name: colorMap }),
...(reScale && { reScale: Object.values(reScale) })
};
}, [tileParams, colorMap, reScale]);

//
// Generate Mapbox GL layers and sources for raster timeseries
Expand All @@ -47,7 +52,9 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) {

useEffect(
() => {
const tileParamsAsString = qs.stringify(updatedTileParams, { arrayFormat: 'comma' });
const tileParamsAsString = qs.stringify(updatedTileParams, {
arrayFormat: 'comma'
});

const zarrSource: RasterSource = {
type: 'raster',
Expand All @@ -63,8 +70,8 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) {
paint: {
'raster-opacity': hidden ? 0 : rasterOpacity,
'raster-opacity-transition': {
duration: 320,
},
duration: 320
}
},
minzoom: minZoom,
metadata: {
Expand Down Expand Up @@ -93,7 +100,8 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) {
tileApiEndpoint,
haveTileParamsChanged,
generatorParams,
colorMap
colorMap,
reScale
// generatorParams includes hidden and opacity
// hidden,
// opacity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export function RasterTimeseries(props: RasterTimeseriesProps) {
stacApiEndpoint,
tileApiEndpoint,
colorMap,
reScale,
envApiStacEndpoint,
envApiRasterEndpoint
} = props;
Expand Down Expand Up @@ -367,7 +368,8 @@ export function RasterTimeseries(props: RasterTimeseriesProps) {
{
assets: 'cog_default',
...(sourceParams ?? {}),
...(colorMap && { colormap_name: colorMap })
...(colorMap && { colormap_name: colorMap }),
...(reScale && { rescale: Object.values(reScale) })
},
// Temporary solution to pass different tile parameters for hls data
{
Expand Down Expand Up @@ -495,6 +497,7 @@ export function RasterTimeseries(props: RasterTimeseriesProps) {
}, [
mosaicUrl,
colorMap,
reScale,
points,
minZoom,
haveSourceParamsChanged,
Expand Down
1 change: 1 addition & 0 deletions app/scripts/components/common/map/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export interface BaseTimeseriesProps extends BaseGeneratorParams {
zoomExtent?: number[];
onStatusChange?: (result: { status: ActionStatus; id: string }) => void;
colorMap?: string;
reScale?: { min: number; max: number };
envApiStacEndpoint: string;
envApiRasterEndpoint: string;
}
Expand Down
1 change: 1 addition & 0 deletions app/scripts/components/common/uswds/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { USWDSAlert } from './alert';
export { USWDSButtonGroup, USWDSButton } from './button';
export { USWDSLink } from './link';
export { USWDSBanner, USWDSBannerContent } from './banner';
export { USWDSTextInput, USWDSTextInputMask } from './input';
10 changes: 10 additions & 0 deletions app/scripts/components/common/uswds/input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import { TextInput, TextInputMask } from '@trussworks/react-uswds';

export function USWDSTextInput(props) {
return <TextInput {...props} />;
}

export function USWDSTextInputMask(props) {
return <TextInputMask {...props} />;
}
12 changes: 12 additions & 0 deletions app/scripts/components/exploration/atoms/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,15 @@ export const useTimelineDatasetAnalysis = (
)
);
};

export function useTimelineDatasetColormapScale(
datasetAtom: PrimitiveAtom<TimelineDataset>
) {
const colorMapScaleAtom = useMemo(() => {
return focusAtom(datasetAtom, (optic) =>
optic.prop('settings').prop('scale')
);
}, [datasetAtom]);

return useAtom(colorMapScaleAtom);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* Removing the default appearance */
.thumb,
.thumb::-webkit-slider-thumb {
touch-action: 'none';

-webkit-appearance: none;
-webkit-tap-highlight-color: transparent;
}

.thumb {
pointer-events: none;
}
/* For Chrome browsers */
.thumb::-webkit-slider-thumb {
-webkit-appearance: none;
pointer-events: all;
width: 20px;
height: 20px;
background-color: #fff;
border-radius: 50%;
border: 2px solid #1565ef;
border-width: 1px;
box-shadow: 0 0 0 1px #c6c6c6;
cursor: pointer;
}

/* For Firefox browsers */
.thumb::-moz-range-thumb {
-webkit-appearance: none;
pointer-events: all;
width: 20px;
height: 20px;
background-color: #fff;
border-radius: 50%;
border: 2px solid #1565ef;
border-width: 1px;
box-shadow: 0 0 0 1px #c6c6c6;
cursor: pointer;
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}

/* Firefox */
input[type='number'] {
-moz-appearance: textfield;
}

.tooltiptext {
background-color: #2c3e50;
}

.tooltipmin::after {
left: 10px;
}

.tooltipmax::after {
right: 10px;
}

.tooltiptext::after {
content: '';
position: absolute;
top: 95%;
border-width: 10px 10px 0px 10px;
border-style: solid;
border-color: #2c3e50 transparent;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React from 'react';
import '@testing-library/jest-dom';

import { fireEvent, render, screen, waitFor } from '@testing-library/react';

import { ColorRangeSlider } from './index';

describe('colorRangeSlider should render with correct content.', () => {
const colorRangeData = {
min: 0,
max: 0.3,
colorMapScale: { max: 0.263, min: 0.131 },
setColorMapScale: jest.fn()
};

beforeEach(() => {
render(<ColorRangeSlider {...colorRangeData} />);
});
afterEach(() => {
jest.clearAllMocks();
});

it('Renders correct content', async () => {
const maxSlider = screen.getByTestId('maxSlider');
const minSlider = screen.getByTestId('minSlider');
const maxInput = screen.getByTestId('maxInput');
const minInput = screen.getByTestId('minInput');

expect(screen.getByText('Rescale')).toBeInTheDocument();
await waitFor(() => {
expect(minSlider).toHaveValue('0.131');
expect(maxSlider).toHaveValue('0.263');
expect(minInput).toHaveValue(0.131);
expect(maxInput).toHaveValue(0.263);
});
});

it('Shows error when number entered above max', () => {
const minInput = screen.getByTestId('minInput');

fireEvent.change(minInput, { target: { value: 0.29 } });
expect(
screen.getByText('Please enter a value less than 0.263')
).toBeInTheDocument();
});
it('Shows error when number entered below min', () => {
const maxInput = screen.getByTestId('maxInput');

fireEvent.change(maxInput, { target: { value: -0.1 } });
expect(
screen.getByText('Please enter a value larger than 0.131')
).toBeInTheDocument();
});
it('Shows error when number entered outside of min and max', () => {
const minInput = screen.getByTestId('minInput');

fireEvent.change(minInput, { target: { value: -0.1 } });
expect(
screen.getByText('Please enter a value between 0 and 0.3')
).toBeInTheDocument();
const maxInput = screen.getByTestId('maxInput');

fireEvent.change(maxInput, { target: { value: 0.4 } });
expect(
screen.getByText('Please enter a value between 0 and 0.3')
).toBeInTheDocument();
});
});

describe('colorRangeSlider should render with correct display content', () => {
const colorRangeData = {
min: -0.0000003,
max: 0.0000003,
colorMapScale: { max: 0.000000263, min: -0.000000131 },
setColorMapScale: jest.fn()
};

beforeEach(() => {
render(<ColorRangeSlider {...colorRangeData} />);
});
afterEach(() => {
jest.clearAllMocks();
});

it('Renders correct content', async () => {
const maxSlider = screen.getByTestId('maxSlider');
const minSlider = screen.getByTestId('minSlider');
const maxInput = screen.getByTestId('maxInput');
const minInput = screen.getByTestId('minInput');

expect(screen.getByText('Rescale')).toBeInTheDocument();
await waitFor(() => {
expect(minSlider).toHaveValue('-1.31e-7');
expect(maxSlider).toHaveValue('2.63e-7');
expect(minInput).toHaveValue(-1.31e-7);
expect(maxInput).toHaveValue(2.63e-7);
});
});
});
Loading

0 comments on commit a35a28e

Please sign in to comment.