Skip to content

Commit 3eba27e

Browse files
committed
Fix support for enum/bool auxiliary signals in NX Line visualization
1 parent fde64c3 commit 3eba27e

File tree

9 files changed

+111
-30
lines changed

9 files changed

+111
-30
lines changed

packages/app/src/providers/mock/mock-file.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,21 @@ export function makeMockFile(): GroupWithChildren {
284284
}),
285285
nxGroup('numeric-like', 'NXprocess', {
286286
children: [
287-
nxData('bool', { signal: array('twoD_bool') }),
287+
nxData('bool', {
288+
signal: array('twoD_bool'),
289+
auxiliary: { secondary_bool: array('secondary_bool') },
290+
auxAttr: ['secondary_bool'],
291+
}),
288292
nxData('enum', {
289293
signal: array('twoD_enum', {
290294
type: enumType(intType(false, 8), ENUM_MAPPING),
291295
}),
296+
auxiliary: {
297+
secondary_enum: array('secondary_enum', {
298+
type: enumType(intType(false, 8), ENUM_MAPPING),
299+
}),
300+
},
301+
auxAttr: ['secondary_enum'],
292302
}),
293303
],
294304
}),

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
type ArrayShape,
55
type ArrayValue,
66
type Dataset,
7+
type NumericLikeType,
78
type ScalarShape,
89
type Value,
910
} from '@h5web/shared/hdf5-models';
@@ -25,6 +26,12 @@ import {
2526

2627
export const useToNumArray = createMemo(toNumArray);
2728

29+
export function useToNumArrays(
30+
arrays: ArrayValue<NumericLikeType>[],
31+
): NumArray[] {
32+
return useMemo(() => arrays.map(toNumArray), arrays); // eslint-disable-line react-hooks/exhaustive-deps
33+
}
34+
2835
export function useValuesInCache(
2936
...datasets: (Dataset<ScalarShape | ArrayShape> | undefined)[]
3037
): (dimMapping: DimensionMapping) => boolean {
@@ -129,23 +136,23 @@ export function useMappedArray(
129136
return useMemo(() => applyMapping(baseArray, mapping), [baseArray, mapping]);
130137
}
131138

132-
export function useMappedArrays(
133-
values: NumArray[],
139+
export function useMappedArrays<T extends ArrayValue>(
140+
values: T[],
134141
dims: number[],
135142
mapping: DimensionMapping,
136-
): NdArray<NumArray>[];
143+
): NdArray<T>[];
137144

138-
export function useMappedArrays(
139-
values: (NumArray | undefined)[],
145+
export function useMappedArrays<T extends ArrayValue>(
146+
values: (T | undefined)[],
140147
dims: number[],
141148
mapping: DimensionMapping,
142-
): (NdArray<NumArray> | undefined)[];
149+
): (NdArray<T> | undefined)[];
143150

144151
export function useMappedArrays(
145-
values: (NumArray | undefined)[],
152+
values: (ArrayValue | undefined)[],
146153
dims: number[],
147154
mapping: DimensionMapping,
148-
): (NdArray<NumArray> | undefined)[] {
155+
): (NdArray<ArrayValue> | undefined)[] {
149156
const baseArrays = useMemo(
150157
() => values.map((arr) => getBaseArray(arr, dims)),
151158
[dims, ...values], // eslint-disable-line react-hooks/exhaustive-deps

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import {
88
} from '@h5web/lib';
99
import {
1010
type ArrayShape,
11-
type ArrayValue,
1211
type Dataset,
1312
type NumericLikeType,
13+
type Value,
1414
} from '@h5web/shared/hdf5-models';
1515
import { type AxisMapping } from '@h5web/shared/nexus-models';
1616
import { type NumArray } from '@h5web/shared/vis-models';
@@ -24,18 +24,19 @@ import {
2424
useMappedArrays,
2525
useSlicedDimsAndMapping,
2626
useToNumArray,
27+
useToNumArrays,
2728
} from '../hooks';
2829
import { DEFAULT_DOMAIN, formatNumLikeType, getSliceSelection } from '../utils';
2930
import { type LineConfig } from './config';
3031
import LineToolbar from './LineToolbar';
3132

3233
interface Props {
33-
dataset?: Dataset<ArrayShape, NumericLikeType>;
34-
value: ArrayValue<NumericLikeType>;
34+
dataset: Dataset<ArrayShape, NumericLikeType>;
35+
value: Value<Props['dataset']>;
3536
valueLabel?: string;
3637
errors?: NumArray;
3738
auxLabels?: string[];
38-
auxValues?: NumArray[];
39+
auxValues?: Value<Props['dataset']>[];
3940
auxErrors?: (NumArray | undefined)[];
4041
dims: number[];
4142
dimMapping: DimensionMapping;
@@ -76,12 +77,13 @@ function MappedLineVis(props: Props) {
7677
} = config;
7778

7879
const numArray = useToNumArray(value);
80+
const numAuxArrays = useToNumArrays(auxValues);
7981
const [slicedDims, slicedMapping] = useSlicedDimsAndMapping(dims, dimMapping);
8082

8183
const hookArgs = [slicedDims, slicedMapping] as const;
8284
const dataArray = useMappedArray(numArray, ...hookArgs);
8385
const errorArray = useMappedArray(errors, ...hookArgs);
84-
const auxArrays = useMappedArrays(auxValues, ...hookArgs);
86+
const auxArrays = useMappedArrays(numAuxArrays, ...hookArgs);
8587
const auxErrorsArrays = useMappedArrays(auxErrors, ...hookArgs);
8688

8789
const dataDomain = useDomain(
@@ -114,7 +116,6 @@ function MappedLineVis(props: Props) {
114116
config={config}
115117
getExportURL={
116118
getExportURL &&
117-
dataset &&
118119
((format) => getExportURL(format, dataset, selection, value))
119120
}
120121
/>,
@@ -135,7 +136,7 @@ function MappedLineVis(props: Props) {
135136
}}
136137
ordinateLabel={valueLabel}
137138
title={title}
138-
dtype={dataset && formatNumLikeType(dataset.type)}
139+
dtype={formatNumLikeType(dataset.type)}
139140
errorsArray={errorArray}
140141
showErrors={showErrors}
141142
auxiliaries={auxArrays.map((array, i) => ({

packages/app/src/vis-packs/nexus/NxSignalPicker.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
import { type ComplexType, type NumericType } from '@h5web/shared/hdf5-models';
1+
import {
2+
type ComplexType,
3+
type NumericLikeType,
4+
} from '@h5web/shared/hdf5-models';
25

36
import { type DatasetDef } from './models';
47
import styles from './NxSignalPicker.module.css';
58

6-
interface Props<T extends NumericType | ComplexType> {
9+
interface Props<T extends NumericLikeType | ComplexType> {
710
definitions: DatasetDef<T>[];
811
onChange: (def: DatasetDef<T>) => void;
912
}
1013

11-
function NxSignalPicker<T extends NumericType | ComplexType>(props: Props<T>) {
14+
function NxSignalPicker<T extends NumericLikeType | ComplexType>(
15+
props: Props<T>,
16+
) {
1217
const { definitions, onChange } = props;
1318

1419
return (

packages/app/src/vis-packs/nexus/NxValuesFetcher.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { type ComplexType, type NumericType } from '@h5web/shared/hdf5-models';
1+
import {
2+
type ComplexType,
3+
type NumericLikeType,
4+
} from '@h5web/shared/hdf5-models';
25
import { type ReactNode } from 'react';
36

47
import {
@@ -8,13 +11,15 @@ import {
811
} from '../core/hooks';
912
import { type NxData, type NxValues } from './models';
1013

11-
interface Props<T extends NumericType | ComplexType> {
14+
interface Props<T extends NumericLikeType | ComplexType> {
1215
nxData: NxData<T>;
1316
selection?: string; // for slice-by-slice fetching
1417
render: (val: NxValues<T>) => ReactNode;
1518
}
1619

17-
function NxValuesFetcher<T extends NumericType | ComplexType>(props: Props<T>) {
20+
function NxValuesFetcher<T extends NumericLikeType | ComplexType>(
21+
props: Props<T>,
22+
) {
1823
const { nxData, selection, render } = props;
1924
const { signalDef, axisDefs, auxDefs, titleDataset } = nxData;
2025

packages/app/src/vis-packs/nexus/guards.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,72 @@ import {
22
assertComplexType,
33
assertNumericLikeType,
44
assertNumericType,
5+
isDefined,
56
} from '@h5web/shared/guards';
6-
import { type ComplexType, type NumericType } from '@h5web/shared/hdf5-models';
7+
import {
8+
type ComplexType,
9+
type NumericLikeType,
10+
type NumericType,
11+
} from '@h5web/shared/hdf5-models';
712

813
import { type NxData } from './models';
914

1015
export function assertNumericLikeNxData(
1116
nxData: NxData,
12-
): asserts nxData is NxData<NumericType> {
13-
const { signalDef, auxDefs } = nxData;
17+
): asserts nxData is NxData<NumericLikeType> {
18+
const { signalDef, auxDefs, axisDefs } = nxData;
19+
1420
assertNumericLikeType(signalDef.dataset);
21+
1522
auxDefs.forEach((def) => {
1623
assertNumericLikeType(def.dataset);
1724
});
25+
26+
if (signalDef.errorDataset) {
27+
assertNumericType(signalDef.errorDataset);
28+
}
29+
30+
axisDefs.filter(isDefined).forEach((def) => {
31+
assertNumericType(def.dataset);
32+
});
1833
}
1934

2035
export function assertNumericNxData(
2136
nxData: NxData,
2237
): asserts nxData is NxData<NumericType> {
23-
const { signalDef, auxDefs } = nxData;
38+
const { signalDef, auxDefs, axisDefs } = nxData;
39+
2440
assertNumericType(signalDef.dataset);
41+
2542
auxDefs.forEach((def) => {
2643
assertNumericType(def.dataset);
2744
});
45+
46+
if (signalDef.errorDataset) {
47+
assertNumericType(signalDef.errorDataset);
48+
}
49+
50+
axisDefs.filter(isDefined).forEach((def) => {
51+
assertNumericType(def.dataset);
52+
});
2853
}
2954

3055
export function assertComplexNxData(
3156
nxData: NxData,
3257
): asserts nxData is NxData<ComplexType> {
33-
const { signalDef, auxDefs } = nxData;
58+
const { signalDef, auxDefs, axisDefs } = nxData;
59+
3460
assertComplexType(signalDef.dataset);
61+
3562
auxDefs.forEach((def) => {
3663
assertComplexType(def.dataset);
3764
});
65+
66+
if (signalDef.errorDataset) {
67+
assertNumericType(signalDef.errorDataset);
68+
}
69+
70+
axisDefs.filter(isDefined).forEach((def) => {
71+
assertNumericType(def.dataset);
72+
});
3873
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
22
type ComplexType,
33
type GroupWithChildren,
4-
type NumericType,
4+
type NumericLikeType,
55
} from '@h5web/shared/hdf5-models';
66

77
import { type DimensionMapping } from '../../dimension-mapper/models';
@@ -48,7 +48,7 @@ export function useNxData(group: GroupWithChildren): NxData {
4848
};
4949
}
5050

51-
export function useNxImageDataToFetch<T extends NumericType | ComplexType>(
51+
export function useNxImageDataToFetch<T extends NumericLikeType | ComplexType>(
5252
nxData: NxData<T>,
5353
selectedDef: DatasetDef<T>,
5454
): NxData<T> {

packages/app/src/vis-packs/nexus/models.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export interface NxData<
5656
silxStyle: SilxStyle;
5757
}
5858

59-
export interface NxValues<T extends NumericType | ComplexType> {
59+
export interface NxValues<T extends NumericLikeType | ComplexType> {
6060
title: string;
6161
signal: ArrayValue<T>;
6262
errors?: NumArray;

packages/shared/src/mock-values.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,24 @@ export const mockValues = {
266266
].flat(1),
267267
[2, 2],
268268
),
269+
secondary_bool: () => {
270+
const { data: dataOneDBool } = oneD_bool();
271+
return ndarray(
272+
dataOneDBool.flatMap((rowBool) =>
273+
dataOneDBool.map((colBool) => (rowBool ? !colBool : colBool)),
274+
),
275+
[10, 10],
276+
);
277+
},
278+
secondary_enum: () => {
279+
const { data: dataOneDEnum } = oneD_enum();
280+
return ndarray(
281+
dataOneDEnum.flatMap((rowEnum) =>
282+
dataOneDEnum.map((colEnum, j) => (j % 2 === 0 ? colEnum : rowEnum)),
283+
),
284+
[10, 10],
285+
);
286+
},
269287
tertiary: () =>
270288
ndarray(
271289
twoD().data.map((v) => v / 2),

0 commit comments

Comments
 (0)