Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import { Button } from '@jupyterlab/ui-components';
import React, { useEffect, useState } from 'react';

import { LoadingIcon } from '@/src/shared/components/loading';
import { ClassificationMode } from '@/src/types';
import CanvasSelectComponent from './CanvasSelectComponent';
import ModeSelectRow from './ModeSelectRow';

interface IColorRampProps {
modeOptions: string[];
modeOptions: ClassificationMode[];
layerParams: IDict;
classifyFunc: (
selectedMode: string,
numberOfShades: string,
selectedMode: ClassificationMode | undefined,
numberOfShades: number | undefined,
selectedRamp: string,
setIsLoading: (isLoading: boolean) => void,
) => void;
Expand All @@ -21,8 +22,12 @@ interface IColorRampProps {

export type ColorRampOptions = {
selectedRamp: string;
numberOfShades: string;
selectedMode: string;
numberOfShades: number | undefined;
selectedMode: ClassificationMode | undefined;
};

const isValidNumberOfShades = (value: number | undefined) => {
return value !== undefined && !isNaN(value) && value > 0;
};

const ColorRamp: React.FC<IColorRampProps> = ({
Expand All @@ -33,12 +38,18 @@ const ColorRamp: React.FC<IColorRampProps> = ({
showRampSelector,
}) => {
const [selectedRamp, setSelectedRamp] = useState('');
const [selectedMode, setSelectedMode] = useState('');
const [numberOfShades, setNumberOfShades] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [selectedMode, setSelectedMode] = useState<
ClassificationMode | undefined
>();
const [numberOfShades, setNumberOfShades] = useState<number | undefined>();
const [isLoading, setIsLoading] = useState<boolean>(false);

useEffect(() => {
if (selectedRamp === '' && selectedMode === '' && numberOfShades === '') {
if (
selectedRamp === '' &&
selectedMode === undefined &&
numberOfShades === undefined
) {
populateOptions();
}
}, [layerParams]);
Expand All @@ -51,8 +62,8 @@ const ColorRamp: React.FC<IColorRampProps> = ({
singleBandMode = layerParams.symbologyState.mode;
colorRamp = layerParams.symbologyState.colorRamp;
}
setNumberOfShades(nClasses ? nClasses : '9');
setSelectedMode(singleBandMode ? singleBandMode : 'equal interval');
setNumberOfShades(nClasses ? nClasses : 9);
setSelectedMode((singleBandMode as ClassificationMode) ?? 'equal interval');
setSelectedRamp(colorRamp ? colorRamp : 'viridis');
};

Expand Down Expand Up @@ -81,6 +92,7 @@ const ColorRamp: React.FC<IColorRampProps> = ({
) : (
<Button
className="jp-Dialog-button jp-mod-accept jp-mod-styled"
disabled={!isValidNumberOfShades(numberOfShades)}
onClick={() =>
classifyFunc(
selectedMode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from 'react';

import { ClassificationMode } from '@/src/types';
interface IModeSelectRowProps {
numberOfShades: string;
setNumberOfShades: (value: string) => void;
selectedMode: string;
setSelectedMode: (value: string) => void;
modeOptions: string[];
numberOfShades: number | undefined;
setNumberOfShades: React.Dispatch<React.SetStateAction<number | undefined>>;
selectedMode: ClassificationMode | undefined;
setSelectedMode: React.Dispatch<
React.SetStateAction<ClassificationMode | undefined>
>;
modeOptions: ClassificationMode[];
}
const ModeSelectRow: React.FC<IModeSelectRowProps> = ({
numberOfShades,
Expand All @@ -21,8 +25,11 @@ const ModeSelectRow: React.FC<IModeSelectRowProps> = ({
className="jp-mod-styled"
name="class-number-input"
type="number"
value={selectedMode === 'continuous' ? 52 : numberOfShades}
onChange={event => setNumberOfShades(event.target.value)}
value={selectedMode === 'continuous' ? 52 : (numberOfShades ?? '')}
onChange={event => {
const value = event.target.value;
setNumberOfShades(value === '' ? undefined : Number(value));
}}
disabled={selectedMode === 'continuous'}
/>
</div>
Expand All @@ -34,10 +41,12 @@ const ModeSelectRow: React.FC<IModeSelectRowProps> = ({
id="mode-select"
className="jp-mod-styled"
value={selectedMode}
onChange={event => setSelectedMode(event.target.value)}
onChange={event =>
setSelectedMode(event.target.value as ClassificationMode)
}
>
{modeOptions.map(mode => (
<option key={mode} value={mode} selected={selectedMode === mode}>
<option key={mode} value={mode}>
{mode}
</option>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Utils } from '@/src/dialogs/symbology/symbologyUtils';
import BandRow from '@/src/dialogs/symbology/tiff_layer/components/BandRow';
import { LoadingOverlay } from '@/src/shared/components/loading';
import { GlobalStateDbManager } from '@/src/store';
import { ClassificationMode } from '@/src/types';

export type InterpolationType = 'discrete' | 'linear' | 'exact';

Expand All @@ -38,7 +39,11 @@ const SingleBandPseudoColor: React.FC<ISymbologyDialogProps> = ({
}

const functions = ['discrete', 'linear', 'exact'];
const modeOptions = ['continuous', 'equal interval', 'quantile'];
const modeOptions = [
'continuous',
'equal interval',
'quantile',
] as const satisfies ClassificationMode[];

const stateDb = GlobalStateDbManager.getInstance().getStateDb();

Expand Down Expand Up @@ -282,8 +287,8 @@ const SingleBandPseudoColor: React.FC<ISymbologyDialogProps> = ({
};

const buildColorInfoFromClassification = async (
selectedMode: string,
numberOfShades: string,
selectedMode: ClassificationMode | undefined,
numberOfShades: number | undefined,
selectedRamp: string,
setIsLoading: (isLoading: boolean) => void,
) => {
Expand All @@ -299,7 +304,8 @@ const SingleBandPseudoColor: React.FC<ISymbologyDialogProps> = ({
const currentBand = bandRows[selectedBand - 1];
const source = model.getSource(layer?.parameters?.source);
const sourceInfo = source?.parameters?.urls[0];
const nClasses = selectedMode === 'continuous' ? 52 : +numberOfShades;
const nClasses =
selectedMode === 'continuous' ? 52 : (numberOfShades as number);

setIsLoading(true);
switch (selectedMode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@/src/dialogs/symbology/symbologyDialog';
import { Utils, VectorUtils } from '@/src/dialogs/symbology/symbologyUtils';
import ValueSelect from '@/src/dialogs/symbology/vector_layer/components/ValueSelect';
import { SymbologyTab } from '@/src/types';
import { SymbologyTab, ClassificationMode } from '@/src/types';

const Categorized: React.FC<ISymbologyTabbedDialogWithAttributesProps> = ({
model,
Expand Down Expand Up @@ -117,8 +117,8 @@ const Categorized: React.FC<ISymbologyTabbedDialogWithAttributesProps> = ({
}, [selectedAttribute, stopRows, colorRampOptions]);

const buildColorInfoFromClassification = (
selectedMode: string,
numberOfShades: string,
selectedMode: ClassificationMode | undefined,
numberOfShades: number | undefined,
selectedRamp: string,
setIsLoading: (isLoading: boolean) => void,
) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@/src/dialogs/symbology/symbologyDialog';
import { Utils, VectorUtils } from '@/src/dialogs/symbology/symbologyUtils';
import ValueSelect from '@/src/dialogs/symbology/vector_layer/components/ValueSelect';
import { ClassificationMode } from '@/src/types';

const Graduated: React.FC<ISymbologyTabbedDialogWithAttributesProps> = ({
model,
Expand All @@ -29,7 +30,7 @@ const Graduated: React.FC<ISymbologyTabbedDialogWithAttributesProps> = ({
'jenks',
'pretty',
'logarithmic',
];
] as const satisfies ClassificationMode[];

const selectableAttributeRef = useRef<string>();
const symbologyTabRef = useRef<string>();
Expand Down Expand Up @@ -215,8 +216,8 @@ const Graduated: React.FC<ISymbologyTabbedDialogWithAttributesProps> = ({
};

const buildColorInfoFromClassification = (
selectedMode: string,
numberOfShades: string,
selectedMode: ClassificationMode | undefined,
numberOfShades: number | undefined,
selectedRamp: string,
) => {
setColorRampOptions({
Expand All @@ -233,31 +234,31 @@ const Graduated: React.FC<ISymbologyTabbedDialogWithAttributesProps> = ({
case 'quantile':
stops = VectorClassifications.calculateQuantileBreaks(
values,
+numberOfShades,
numberOfShades as number,
);
break;
case 'equal interval':
stops = VectorClassifications.calculateEqualIntervalBreaks(
values,
+numberOfShades,
numberOfShades as number,
);
break;
case 'jenks':
stops = VectorClassifications.calculateJenksBreaks(
values,
+numberOfShades,
numberOfShades as number,
);
break;
case 'pretty':
stops = VectorClassifications.calculatePrettyBreaks(
values,
+numberOfShades,
numberOfShades as number,
);
break;
case 'logarithmic':
stops = VectorClassifications.calculateLogarithmicBreaks(
values,
+numberOfShades,
numberOfShades as number,
);
break;
default:
Expand All @@ -271,7 +272,7 @@ const Graduated: React.FC<ISymbologyTabbedDialogWithAttributesProps> = ({
: Utils.getValueColorPairs(
stops,
selectedRamp,
+numberOfShades,
numberOfShades as number,
reverseRamp,
);

Expand Down
11 changes: 11 additions & 0 deletions packages/base/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,14 @@ declare global {
jupytergisMaps: { [name: string]: Map };
}
}

const classificationModes = [
'quantile',
'equal interval',
'jenks',
'pretty',
'logarithmic',
'continuous',
] as const;

export type ClassificationMode = (typeof classificationModes)[number];
Loading