From bbe3672abab306b26969b43580a58791bce3ed85 Mon Sep 17 00:00:00 2001 From: snmln Date: Wed, 9 Oct 2024 10:25:33 -0400 Subject: [PATCH 01/11] initial commit --- app/scripts/components/common/uswds/index.tsx | 2 + app/scripts/components/common/uswds/input.tsx | 10 + .../datasets/color-range-slider.scss | 59 ++++++ .../components/datasets/colorRangeSlider.tsx | 180 ++++++++++++++++++ .../components/datasets/colormap-options.tsx | 117 +++++++++--- .../components/datasets/data-layer-card.tsx | 2 + 6 files changed, 344 insertions(+), 26 deletions(-) create mode 100644 app/scripts/components/common/uswds/input.tsx create mode 100644 app/scripts/components/exploration/components/datasets/color-range-slider.scss create mode 100644 app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx diff --git a/app/scripts/components/common/uswds/index.tsx b/app/scripts/components/common/uswds/index.tsx index e5410b060..a8f151d6b 100644 --- a/app/scripts/components/common/uswds/index.tsx +++ b/app/scripts/components/common/uswds/index.tsx @@ -2,3 +2,5 @@ export { USWDSAlert } from './alert'; export { USWDSButtonGroup, USWDSButton } from './button'; export { USWDSLink } from './link'; export { USWDSBanner, USWDSBannerContent } from './banner'; + +export { USWDSTextInput, USWDSTextInputMask } from './input'; diff --git a/app/scripts/components/common/uswds/input.tsx b/app/scripts/components/common/uswds/input.tsx new file mode 100644 index 000000000..f239b6bc5 --- /dev/null +++ b/app/scripts/components/common/uswds/input.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import { TextInput, TextInputMask } from "@trussworks/react-uswds"; + +export function USWDSTextInput(props) { + return ; +} + +export function USWDSTextInputMask(props) { + return ; + } \ No newline at end of file diff --git a/app/scripts/components/exploration/components/datasets/color-range-slider.scss b/app/scripts/components/exploration/components/datasets/color-range-slider.scss new file mode 100644 index 000000000..a713e291b --- /dev/null +++ b/app/scripts/components/exploration/components/datasets/color-range-slider.scss @@ -0,0 +1,59 @@ +.slider__track { + background-color: #dddfe2; +} + +.slider__range { + background-color: #1565ef; +} + +/* Removing the default appearance */ +.thumb, +.thumb::-webkit-slider-thumb { + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; +} + +.thumb { + pointer-events: none; +} +.middle_marker{ + background-color: #1B2631; +} +/* 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; +} diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx new file mode 100644 index 000000000..21740c9a7 --- /dev/null +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -0,0 +1,180 @@ +import React, { useCallback, useEffect, useState, useRef } from 'react'; + +import './color-range-slider.scss'; + +import { USWDSTextInput } from '$components/common/uswds'; + +export function ColorRangeSlider({ min, max, onChange }) { + const fromInput = useRef(null); + const toInput = useRef(null); + + const [minVal, setMinVal] = useState(min); + const [maxVal, setMaxVal] = useState(max); + const [inputError, setInputError] = useState({ min: false, max: false }); + + const minValRef = useRef(min); + const maxValRef = useRef(max); + const range = useRef(null); + const middleMarker = useRef(null); + + // Convert to percentage + const getPercent = useCallback( + (value) => Math.round(((value - min) / (max - min)) * 100), + [min, max] + ); + + // Set width of the range to decrease from the right side + useEffect(() => { + let maxValPrevious; + + let minValPrevious; + if (maxVal != maxValPrevious) { + maxValPrevious = maxVal; + const minPercent = getPercent(minValRef.current); + const maxPercent = getPercent(maxVal); + + if (range.current) { + range.current.style.width = `${ + maxPercent - minPercent >= 100 ? 100 : maxPercent - minPercent + }%`; + if (middleMarker.current) + middleMarker.current.style.left = `${range.current.style.width}%`; + } + } + if (minVal != minValPrevious) { + minValPrevious = maxVal; + const minPercent = getPercent(minVal); + const maxPercent = getPercent(maxValRef.current); + + if (range.current) { + range.current.style.left = `${minPercent}%`; + range.current.style.width = `${ + maxPercent - minPercent >= 100 ? 100 : maxPercent - minPercent + }%`; + } + } + onChange({ min: minVal, max: maxVal }); + }, [maxVal, minVal, getPercent, onChange]); + + const textInputClasses = + 'flex-1 radius-md height-3 font-size-3xs width-5 border-2px '; + const thumbPosition = `position-absolute pointer-events width-card height-0 outline-0`; + + const dynamicStepIncrement = (max, min) => { + // determining numeric distance between min and max + const value = Math.abs(max - min); + const tenLog = Math.floor(Math.log(value) / Math.log(10)); + }; + return ( +
+
+ + + { + const value = Number(event.target.value); + + if (value < min || value > max) { + return setInputError({ max: inputError.max, min: true }); + } + setInputError({ max: inputError.max, min: false }); + + setMinVal(value); + return (minValRef.current = value); + }} + /> + +
+ { + setMinVal(Math.min(Number(event.target.value), maxVal - 0.01)); + minValRef.current = Number(event.target.value); + }} + className={`thumb ${thumbPosition} z-index-300`} + style={{ zIndex: minVal >= max - 10 * 0.01 ? '500' : '300' }} + /> + { + setMaxVal(Math.max(Number(event.target.value), minVal + 0.01)); + maxValRef.current = Number(event.target.value); + }} + className={`thumb ${thumbPosition} z-400`} + style={{ zIndex: minVal <= max - 10 * 0.01 ? '500' : '400' }} + /> +
+
+
+ {min < 0 ? ( +
+ ) : null} +
+
+
+ + { + const value = Number(event.target.value); + + if (value < min || value > max) { + return setInputError({ max: true, min: inputError.min }); + } else{ + setInputError({ max: false, min: inputError.min }); + setMaxVal(value); + return (maxValRef.current = value);} + + //NEED to find the value on change for color maps. + }} + /> + + {inputError.max || inputError.min ? ( +

+ Please enter a value between {min} and {max} +

+ ) : null} +
+ ); +} diff --git a/app/scripts/components/exploration/components/datasets/colormap-options.tsx b/app/scripts/components/exploration/components/datasets/colormap-options.tsx index a6ce07e21..a8f483342 100644 --- a/app/scripts/components/exploration/components/datasets/colormap-options.tsx +++ b/app/scripts/components/exploration/components/datasets/colormap-options.tsx @@ -1,23 +1,39 @@ import React, { useEffect, useState } from 'react'; -import { Icon } from "@trussworks/react-uswds"; +import { Icon } from '@trussworks/react-uswds'; import { CollecticonDrop } from '@devseed-ui/collecticons'; -import { sequentialColorMaps, divergingColorMaps, restColorMaps } from './colorMaps'; + +import { + sequentialColorMaps, + divergingColorMaps, + restColorMaps +} from './colorMaps'; import './colormap-options.scss'; +import { ColorRangeSlider } from './colorRangeSlider'; export const DEFAULT_COLORMAP = 'viridis'; const CURATED_SEQUENTIAL_COLORMAPS = [ - 'viridis', 'plasma', 'inferno', 'magma', 'cividis', - 'purples', 'blues', 'reds', 'greens', 'oranges', - 'ylgnbu', 'ylgn', 'gnbu' + 'viridis', + 'plasma', + 'inferno', + 'magma', + 'cividis', + 'purples', + 'blues', + 'reds', + 'greens', + 'oranges', + 'ylgnbu', + 'ylgn', + 'gnbu' ]; -const CURATED_DIVERGING_COLORMAPS = [ - 'rdbu', 'rdylbu', 'bwr', 'coolwarm' -]; +const CURATED_DIVERGING_COLORMAPS = ['rdbu', 'rdylbu', 'bwr', 'coolwarm']; -export const classifyColormap = (colormapName: string): 'sequential' | 'diverging' | 'rest' | 'unknown' => { +export const classifyColormap = ( + colormapName: string +): 'sequential' | 'diverging' | 'rest' | 'unknown' => { const baseName = normalizeColorMap(colormapName); if (sequentialColorMaps[baseName]) { @@ -33,9 +49,14 @@ export const classifyColormap = (colormapName: string): 'sequential' | 'divergin interface ColormapOptionsProps { colorMap: string | undefined; setColorMap: (colorMap: string) => void; + min: number; + max: number; } -export const getColormapColors = (colormapName: string, isReversed: boolean): string[] => { +export const getColormapColors = ( + colormapName: string, + isReversed: boolean +): string[] => { const baseName = normalizeColorMap(colormapName); const colormapData = sequentialColorMaps[baseName] || @@ -49,10 +70,17 @@ export const getColormapColors = (colormapName: string, isReversed: boolean): st return `rgba(${r}, ${g}, ${b}, ${a})`; }); - return isReversed ? colors.reduceRight((acc, color) => [...acc, color], []) : colors; + return isReversed + ? colors.reduceRight((acc, color) => [...acc, color], []) + : colors; }; -export function ColormapOptions({ colorMap = DEFAULT_COLORMAP, setColorMap}: ColormapOptionsProps) { +export function ColormapOptions({ + colorMap = DEFAULT_COLORMAP, + min, + max, + setColorMap +}: ColormapOptionsProps) { const initialIsReversed = colorMap.endsWith('_r'); const initialColorMap = normalizeColorMap(colorMap); @@ -63,9 +91,15 @@ export function ColormapOptions({ colorMap = DEFAULT_COLORMAP, setColorMap}: Col const [customColorMap, setCustomColorMap] = useState(null); useEffect(() => { - if (colormapType === 'sequential' && !CURATED_SEQUENTIAL_COLORMAPS.includes(selectedColorMap)) { + if ( + colormapType === 'sequential' && + !CURATED_SEQUENTIAL_COLORMAPS.includes(selectedColorMap) + ) { setCustomColorMap(selectedColorMap); - } else if (colormapType === 'diverging' && !CURATED_DIVERGING_COLORMAPS.includes(selectedColorMap)) { + } else if ( + colormapType === 'diverging' && + !CURATED_DIVERGING_COLORMAPS.includes(selectedColorMap) + ) { setCustomColorMap(selectedColorMap); } }, [selectedColorMap, colormapType]); @@ -74,15 +108,25 @@ export function ColormapOptions({ colorMap = DEFAULT_COLORMAP, setColorMap}: Col if (colormapType === 'sequential') { if (customColorMap) { - availableColormaps = [{ name: customColorMap }, ...CURATED_SEQUENTIAL_COLORMAPS.map(name => ({ name }))]; + availableColormaps = [ + { name: customColorMap }, + ...CURATED_SEQUENTIAL_COLORMAPS.map((name) => ({ name })) + ]; } else { - availableColormaps = CURATED_SEQUENTIAL_COLORMAPS.map(name => ({ name })); + availableColormaps = CURATED_SEQUENTIAL_COLORMAPS.map((name) => ({ + name + })); } } else if (colormapType === 'diverging') { if (customColorMap) { - availableColormaps = [{ name: customColorMap }, ...CURATED_DIVERGING_COLORMAPS.map(name => ({ name }))]; + availableColormaps = [ + { name: customColorMap }, + ...CURATED_DIVERGING_COLORMAPS.map((name) => ({ name })) + ]; } else { - availableColormaps = CURATED_DIVERGING_COLORMAPS.map(name => ({ name })); + availableColormaps = CURATED_DIVERGING_COLORMAPS.map((name) => ({ + name + })); } } else if (colormapType === 'rest') { availableColormaps = [{ name: selectedColorMap }]; @@ -105,17 +149,31 @@ export function ColormapOptions({ colorMap = DEFAULT_COLORMAP, setColorMap}: Col return (
-
Colormap options
+
+ Colormap options +
+ +
+ console.log(`min = ${min}, max = ${max}`)} /> +
+ -
-
- {isReversed ? ( ) : ( )} - +
@@ -125,13 +183,21 @@ export function ColormapOptions({ colorMap = DEFAULT_COLORMAP, setColorMap}: Col return (
handleColorMapSelect(name.toLowerCase())} >
- { const value = Number(event.target.value); - + if (value < minVal + 0.01) return false; if (value < min || value > max) { return setInputError({ max: true, min: inputError.min }); - } else{ - setInputError({ max: false, min: inputError.min }); - setMaxVal(value); - return (maxValRef.current = value);} - - //NEED to find the value on change for color maps. + } else { + setInputError({ max: false, min: inputError.min }); + setMaxVal(Math.max(value, minVal + 0.01)); + setColorMapScale({ + min: colorMapScale.min, + max: maxValRef.current + }); + return (maxValRef.current = value); + } }} /> diff --git a/app/scripts/components/exploration/components/datasets/colormap-options.tsx b/app/scripts/components/exploration/components/datasets/colormap-options.tsx index a8f483342..a57451778 100644 --- a/app/scripts/components/exploration/components/datasets/colormap-options.tsx +++ b/app/scripts/components/exploration/components/datasets/colormap-options.tsx @@ -10,6 +10,7 @@ import { import './colormap-options.scss'; import { ColorRangeSlider } from './colorRangeSlider'; +import { colorMapScale } from '$components/exploration/types.d.ts'; export const DEFAULT_COLORMAP = 'viridis'; @@ -51,6 +52,8 @@ interface ColormapOptionsProps { setColorMap: (colorMap: string) => void; min: number; max: number; + setColorMapScale: (colorMapScale: colorMapScale) => void; + colorMapScale: colorMapScale | undefined; } export const getColormapColors = ( @@ -79,7 +82,9 @@ export function ColormapOptions({ colorMap = DEFAULT_COLORMAP, min, max, - setColorMap + setColorMap, + setColorMapScale, + colorMapScale }: ColormapOptionsProps) { const initialIsReversed = colorMap.endsWith('_r'); const initialColorMap = normalizeColorMap(colorMap); @@ -154,7 +159,12 @@ export function ColormapOptions({
- console.log(`min = ${min}, max = ${max}`)} /> +
void; + colorMapScale:colorMapScale | undefined; + setColorMapScale: (colorMapScale: colorMapScale) => void; onClickLayerInfo: () => void; datasetLegend: LayerLegendCategorical | LayerLegendGradient | undefined; } @@ -104,7 +108,9 @@ const LegendColorMapTrigger = styled.div` `; // Hiding configurable map for now until Instances are ready to adapt it -const showConfigurableColorMap = checkEnvFlag(process.env.SHOW_CONFIGURABLE_COLOR_MAP); +const showConfigurableColorMap = checkEnvFlag( + process.env.SHOW_CONFIGURABLE_COLOR_MAP +); export default function DataLayerCard(props: CardProps) { const { @@ -114,6 +120,8 @@ export default function DataLayerCard(props: CardProps) { setVisible, colorMap, setColorMap, + colorMapScale, + setColorMapScale, datasetLegend, onClickLayerInfo } = props; @@ -132,9 +140,16 @@ export default function DataLayerCard(props: CardProps) { } }; - const showLoadingConfigurableCmapSkeleton = showConfigurableColorMap && dataset.status === 'loading' && datasetLegend?.type === 'gradient'; - const showConfigurableCmap = showConfigurableColorMap && dataset.status === 'success' && datasetLegend?.type === 'gradient'; - const showNonConfigurableCmap = !showConfigurableColorMap && datasetLegend?.type === 'gradient'; + const showLoadingConfigurableCmapSkeleton = + showConfigurableColorMap && + dataset.status === 'loading' && + datasetLegend?.type === 'gradient'; + const showConfigurableCmap = + showConfigurableColorMap && + dataset.status === 'success' && + datasetLegend?.type === 'gradient'; + const showNonConfigurableCmap = + !showConfigurableColorMap && datasetLegend?.type === 'gradient'; return ( <> @@ -158,7 +173,10 @@ export default function DataLayerCard(props: CardProps) { onPointerDownCapture={(e) => e.stopPropagation()} onClick={onClickLayerInfo} > - + setVisible((v) => !v)} > {isVisible ? ( - + ) : ( - + )} @@ -182,51 +206,66 @@ export default function DataLayerCard(props: CardProps) { {datasetLegend?.type === 'categorical' && ( - + )} - {/* Show a loading skeleton when the color map is not categorical and the dataset + {/* Show a loading skeleton when the color map is not categorical and the dataset status is 'loading'. This is because we color map sometimes might come from the titiler which could introduce a visual flash when going from the 'default' color map to the one configured in titiler */} - {showLoadingConfigurableCmapSkeleton &&
} - {showConfigurableCmap && ( -
- - + +
+ )} + {showConfigurableCmap && ( +
+ + - } - appendTo={() => document.body} - visible={isColorMapOpen} - interactive={true} - placement='top' - onClickOutside={(_, event) => handleClickOutside(event)} + colorMap={colorMap} + setColorMap={setColorMap} + setColorMapScale={setColorMapScale} + colorMapScale={colorMapScale} + /> + } + appendTo={() => document.body} + visible={isColorMapOpen} + interactive={true} + placement='top' + onClickOutside={(_, event) => handleClickOutside(event)} + > + - - - - -
- )} - {showNonConfigurableCmap && + + + +
+ )} + {showNonConfigurableCmap && ( } - + /> + )} ); diff --git a/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx b/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx index a80792c32..8c1d08441 100644 --- a/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx +++ b/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx @@ -33,7 +33,8 @@ import { useTimelineDatasetAtom, useTimelineDatasetColormap, useTimelineDatasetSettings, - useTimelineDatasetVisibility + useTimelineDatasetVisibility, + useTimelineDatasetColormapScale } from '$components/exploration/atoms/hooks'; import { useAnalysisController, @@ -103,6 +104,7 @@ export function DatasetListItem(props: DatasetListItemProps) { const [isVisible, setVisible] = useTimelineDatasetVisibility(datasetAtom); const [colorMap, setColorMap] = useTimelineDatasetColormap(datasetAtom); + const [colorMapScale, setColorMapScale]=useTimelineDatasetColormapScale(datasetAtom); const [modalLayerInfo, setModalLayerInfo] = React.useState(); const [, setSetting] = useTimelineDatasetSettings(datasetAtom); @@ -209,7 +211,7 @@ export function DatasetListItem(props: DatasetListItemProps) {
- +
{modalLayerInfo && ( Date: Wed, 9 Oct 2024 15:29:01 -0400 Subject: [PATCH 03/11] addressing ref errors --- .../exploration/components/datasets/colorRangeSlider.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx index 220427179..c26093b84 100644 --- a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -25,9 +25,6 @@ export function ColorRangeSlider({ colorMapScale, setColorMapScale }: ColorrangeRangeSlideProps) { - const fromInput = useRef(null); - const toInput = useRef(null); - const [minVal, setMinVal] = useState(min); const [maxVal, setMaxVal] = useState(max); const [inputError, setInputError] = useState({ min: false, max: false }); @@ -103,11 +100,10 @@ export function ColorRangeSlider({
Date: Thu, 10 Oct 2024 13:36:58 -0400 Subject: [PATCH 04/11] setting up color map rescale communication --- .../style-generators/raster-paint-layer.tsx | 25 +++++-- .../style-generators/raster-timeseries.tsx | 19 +++-- app/scripts/components/common/map/types.d.ts | 1 + .../components/datasets/colorRangeSlider.tsx | 75 ++++++++----------- .../exploration/components/map/layer.tsx | 6 +- 5 files changed, 66 insertions(+), 60 deletions(-) diff --git a/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx b/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx index bf5f170bf..653b1199d 100644 --- a/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx +++ b/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx @@ -13,6 +13,7 @@ interface RasterPaintLayerProps extends BaseGeneratorParams { colorMap?: string | undefined; tileParams: Record; generatorPrefix?: string; + scale?: { min: number; max: number }; } export function RasterPaintLayer(props: RasterPaintLayerProps) { @@ -24,7 +25,8 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) { hidden, opacity, colorMap, - generatorPrefix = 'raster', + scale, + generatorPrefix = 'raster' } = props; const { updateStyle } = useMapStyle(); @@ -32,8 +34,14 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) { const generatorId = `${generatorPrefix}-${id}`; const updatedTileParams = useMemo(() => { - return { ...tileParams, ...colorMap && {colormap_name: colorMap}}; - }, [tileParams, colorMap]); + return { + ...tileParams, + ...(colorMap && { + colormap_name: colorMap + }), + ...(scale && { rescale: Object.values(scale) }) + }; + }, [tileParams, colorMap, scale]); // // Generate Mapbox GL layers and sources for raster timeseries @@ -47,7 +55,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', @@ -63,8 +73,8 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) { paint: { 'raster-opacity': hidden ? 0 : rasterOpacity, 'raster-opacity-transition': { - duration: 320, - }, + duration: 320 + } }, minzoom: minZoom, metadata: { @@ -93,7 +103,8 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) { tileApiEndpoint, haveTileParamsChanged, generatorParams, - colorMap + colorMap, + scale // generatorParams includes hidden and opacity // hidden, // opacity, diff --git a/app/scripts/components/common/map/style-generators/raster-timeseries.tsx b/app/scripts/components/common/map/style-generators/raster-timeseries.tsx index 271bf74ac..f1099ef99 100644 --- a/app/scripts/components/common/map/style-generators/raster-timeseries.tsx +++ b/app/scripts/components/common/map/style-generators/raster-timeseries.tsx @@ -63,10 +63,10 @@ export function RasterTimeseries(props: RasterTimeseriesProps) { stacApiEndpoint, tileApiEndpoint, colorMap, + reScale } = props; const { current: mapInstance } = useMaps(); - const theme = useTheme(); const { updateStyle } = useMapStyle(); @@ -270,7 +270,9 @@ export function RasterTimeseries(props: RasterTimeseriesProps) { controller }); const mosaicUrl = responseData.links[1].href; - setMosaicUrl(mosaicUrl.replace('/{tileMatrixSetId}', '/WebMercatorQuad')); + setMosaicUrl( + mosaicUrl.replace('/{tileMatrixSetId}', '/WebMercatorQuad') + ); } catch (error) { // @NOTE: conditional logic TO BE REMOVED once new BE endpoints have moved to prod... Fallback on old request url if new endpoints error with nonexistance... if (error.request) { @@ -284,10 +286,14 @@ export function RasterTimeseries(props: RasterTimeseriesProps) { const mosaicUrl = responseData.links[1].href; setMosaicUrl(mosaicUrl); } else { - LOG && + LOG && /* eslint-disable-next-line no-console */ - console.log('Titiler /register %cEndpoint error', 'color: red;', error); - throw error; + console.log( + 'Titiler /register %cEndpoint error', + 'color: red;', + error + ); + throw error; } } @@ -361,7 +367,7 @@ export function RasterTimeseries(props: RasterTimeseriesProps) { { assets: 'cog_default', ...(sourceParams ?? {}), - ...colorMap && {colormap_name: colorMap} + ...(colorMap && { colormap_name: colorMap, rescale: Object.values(reScale) }) }, // Temporary solution to pass different tile parameters for hls data { @@ -489,6 +495,7 @@ export function RasterTimeseries(props: RasterTimeseriesProps) { }, [ mosaicUrl, colorMap, + reScale, points, minZoom, haveSourceParamsChanged, diff --git a/app/scripts/components/common/map/types.d.ts b/app/scripts/components/common/map/types.d.ts index 899931d39..47ad68c4f 100644 --- a/app/scripts/components/common/map/types.d.ts +++ b/app/scripts/components/common/map/types.d.ts @@ -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 }; } // export interface ZarrTimeseriesProps extends BaseTimeseriesProps { diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx index c26093b84..a49cb09ef 100644 --- a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -29,8 +29,12 @@ export function ColorRangeSlider({ const [maxVal, setMaxVal] = useState(max); const [inputError, setInputError] = useState({ min: false, max: false }); - const minValRef = useRef(colorMapScale?.min ? colorMapScale.min : min); - const maxValRef = useRef(colorMapScale?.max ? colorMapScale.max : max); + const minValRef = useRef( + String(colorMapScale?.min ? colorMapScale.min : min) + ); + const maxValRef = useRef( + String(colorMapScale?.max ? colorMapScale.max : max) + ); const range = useRef(null); const middleMarker = useRef(null); @@ -65,7 +69,6 @@ export function ColorRangeSlider({ const maxPercent = getPercent(maxVal); rangeCalculation(maxPercent, minPercent); } - if (minVal != minValPrevious) { minValPrevious = minVal; const minPercent = getPercent(minVal); @@ -76,22 +79,19 @@ export function ColorRangeSlider({ } if ( !colorMapScale || - colorMapScale.max == max || - colorMapScale.min == min + (colorMapScale.max == max && colorMapScale.min == min) ) { setColorMapScale({ min: minVal, max: maxVal }); - } + } else + setColorMapScale({ + min: Number(minValRef.current), + max: Number(maxValRef.current) + }); }, [maxVal, minVal, getPercent, setColorMapScale]); const textInputClasses = 'flex-1 radius-md height-3 font-size-3xs width-5 border-2px '; const thumbPosition = `position-absolute pointer-events width-card height-0 outline-0`; - - const dynamicStepIncrement = (max, min) => { - // determining numeric distance between min and max - const value = Math.abs(max - min); - const tenLog = Math.floor(Math.log(value) / Math.log(10)); - }; return (
@@ -112,18 +112,14 @@ export function ColorRangeSlider({ value={minValRef.current} onChange={(event) => { const value = Number(event.target.value); - if (value > maxVal - 0.01) return false; - if (value < min || value > max) { - return setInputError({ max: inputError.max, min: true }); - } - setInputError({ max: inputError.max, min: false }); - setMinVal(Math.min(value, minVal + 0.01)); - setColorMapScale({ - min: minValRef.current, - max: colorMapScale.max - }); - - return (minValRef.current = value); + minValRef.current = value; + setTimeout(() => { + if (value > maxVal - 0.001) return false; + if (value < min || value > max) { + return setInputError({ max: inputError.max, min: true }); + } else setInputError({ max: inputError.max, min: false }); + setMinVal(Math.min(value, maxVal - 0.001)); + }, 2500); }} /> @@ -136,15 +132,11 @@ export function ColorRangeSlider({ value={minValRef.current} onChange={(event) => { const value = Number(event.target.value); - setMinVal(Math.min(value, maxVal - 0.01)); + setMinVal(Math.min(value, maxVal - 0.001)); minValRef.current = value; - setColorMapScale({ - min: minValRef.current, - max: colorMapScale.max - }); }} className={`thumb ${thumbPosition} z-index-300`} - style={{ zIndex: minVal >= max - 10 * 0.01 ? '500' : '300' }} + style={{ zIndex: minVal >= max - 10 * 0.001 ? '500' : '300' }} /> { - setMaxVal(Math.max(Number(event.target.value), minVal + 0.01)); - maxValRef.current = Number(event.target.value); - console.log('maxValRef.current', maxValRef.current); + const value = Number(event.target.value); - setColorMapScale({ - min: colorMapScale.min, - max: maxValRef.current - }); + setMaxVal(Math.max(value, minVal + 0.001)); + maxValRef.current = value; }} className={`thumb ${thumbPosition} z-400`} - style={{ zIndex: minVal <= max - 10 * 0.01 ? '500' : '400' }} + style={{ zIndex: minVal <= max - 10 * 0.001 ? '500' : '400' }} />
@@ -182,6 +170,7 @@ export function ColorRangeSlider({
{ const value = Number(event.target.value); - if (value < minVal + 0.01) return false; + if (value < minVal + 0.001) return false; if (value < min || value > max) { return setInputError({ max: true, min: inputError.min }); } else { setInputError({ max: false, min: inputError.min }); - setMaxVal(Math.max(value, minVal + 0.01)); - setColorMapScale({ - min: colorMapScale.min, - max: maxValRef.current - }); - return (maxValRef.current = value); + setMaxVal(Math.max(value, minVal + 0.001)); + maxValRef.current = event.target.value; } }} /> diff --git a/app/scripts/components/exploration/components/map/layer.tsx b/app/scripts/components/exploration/components/map/layer.tsx index dfc9c87b6..d183c3673 100644 --- a/app/scripts/components/exploration/components/map/layer.tsx +++ b/app/scripts/components/exploration/components/map/layer.tsx @@ -22,7 +22,7 @@ interface LayerProps { export function Layer(props: LayerProps) { const { id: layerId, dataset, order, selectedDay, onStatusChange } = props; - const { isVisible, opacity, colorMap } = dataset.settings; + const { isVisible, opacity, colorMap, scale } = dataset.settings; // The date needs to match the dataset's time density. const relevantDate = useMemo( @@ -40,7 +40,6 @@ export function Layer(props: LayerProps) { }; return resolveConfigFunctions(dataset.data, bag); }, [dataset, relevantDate]); - switch (dataset.data.type) { case 'vector': return ( @@ -72,6 +71,7 @@ export function Layer(props: LayerProps) { opacity={opacity} onStatusChange={onStatusChange} colorMap={colorMap} + reScale={scale} /> ); case 'cmr': @@ -88,6 +88,7 @@ export function Layer(props: LayerProps) { opacity={opacity} onStatusChange={onStatusChange} colorMap={colorMap} + reScale={scale} /> ); case 'raster': @@ -105,6 +106,7 @@ export function Layer(props: LayerProps) { opacity={opacity} onStatusChange={onStatusChange} colorMap={colorMap} + reScale={scale} /> ); default: From 8e557f90b40a987986e9cc5ba015746cb212e9ce Mon Sep 17 00:00:00 2001 From: snmln Date: Thu, 10 Oct 2024 14:35:45 -0400 Subject: [PATCH 05/11] correcting CMR layer error --- .../common/map/style-generators/raster-paint-layer.tsx | 10 +++++----- .../common/map/style-generators/raster-timeseries.tsx | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx b/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx index 653b1199d..e5aa8479d 100644 --- a/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx +++ b/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx @@ -13,7 +13,7 @@ interface RasterPaintLayerProps extends BaseGeneratorParams { colorMap?: string | undefined; tileParams: Record; generatorPrefix?: string; - scale?: { min: number; max: number }; + reScale?: { min: number; max: number }; } export function RasterPaintLayer(props: RasterPaintLayerProps) { @@ -25,7 +25,7 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) { hidden, opacity, colorMap, - scale, + reScale, generatorPrefix = 'raster' } = props; @@ -39,9 +39,9 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) { ...(colorMap && { colormap_name: colorMap }), - ...(scale && { rescale: Object.values(scale) }) + ...(reScale && { rescale: Object.values(reScale) }) }; - }, [tileParams, colorMap, scale]); + }, [tileParams, colorMap, reScale]); // // Generate Mapbox GL layers and sources for raster timeseries @@ -104,7 +104,7 @@ export function RasterPaintLayer(props: RasterPaintLayerProps) { haveTileParamsChanged, generatorParams, colorMap, - scale + reScale // generatorParams includes hidden and opacity // hidden, // opacity, diff --git a/app/scripts/components/common/map/style-generators/raster-timeseries.tsx b/app/scripts/components/common/map/style-generators/raster-timeseries.tsx index f1099ef99..d0bd548c8 100644 --- a/app/scripts/components/common/map/style-generators/raster-timeseries.tsx +++ b/app/scripts/components/common/map/style-generators/raster-timeseries.tsx @@ -367,7 +367,8 @@ export function RasterTimeseries(props: RasterTimeseriesProps) { { assets: 'cog_default', ...(sourceParams ?? {}), - ...(colorMap && { colormap_name: colorMap, rescale: Object.values(reScale) }) + ...(colorMap && { colormap_name: colorMap }), + ...(reScale && {rescale: Object.values(reScale)}) }, // Temporary solution to pass different tile parameters for hls data { From 67e9cf137af61b00da69ad20cf73499209896b41 Mon Sep 17 00:00:00 2001 From: snmln Date: Mon, 14 Oct 2024 14:35:55 -0400 Subject: [PATCH 06/11] correcting input error handling --- .../components/datasets/colorRangeSlider.tsx | 137 ++++++++++++------ 1 file changed, 94 insertions(+), 43 deletions(-) diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx index a49cb09ef..ac475e820 100644 --- a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -27,13 +27,18 @@ export function ColorRangeSlider({ }: ColorrangeRangeSlideProps) { const [minVal, setMinVal] = useState(min); const [maxVal, setMaxVal] = useState(max); - const [inputError, setInputError] = useState({ min: false, max: false }); + const [inputError, setInputError] = useState({ + min: false, + max: false, + largerThanMax: false, + lessThanMin: false + }); - const minValRef = useRef( - String(colorMapScale?.min ? colorMapScale.min : min) + const minValRef = useRef( + colorMapScale?.min ? colorMapScale.min : min ); - const maxValRef = useRef( - String(colorMapScale?.max ? colorMapScale.max : max) + const maxValRef = useRef( + colorMapScale?.max ? colorMapScale.max : max ); const range = useRef(null); const middleMarker = useRef(null); @@ -44,39 +49,51 @@ export function ColorRangeSlider({ [min, max] ); const rangeCalculation = (maxPercent, minPercent) => { - range.current.style.width = `${ - maxPercent - minPercent >= 100 ? 100 : maxPercent - minPercent - }%`; + if (range.current) { + range.current.style.width = `${ + maxPercent - minPercent >= 100 ? 100 : maxPercent - minPercent + }%`; + } if (middleMarker.current) middleMarker.current.style.left = `${range.current.style.width}%`; return; }; + // Set width of the range to decrease from the right side useEffect(() => { let maxValPrevious; let minValPrevious; - if (colorMapScale && maxVal != maxValPrevious && minVal != minValPrevious) { - const minPercent = getPercent(minValRef.current); - const maxPercent = getPercent(maxValRef.current); - rangeCalculation(maxPercent, minPercent); - if (range.current) range.current.style.left = `${minPercent}%`; - } else { - if (maxVal != maxValPrevious) { - maxValPrevious = maxVal; + if (Object.values(inputError).every((v) => v === false)) { + if ( + colorMapScale && + maxVal != maxValPrevious && + minVal != minValPrevious + ) { const minPercent = getPercent(minValRef.current); - const maxPercent = getPercent(maxVal); - rangeCalculation(maxPercent, minPercent); - } - if (minVal != minValPrevious) { - minValPrevious = minVal; - const minPercent = getPercent(minVal); const maxPercent = getPercent(maxValRef.current); + rangeCalculation(maxPercent, minPercent); + if (range.current) range.current.style.left = `${minPercent}%`; + } else { + if (maxVal != maxValPrevious) { + maxValPrevious = maxVal; + const minPercent = getPercent(minValRef.current); + const maxPercent = getPercent(maxVal); + rangeCalculation(maxPercent, minPercent); + } + if (minVal != minValPrevious) { + minValPrevious = minVal; + const minPercent = getPercent(minVal); + const maxPercent = getPercent(maxValRef.current); + rangeCalculation(maxPercent, minPercent); + if (range.current) range.current.style.left = `${minPercent}%`; + } } } + if ( !colorMapScale || (colorMapScale.max == max && colorMapScale.min == min) @@ -87,8 +104,15 @@ export function ColorRangeSlider({ min: Number(minValRef.current), max: Number(maxValRef.current) }); - }, [maxVal, minVal, getPercent, setColorMapScale]); + }, [maxVal, minVal, getPercent, setColorMapScale, inputError]); + const resetErrorOnSlide = (value, slider) => { + if (value > min || value < max) { + slider === 'max' + ? setInputError({ ...inputError, max: false, lessThanMin: false }) + : setInputError({ ...inputError, min: false, largerThanMax: false }); + } + }; const textInputClasses = 'flex-1 radius-md height-3 font-size-3xs width-5 border-2px '; const thumbPosition = `position-absolute pointer-events width-card height-0 outline-0`; @@ -105,21 +129,27 @@ export function ColorRangeSlider({ name='min' placeholder={minValRef.current} className={`${textInputClasses} ${ - inputError.min + inputError.min || inputError.largerThanMax ? 'border-secondary-vivid text-secondary-vivid' : ' border-base-light' }`} value={minValRef.current} onChange={(event) => { + minValRef.current = event.target.value; const value = Number(event.target.value); - minValRef.current = value; - setTimeout(() => { - if (value > maxVal - 0.001) return false; - if (value < min || value > max) { - return setInputError({ max: inputError.max, min: true }); - } else setInputError({ max: inputError.max, min: false }); + + if (value > maxVal - 0.001) + return setInputError({ ...inputError, largerThanMax: true }); + if (value < min || value > max) { + return setInputError({ ...inputError, min: true }); + } else { + setInputError({ + ...inputError, + min: false, + largerThanMax: false + }); setMinVal(Math.min(value, maxVal - 0.001)); - }, 2500); + } }} /> @@ -129,10 +159,14 @@ export function ColorRangeSlider({ min={min} max={max} step='.001' - value={minValRef.current} + value={minVal} onChange={(event) => { - const value = Number(event.target.value); - setMinVal(Math.min(value, maxVal - 0.001)); + const value = Math.min( + Number(event.target.value), + maxVal - 0.001 + ); + resetErrorOnSlide(value, 'min'); + setMinVal(value); minValRef.current = value; }} className={`thumb ${thumbPosition} z-index-300`} @@ -143,11 +177,14 @@ export function ColorRangeSlider({ min={min} step='.001' max={max} - value={maxValRef.current} + value={maxVal} onChange={(event) => { - const value = Number(event.target.value); - - setMaxVal(Math.max(value, minVal + 0.001)); + const value = Math.max( + Number(event.target.value), + minVal + 0.001 + ); + resetErrorOnSlide(value, 'max'); + setMaxVal(value); maxValRef.current = value; }} className={`thumb ${thumbPosition} z-400`} @@ -175,20 +212,24 @@ export function ColorRangeSlider({ name='max' placeholder={maxValRef.current} className={`${textInputClasses} ${ - inputError.max + inputError.max || inputError.lessThanMin ? 'border-secondary-vivid text-secondary-vivid' : ' border-base-light' }`} value={maxValRef.current} onChange={(event) => { const value = Number(event.target.value); - if (value < minVal + 0.001) return false; + maxValRef.current = event.target.value; + + if (value < minVal + 0.001) + return setInputError({ ...inputError, lessThanMin: true }); + if (value < min || value > max) { - return setInputError({ max: true, min: inputError.min }); + return setInputError({ ...inputError, max: true }); } else { - setInputError({ max: false, min: inputError.min }); + setInputError({ ...inputError, max: false, lessThanMin: false }); setMaxVal(Math.max(value, minVal + 0.001)); - maxValRef.current = event.target.value; + // maxValRef.current = event.target.value; } }} /> @@ -197,6 +238,16 @@ export function ColorRangeSlider({

Please enter a value between {min} and {max}

+ ) : null}{' '} + {inputError.largerThanMax ? ( +

+ Please enter a value less than {maxValRef.current} +

+ ) : null} + {inputError.lessThanMin ? ( +

+ Please enter a value larger than {minValRef.current} +

) : null}
); From b488f3d21ba35db7183d8af8910bc6232ea895ea Mon Sep 17 00:00:00 2001 From: snmln Date: Mon, 14 Oct 2024 15:49:30 -0400 Subject: [PATCH 07/11] cleaning up file --- .../components/datasets/colorRangeSlider.tsx | 74 +++++++++++-------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx index ac475e820..676166e00 100644 --- a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -25,8 +25,12 @@ export function ColorRangeSlider({ colorMapScale, setColorMapScale }: ColorrangeRangeSlideProps) { - const [minVal, setMinVal] = useState(min); - const [maxVal, setMaxVal] = useState(max); + const [minVal, setMinVal] = useState( + colorMapScale?.min ? colorMapScale.min : min + ); + const [maxVal, setMaxVal] = useState( + colorMapScale?.min ? colorMapScale.max : max + ); const [inputError, setInputError] = useState({ min: false, max: false, @@ -40,32 +44,44 @@ export function ColorRangeSlider({ const maxValRef = useRef( colorMapScale?.max ? colorMapScale.max : max ); - const range = useRef(null); - const middleMarker = useRef(null); + const range = useRef(null); + const middleMarker = useRef(null); // Convert to percentage const getPercent = useCallback( (value) => Math.round(((value - min) / (max - min)) * 100), [min, max] ); + //Calculate the range const rangeCalculation = (maxPercent, minPercent) => { if (range.current) { range.current.style.width = `${ maxPercent - minPercent >= 100 ? 100 : maxPercent - minPercent }%`; + if (middleMarker.current) + middleMarker.current.style.left = `${range.current.style.width}%`; } - if (middleMarker.current) - middleMarker.current.style.left = `${range.current.style.width}%`; return; }; + const resetErrorOnSlide = (value, slider) => { + if (value > min || value < max) { + slider === 'max' + ? setInputError({ ...inputError, max: false, lessThanMin: false }) + : setInputError({ ...inputError, min: false, largerThanMax: false }); + } + }; - // Set width of the range to decrease from the right side + const minMaxBuffer = 0.001; + const textInputClasses = + 'flex-1 radius-md height-3 font-size-3xs width-5 border-2px '; + const thumbPosition = `position-absolute pointer-events width-card height-0 outline-0`; useEffect(() => { let maxValPrevious; let minValPrevious; - - if (Object.values(inputError).every((v) => v === false)) { + //checking that there are no current errors with inputs + if (Object.values(inputError).every((error) => !error)) { + //set the filled range bar on initial load if ( colorMapScale && maxVal != maxValPrevious && @@ -78,12 +94,14 @@ export function ColorRangeSlider({ if (range.current) range.current.style.left = `${minPercent}%`; } else { + //set the filled range bar if change to max slider if (maxVal != maxValPrevious) { maxValPrevious = maxVal; const minPercent = getPercent(minValRef.current); const maxPercent = getPercent(maxVal); rangeCalculation(maxPercent, minPercent); } + //set the filled range bar if change to min slider if (minVal != minValPrevious) { minValPrevious = minVal; const minPercent = getPercent(minVal); @@ -104,18 +122,8 @@ export function ColorRangeSlider({ min: Number(minValRef.current), max: Number(maxValRef.current) }); - }, [maxVal, minVal, getPercent, setColorMapScale, inputError]); + }, [maxVal, minVal, getPercent, setColorMapScale, inputError, max, min]); - const resetErrorOnSlide = (value, slider) => { - if (value > min || value < max) { - slider === 'max' - ? setInputError({ ...inputError, max: false, lessThanMin: false }) - : setInputError({ ...inputError, min: false, largerThanMax: false }); - } - }; - const textInputClasses = - 'flex-1 radius-md height-3 font-size-3xs width-5 border-2px '; - const thumbPosition = `position-absolute pointer-events width-card height-0 outline-0`; return (
@@ -138,7 +146,7 @@ export function ColorRangeSlider({ minValRef.current = event.target.value; const value = Number(event.target.value); - if (value > maxVal - 0.001) + if (value > maxVal - minMaxBuffer) return setInputError({ ...inputError, largerThanMax: true }); if (value < min || value > max) { return setInputError({ ...inputError, min: true }); @@ -148,7 +156,7 @@ export function ColorRangeSlider({ min: false, largerThanMax: false }); - setMinVal(Math.min(value, maxVal - 0.001)); + setMinVal(Math.min(value, maxVal - minMaxBuffer)); } }} /> @@ -163,14 +171,16 @@ export function ColorRangeSlider({ onChange={(event) => { const value = Math.min( Number(event.target.value), - maxVal - 0.001 + maxVal - minMaxBuffer ); resetErrorOnSlide(value, 'min'); setMinVal(value); minValRef.current = value; }} className={`thumb ${thumbPosition} z-index-300`} - style={{ zIndex: minVal >= max - 10 * 0.001 ? '500' : '300' }} + style={{ + zIndex: minVal >= max - 10 * minMaxBuffer ? '500' : '300' + }} /> { const value = Math.max( Number(event.target.value), - minVal + 0.001 + minVal + minMaxBuffer ); resetErrorOnSlide(value, 'max'); setMaxVal(value); maxValRef.current = value; }} className={`thumb ${thumbPosition} z-400`} - style={{ zIndex: minVal <= max - 10 * 0.001 ? '500' : '400' }} + style={{ + zIndex: minVal <= max - 10 * minMaxBuffer ? '500' : '400' + }} />
@@ -196,6 +208,7 @@ export function ColorRangeSlider({ ref={range} className='slider__range display-flex flex-align-center flex-justify-center radius-md position-absolute height-05 z-200' > + {/* Show divergent map middle point */} {min < 0 ? (
max) { return setInputError({ ...inputError, max: true }); } else { + //unsetting error setInputError({ ...inputError, max: false, lessThanMin: false }); - setMaxVal(Math.max(value, minVal + 0.001)); - // maxValRef.current = event.target.value; + setMaxVal(Math.max(value, minVal + minMaxBuffer)); } }} /> + {/* error message for min input that is outside min max of color map */} {inputError.max || inputError.min ? (

Please enter a value between {min} and {max}

) : null}{' '} + {/* error message for min input that is larger than current max */} {inputError.largerThanMax ? (

Please enter a value less than {maxValRef.current}

) : null} + {/* error message for min input that is less than current min */} {inputError.lessThanMin ? (

Please enter a value larger than {minValRef.current} From 0e865aa3f6648b8e9815ac0f38c2c3c6596576c2 Mon Sep 17 00:00:00 2001 From: snmln Date: Tue, 15 Oct 2024 10:55:55 -0400 Subject: [PATCH 08/11] adjusting naming to BEM --- .../components/datasets/color-range-slider.scss | 7 +++++-- .../exploration/components/datasets/colorRangeSlider.tsx | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/scripts/components/exploration/components/datasets/color-range-slider.scss b/app/scripts/components/exploration/components/datasets/color-range-slider.scss index a713e291b..6a757daf6 100644 --- a/app/scripts/components/exploration/components/datasets/color-range-slider.scss +++ b/app/scripts/components/exploration/components/datasets/color-range-slider.scss @@ -1,3 +1,4 @@ + .slider__track { background-color: #dddfe2; } @@ -9,6 +10,8 @@ /* Removing the default appearance */ .thumb, .thumb::-webkit-slider-thumb { + touch-action: 'none'; + -webkit-appearance: none; -webkit-tap-highlight-color: transparent; } @@ -16,8 +19,8 @@ .thumb { pointer-events: none; } -.middle_marker{ - background-color: #1B2631; +.middle-marker { + background-color: #1b2631; } /* For Chrome browsers */ .thumb::-webkit-slider-thumb { diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx index 676166e00..4a4263b89 100644 --- a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -212,7 +212,7 @@ export function ColorRangeSlider({ {min < 0 ? (

) : null}
From 4e34c7d12a80ae000b0e4bdef9631e0747844f8a Mon Sep 17 00:00:00 2001 From: snmln Date: Tue, 15 Oct 2024 13:53:42 -0400 Subject: [PATCH 09/11] Adding comment --- .../exploration/components/datasets/colorRangeSlider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx index 4a4263b89..29a42acf2 100644 --- a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -111,7 +111,7 @@ export function ColorRangeSlider({ } } } - + // determining if there is an initial colorMapeScale or if it is the default min and max if ( !colorMapScale || (colorMapScale.max == max && colorMapScale.min == min) From 13e6acf80b4bbb712c30d4da810b5313b0132759 Mon Sep 17 00:00:00 2001 From: snmln Date: Thu, 17 Oct 2024 16:28:37 -0400 Subject: [PATCH 10/11] removing unnecessary styling --- .../components/datasets/color-range-slider.scss | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/scripts/components/exploration/components/datasets/color-range-slider.scss b/app/scripts/components/exploration/components/datasets/color-range-slider.scss index 6a757daf6..d66d2e815 100644 --- a/app/scripts/components/exploration/components/datasets/color-range-slider.scss +++ b/app/scripts/components/exploration/components/datasets/color-range-slider.scss @@ -1,12 +1,3 @@ - -.slider__track { - background-color: #dddfe2; -} - -.slider__range { - background-color: #1565ef; -} - /* Removing the default appearance */ .thumb, .thumb::-webkit-slider-thumb { @@ -19,9 +10,6 @@ .thumb { pointer-events: none; } -.middle-marker { - background-color: #1b2631; -} /* For Chrome browsers */ .thumb::-webkit-slider-thumb { -webkit-appearance: none; From fa9a363041d971c5c747bde85fb1a0d1ab3b4236 Mon Sep 17 00:00:00 2001 From: snmln Date: Thu, 17 Oct 2024 16:29:37 -0400 Subject: [PATCH 11/11] Implementing feedback. --- .../components/datasets/colorRangeSlider.tsx | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx index 29a42acf2..835e5b42a 100644 --- a/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx +++ b/app/scripts/components/exploration/components/datasets/colorRangeSlider.tsx @@ -25,12 +25,13 @@ export function ColorRangeSlider({ colorMapScale, setColorMapScale }: ColorrangeRangeSlideProps) { - const [minVal, setMinVal] = useState( - colorMapScale?.min ? colorMapScale.min : min - ); - const [maxVal, setMaxVal] = useState( - colorMapScale?.min ? colorMapScale.max : max - ); + const setDefaultMin = colorMapScale?.min ? colorMapScale.min : min; + const setDefaultMax = colorMapScale?.max ? colorMapScale.max : max; + + const [minVal, setMinVal] = useState(setDefaultMin); + const [maxVal, setMaxVal] = useState(setDefaultMax); + const minValRef = useRef(setDefaultMin); + const maxValRef = useRef(setDefaultMax); const [inputError, setInputError] = useState({ min: false, max: false, @@ -38,28 +39,20 @@ export function ColorRangeSlider({ lessThanMin: false }); - const minValRef = useRef( - colorMapScale?.min ? colorMapScale.min : min - ); - const maxValRef = useRef( - colorMapScale?.max ? colorMapScale.max : max - ); const range = useRef(null); - const middleMarker = useRef(null); // Convert to percentage const getPercent = useCallback( - (value) => Math.round(((value - min) / (max - min)) * 100), + (value) => ((value - min) * 100) / (max - min), [min, max] ); //Calculate the range const rangeCalculation = (maxPercent, minPercent) => { + const thumbWidth = 20; if (range.current) { - range.current.style.width = `${ + range.current.style.width = `calc(${ maxPercent - minPercent >= 100 ? 100 : maxPercent - minPercent - }%`; - if (middleMarker.current) - middleMarker.current.style.left = `${range.current.style.width}%`; + }% - ${(thumbWidth - minPercent * 0.2) * (maxPercent / 100)}px )`; } return; }; @@ -92,7 +85,10 @@ export function ColorRangeSlider({ rangeCalculation(maxPercent, minPercent); - if (range.current) range.current.style.left = `${minPercent}%`; + if (range.current) + range.current.style.left = `calc(${minPercent}% + ${ + 10 - minPercent * 0.2 + }px)`; } else { //set the filled range bar if change to max slider if (maxVal != maxValPrevious) { @@ -107,7 +103,10 @@ export function ColorRangeSlider({ const minPercent = getPercent(minVal); const maxPercent = getPercent(maxValRef.current); rangeCalculation(maxPercent, minPercent); - if (range.current) range.current.style.left = `${minPercent}%`; + if (range.current) + range.current.style.left = `calc(${minPercent}% + ${ + 10 - minPercent * 0.2 + }px)`; } } } @@ -121,7 +120,7 @@ export function ColorRangeSlider({ setColorMapScale({ min: Number(minValRef.current), max: Number(maxValRef.current) - }); + }); /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [maxVal, minVal, getPercent, setColorMapScale, inputError, max, min]); return ( @@ -142,6 +141,9 @@ export function ColorRangeSlider({ : ' border-base-light' }`} value={minValRef.current} + onBlur={(event) => { + if (event.target.value == '') return (minValRef.current = minVal); + }} onChange={(event) => { minValRef.current = event.target.value; const value = Number(event.target.value); @@ -177,7 +179,7 @@ export function ColorRangeSlider({ setMinVal(value); minValRef.current = value; }} - className={`thumb ${thumbPosition} z-index-300`} + className={`thumb ${thumbPosition} z-index-30`} style={{ zIndex: minVal >= max - 10 * minMaxBuffer ? '500' : '300' }} @@ -188,6 +190,9 @@ export function ColorRangeSlider({ step='.001' max={max} value={maxVal} + onBlur={(event) => { + if (event.target.value == '') return (maxValRef.current = maxVal); + }} onChange={(event) => { const value = Math.max( Number(event.target.value), @@ -203,17 +208,14 @@ export function ColorRangeSlider({ }} />
-
+
{/* Show divergent map middle point */} {min < 0 ? ( -
+
) : null}