Skip to content

Commit 7990d39

Browse files
authored
Merge pull request #1954 from silx-kit/fix-ratio-toggle
Fix keep ratio not toggling after applying suggestion in NX Heatmap
2 parents cd75d72 + 4600aee commit 7990d39

File tree

13 files changed

+159
-171
lines changed

13 files changed

+159
-171
lines changed

packages/app/src/vis-packs/core/heatmap/HeatmapToolbar.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,22 @@ function HeatmapToolbar(props: Props) {
4545
const {
4646
customDomain,
4747
colorMap,
48+
invertColorMap,
4849
scaleType,
4950
complexVisType,
50-
keepRatio,
5151
showGrid,
52-
invertColorMap,
52+
keepRatio,
5353
flipXAxis,
5454
flipYAxis,
5555
setCustomDomain,
5656
setColorMap,
57+
setInvertColorMap,
5758
setScaleType,
5859
setComplexVisType,
59-
toggleKeepRatio,
60-
toggleGrid,
61-
toggleColorMapInversion,
62-
toggleXAxisFlip,
63-
toggleYAxisFlip,
60+
setShowGrid,
61+
setKeepRatio,
62+
setFlipXAxis,
63+
setFlipYAxis,
6464
} = config;
6565

6666
return (
@@ -77,7 +77,7 @@ function HeatmapToolbar(props: Props) {
7777
value={colorMap}
7878
onValueChange={setColorMap}
7979
invert={invertColorMap}
80-
onInversionChange={toggleColorMapInversion}
80+
onInversionChange={() => setInvertColorMap(!invertColorMap)}
8181
/>
8282

8383
<Separator />
@@ -103,28 +103,28 @@ function HeatmapToolbar(props: Props) {
103103
aria-label="Flip X"
104104
Icon={MdSwapHoriz}
105105
value={flipXAxis}
106-
onToggle={toggleXAxisFlip}
106+
onToggle={() => setFlipXAxis(!flipXAxis)}
107107
/>
108108
<ToggleBtn
109109
label="Y"
110110
aria-label="Flip Y"
111111
Icon={MdSwapVert}
112112
value={flipYAxis}
113-
onToggle={toggleYAxisFlip}
113+
onToggle={() => setFlipYAxis(!flipYAxis)}
114114
/>
115115

116116
<ToggleBtn
117117
label="Keep ratio"
118118
Icon={MdAspectRatio}
119119
value={keepRatio}
120-
onToggle={toggleKeepRatio}
120+
onToggle={() => setKeepRatio(!keepRatio)}
121121
/>
122122

123123
<ToggleBtn
124124
label="Grid"
125125
Icon={MdGridOn}
126126
value={showGrid}
127-
onToggle={toggleGrid}
127+
onToggle={() => setShowGrid(!showGrid)}
128128
/>
129129

130130
<Separator />
Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { type CustomDomain } from '@h5web/lib';
2-
import { isDefined } from '@h5web/shared/guards';
32
import {
43
type ColorScaleType,
54
type ComplexHeatmapVisType,
65
ComplexVisType,
76
type NoProps,
87
ScaleType,
98
} from '@h5web/shared/vis-models';
10-
import { useMap } from '@react-hookz/web';
119
import {
1210
createContext,
1311
type PropsWithChildren,
@@ -17,6 +15,7 @@ import {
1715
import { createStore, type StoreApi, useStore } from 'zustand';
1816
import { persist } from 'zustand/middleware';
1917

18+
import { useSuggestion } from '../hooks';
2019
import { type ColorMap } from './models';
2120

2221
export interface HeatmapConfig {
@@ -27,7 +26,7 @@ export interface HeatmapConfig {
2726
setColorMap: (colorMap: ColorMap) => void;
2827

2928
invertColorMap: boolean;
30-
toggleColorMapInversion: () => void;
29+
setInvertColorMap: (invertColorMap: boolean) => void;
3130

3231
scaleType: ColorScaleType;
3332
setScaleType: (scaleType: ColorScaleType) => void;
@@ -36,16 +35,16 @@ export interface HeatmapConfig {
3635
setComplexVisType: (complexVisType: ComplexHeatmapVisType) => void;
3736

3837
showGrid: boolean;
39-
toggleGrid: () => void;
38+
setShowGrid: (showGrid: boolean) => void;
4039

4140
keepRatio: boolean;
42-
toggleKeepRatio: () => void;
41+
setKeepRatio: (keepRatio: boolean) => void;
4342

4443
flipXAxis: boolean;
45-
toggleXAxisFlip: () => void;
44+
setFlipXAxis: (flipXAxis: boolean) => void;
4645

4746
flipYAxis: boolean;
48-
toggleYAxisFlip: () => void;
47+
setFlipYAxis: (flipYAxis: boolean) => void;
4948
}
5049

5150
function createHeatmapConfigStore() {
@@ -59,9 +58,7 @@ function createHeatmapConfigStore() {
5958
setColorMap: (colorMap) => set({ colorMap }),
6059

6160
invertColorMap: false,
62-
toggleColorMapInversion: () => {
63-
set((state) => ({ invertColorMap: !state.invertColorMap }));
64-
},
61+
setInvertColorMap: (invertColorMap) => set({ invertColorMap }),
6562

6663
scaleType: ScaleType.Linear,
6764
setScaleType: (scaleType) => set(() => ({ scaleType })),
@@ -70,23 +67,20 @@ function createHeatmapConfigStore() {
7067
setComplexVisType: (complexVisType) => set(() => ({ complexVisType })),
7168

7269
showGrid: true,
73-
toggleGrid: () => set((state) => ({ showGrid: !state.showGrid })),
70+
setShowGrid: (showGrid) => set({ showGrid }),
7471

7572
keepRatio: true,
76-
toggleKeepRatio: () =>
77-
set((state) => ({ keepRatio: !state.keepRatio })),
73+
setKeepRatio: (keepRatio) => set({ keepRatio }),
7874

7975
flipYAxis: false,
80-
toggleYAxisFlip: () =>
81-
set((state) => ({ flipYAxis: !state.flipYAxis })),
76+
setFlipYAxis: (flipYAxis) => set({ flipYAxis }),
8277

8378
flipXAxis: false,
84-
toggleXAxisFlip: () =>
85-
set((state) => ({ flipXAxis: !state.flipXAxis })),
79+
setFlipXAxis: (flipXAxis) => set({ flipXAxis }),
8680
}),
8781
{
8882
name: 'h5web:heatmap',
89-
version: 11,
83+
version: 12,
9084
},
9185
),
9286
);
@@ -105,30 +99,21 @@ export function HeatmapConfigProvider(props: PropsWithChildren<NoProps>) {
10599
}
106100

107101
export function useHeatmapConfig(
108-
initialSuggestedOpts: Partial<
109-
Pick<HeatmapConfig, 'scaleType' | 'keepRatio'>
110-
> = {},
102+
suggestions: Partial<Pick<HeatmapConfig, 'scaleType' | 'keepRatio'>> = {},
111103
): HeatmapConfig {
112-
const suggestedOpts = useMap(
113-
Object.entries(initialSuggestedOpts).filter(([, val]) => isDefined(val)),
104+
const config = useStore(useContext(StoreContext));
105+
106+
const [scaleType, setScaleType] = useSuggestion(
107+
suggestions.scaleType,
108+
config.scaleType,
109+
config.setScaleType,
110+
);
111+
112+
const [keepRatio, setKeepRatio] = useSuggestion(
113+
suggestions.keepRatio,
114+
config.keepRatio,
115+
config.setKeepRatio,
114116
);
115117

116-
const persistedConfig = useStore(useContext(StoreContext));
117-
const {
118-
setScaleType: setPersistedScaleType,
119-
toggleKeepRatio: togglePersistedKeepRatio,
120-
} = persistedConfig;
121-
122-
return {
123-
...persistedConfig,
124-
...Object.fromEntries(suggestedOpts.entries()),
125-
setScaleType: (scaleType: ColorScaleType) => {
126-
setPersistedScaleType(scaleType);
127-
suggestedOpts.delete('scaleType');
128-
},
129-
toggleKeepRatio: () => {
130-
togglePersistedKeepRatio();
131-
suggestedOpts.delete('keepRatio');
132-
},
133-
};
118+
return { ...config, scaleType, keepRatio, setScaleType, setKeepRatio };
134119
}

packages/app/src/vis-packs/core/hooks.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import {
1717
type IgnoreValue,
1818
type NumArray,
1919
} from '@h5web/shared/vis-models';
20+
import { useToggle } from '@react-hookz/web';
2021
import { type NdArray } from 'ndarray';
21-
import { useMemo } from 'react';
22+
import { useCallback, useMemo } from 'react';
2223

2324
import { useDataContext } from '../../providers/DataProvider';
2425
import {
@@ -152,3 +153,25 @@ export function useExportEntries<F extends ExportFormat[]>(
152153
})
153154
.filter(isDefined);
154155
}
156+
157+
export function useSuggestion<T>(
158+
suggestion: T | undefined,
159+
storeValue: T,
160+
storeSetter: (val: T) => void,
161+
): [T, (val: T) => void] {
162+
const [isIgnored, ignoreSuggestion] = useToggle();
163+
164+
const patchedSetter = useCallback(
165+
(val: T) => {
166+
storeSetter(val);
167+
ignoreSuggestion();
168+
},
169+
[storeSetter, ignoreSuggestion],
170+
);
171+
172+
if (isIgnored || !isDefined(suggestion)) {
173+
return [storeValue, storeSetter];
174+
}
175+
176+
return [suggestion, patchedSetter];
177+
}

packages/app/src/vis-packs/core/line/LineToolbar.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ function LineToolbar(props: Props) {
5454
interpolation,
5555
setCustomDomain,
5656
setCurveType,
57-
toggleGrid,
57+
setShowGrid,
5858
setXScaleType,
5959
setYScaleType,
6060
setComplexVisType,
61-
toggleErrors,
61+
setShowErrors,
6262
setInterpolation,
6363
} = config;
6464

@@ -103,15 +103,15 @@ function LineToolbar(props: Props) {
103103
label="Errors"
104104
Icon={ErrorsIcon}
105105
value={showErrors}
106-
onToggle={toggleErrors}
106+
onToggle={() => setShowErrors(!showErrors)}
107107
/>
108108
)}
109109

110110
<ToggleBtn
111111
label="Grid"
112112
Icon={MdGridOn}
113113
value={showGrid}
114-
onToggle={toggleGrid}
114+
onToggle={() => setShowGrid(!showGrid)}
115115
/>
116116

117117
<Menu label="Aspect" Icon={MdAutoGraph}>

packages/app/src/vis-packs/core/line/config.tsx

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { CurveType, type CustomDomain, Interpolation } from '@h5web/lib';
2-
import { isDefined } from '@h5web/shared/guards';
32
import {
43
type AxisScaleType,
54
type ComplexLineVisType,
65
ComplexVisType,
76
type NoProps,
87
ScaleType,
98
} from '@h5web/shared/vis-models';
10-
import { useMap } from '@react-hookz/web';
119
import {
1210
createContext,
1311
type PropsWithChildren,
@@ -17,6 +15,8 @@ import {
1715
import { createStore, type StoreApi, useStore } from 'zustand';
1816
import { persist } from 'zustand/middleware';
1917

18+
import { useSuggestion } from '../hooks';
19+
2020
export interface LineConfig {
2121
customDomain: CustomDomain;
2222
setCustomDomain: (customDomain: CustomDomain) => void;
@@ -25,7 +25,7 @@ export interface LineConfig {
2525
setCurveType: (type: CurveType) => void;
2626

2727
showGrid: boolean;
28-
toggleGrid: () => void;
28+
setShowGrid: (showGrid: boolean) => void;
2929

3030
xScaleType: AxisScaleType;
3131
yScaleType: AxisScaleType;
@@ -36,7 +36,7 @@ export interface LineConfig {
3636
setComplexVisType: (visType: ComplexLineVisType) => void;
3737

3838
showErrors: boolean;
39-
toggleErrors: () => void;
39+
setShowErrors: (showErrors: boolean) => void;
4040

4141
interpolation: Interpolation;
4242
setInterpolation: (interpolation: Interpolation) => void;
@@ -53,7 +53,7 @@ function createLineConfigStore() {
5353
setCurveType: (curveType) => set({ curveType }),
5454

5555
showGrid: true,
56-
toggleGrid: () => set((state) => ({ showGrid: !state.showGrid })),
56+
setShowGrid: (showGrid) => set({ showGrid }),
5757

5858
xScaleType: ScaleType.Linear,
5959
yScaleType: ScaleType.Linear,
@@ -64,7 +64,7 @@ function createLineConfigStore() {
6464
setComplexVisType: (complexVisType) => set(() => ({ complexVisType })),
6565

6666
showErrors: true,
67-
toggleErrors: () => set((state) => ({ showErrors: !state.showErrors })),
67+
setShowErrors: (showErrors) => set({ showErrors }),
6868

6969
interpolation: Interpolation.Linear,
7070
setInterpolation: (interpolation) => set({ interpolation }),
@@ -90,30 +90,21 @@ export function LineConfigProvider(props: PropsWithChildren<NoProps>) {
9090
}
9191

9292
export function useLineConfig(
93-
initialSuggestedOpts: Partial<
94-
Pick<LineConfig, 'xScaleType' | 'yScaleType'>
95-
> = {},
93+
suggestions: Partial<Pick<LineConfig, 'xScaleType' | 'yScaleType'>> = {},
9694
): LineConfig {
97-
const suggestedOpts = useMap(
98-
Object.entries(initialSuggestedOpts).filter(([, val]) => isDefined(val)),
95+
const config = useStore(useContext(StoreContext));
96+
97+
const [xScaleType, setXScaleType] = useSuggestion(
98+
suggestions.xScaleType,
99+
config.xScaleType,
100+
config.setXScaleType,
101+
);
102+
103+
const [yScaleType, setYScaleType] = useSuggestion(
104+
suggestions.yScaleType,
105+
config.yScaleType,
106+
config.setYScaleType,
99107
);
100108

101-
const persistedConfig = useStore(useContext(StoreContext));
102-
const {
103-
setXScaleType: setPersistedXScaleType,
104-
setYScaleType: setPersistedYScaleType,
105-
} = persistedConfig;
106-
107-
return {
108-
...persistedConfig,
109-
...Object.fromEntries(suggestedOpts.entries()),
110-
setXScaleType: (xScaleType: AxisScaleType) => {
111-
setPersistedXScaleType(xScaleType);
112-
suggestedOpts.delete('xScaleType');
113-
},
114-
setYScaleType: (yScaleType: AxisScaleType) => {
115-
setPersistedYScaleType(yScaleType);
116-
suggestedOpts.delete('yScaleType');
117-
},
118-
};
109+
return { ...config, xScaleType, yScaleType, setXScaleType, setYScaleType };
119110
}

packages/app/src/vis-packs/core/raw/RawToolbar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface Props {
1212

1313
function RawToolbar(props: Props) {
1414
const { isImage, config, exportEntries } = props;
15-
const { fitImage, toggleFitImage } = config;
15+
const { fitImage, setFitImage } = config;
1616

1717
return (
1818
<Toolbar>
@@ -21,7 +21,7 @@ function RawToolbar(props: Props) {
2121
Icon={MdOutlineFitScreen}
2222
value={fitImage}
2323
disabled={!isImage}
24-
onToggle={toggleFitImage}
24+
onToggle={() => setFitImage(!fitImage)}
2525
/>
2626

2727
{exportEntries.length > 0 && (

0 commit comments

Comments
 (0)