Skip to content

Commit 386cd82

Browse files
committed
Add layer toggle with default off
1 parent ce154bd commit 386cd82

File tree

6 files changed

+63
-37
lines changed

6 files changed

+63
-37
lines changed

src/components/LayerController/Content.tsx

+12-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const Details = withStyles({
2323
function Content() {
2424
const [layer] = useLayerState();
2525
const nChannels = layer.layerProps.selections.length;
26-
const nLabels = layer.labels?.length ?? 0;
2726
return (
2827
<Details>
2928
<Grid container direction="column">
@@ -53,13 +52,18 @@ function Content() {
5352
<ChannelController channelIndex={i} key={i} />
5453
))}
5554
</Grid>
56-
{nLabels > 0 && (
57-
<Grid>
58-
<Typography variant="caption">labels:</Typography>
59-
{range(nLabels).map((i) => (
60-
<Labels labelIndex={i} key={i} />
61-
))}
62-
</Grid>
55+
{layer.labels?.length && (
56+
<>
57+
<Grid container justifyContent="space-between">
58+
<Typography variant="caption">labels:</Typography>
59+
</Grid>
60+
<Divider />
61+
<Grid>
62+
{layer.labels.map((label, i) => (
63+
<Labels labelIndex={i} key={label.layerProps.id} />
64+
))}
65+
</Grid>
66+
</>
6367
)}
6468
</Grid>
6569
</Details>
+41-18
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,10 @@
1-
import { Divider, Typography } from "@material-ui/core";
2-
import { Slider } from "@material-ui/core";
3-
import { withStyles } from "@material-ui/styles";
1+
import { Grid, IconButton, Slider, Typography } from "@material-ui/core";
2+
import { RadioButtonChecked, RadioButtonUnchecked } from "@material-ui/icons";
43
import React from "react";
54

65
import { useLayerState, useSourceData } from "../../hooks";
76
import { assert } from "../../utils";
87

9-
const DenseSlider = withStyles({
10-
root: {
11-
color: "white",
12-
padding: "10px 0px 5px 0px",
13-
marginRight: "5px",
14-
},
15-
active: {
16-
boxshadow: "0px 0px 0px 8px rgba(158, 158, 158, 0.16)",
17-
},
18-
})(Slider);
19-
208
export default function Labels({ labelIndex }: { labelIndex: number }) {
219
const [source] = useSourceData();
2210
const [layer, setLayer] = useLayerState();
@@ -39,12 +27,47 @@ export default function Labels({ labelIndex }: { labelIndex: number }) {
3927
};
4028

4129
const { name } = source.labels[labelIndex];
42-
const { opacity } = layer.labels[labelIndex].layerProps;
30+
const label = layer.labels[labelIndex];
4331
return (
4432
<>
45-
<Divider />
46-
<Typography variant="caption">{name}</Typography>
47-
<DenseSlider value={opacity} onChange={handleOpacityChange} min={0} max={1} step={0.01} />
33+
<Grid container justifyContent="space-between" wrap="nowrap">
34+
<div style={{ width: 165, overflow: "hidden", textOverflow: "ellipsis" }}>
35+
<Typography variant="caption" noWrap>
36+
{name}
37+
</Typography>
38+
</div>
39+
</Grid>
40+
<Grid container justifyContent="space-between">
41+
<Grid item xs={2}>
42+
<IconButton
43+
style={{ backgroundColor: "transparent", padding: 0, zIndex: 2 }}
44+
onClick={() => {
45+
setLayer((prev) => {
46+
assert(prev.kind === "multiscale" && prev.labels, "Missing image labels");
47+
return {
48+
...prev,
49+
labels: prev.labels.with(labelIndex, {
50+
...prev.labels[labelIndex],
51+
on: !prev.labels[labelIndex].on,
52+
}),
53+
};
54+
});
55+
}}
56+
>
57+
{label.on ? <RadioButtonChecked /> : <RadioButtonUnchecked />}
58+
</IconButton>
59+
</Grid>
60+
<Grid item xs={10}>
61+
<Slider
62+
value={label.layerProps.opacity}
63+
onChange={handleOpacityChange}
64+
min={0}
65+
max={1}
66+
step={0.01}
67+
style={{ padding: "10px 0px 5px 0px" }}
68+
/>
69+
</Grid>
70+
</Grid>
4871
</>
4972
);
5073
}

src/components/LayerController/index.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const Accordion = withStyles({
3131
function LayerController() {
3232
const [sourceInfo] = useSourceData();
3333
const layerAtom = layerFamilyAtom(sourceInfo);
34-
const { name = "" } = sourceInfo;
3534
return (
3635
<LayerStateContext.Provider value={layerAtom}>
3736
<Accordion defaultExpanded>

src/io.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,14 @@ export function initLayerStateFromSource(source: SourceData & { id: string }): L
222222
let labels = undefined;
223223
if (source.labels && source.labels.length > 0) {
224224
labels = source.labels.map((label, i) => ({
225-
on: true,
225+
on: false,
226226
transformSourceSelection: getSourceSelectionTransform(label.loader[0], source.loader[0]),
227227
layerProps: {
228228
id: `${source.id}_${i}`,
229229
loader: label.loader,
230230
modelMatrix: label.modelMatrix,
231231
opacity: DEFAULT_LABEL_OPACITY,
232+
colors: label.colors,
232233
},
233234
}));
234235
}

src/state.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,13 @@ const imageLabelsIstanceFamily = atomFamily((a: Atom<LayerState>) =>
175175
if (!on || !labels) {
176176
return [];
177177
}
178-
return labels.map(
179-
(label) =>
180-
new LabelLayer({
181-
...label.layerProps,
182-
selection: label.transformSourceSelection(layerProps.selections[0]),
183-
}),
178+
return labels.map((label) =>
179+
label.on
180+
? new LabelLayer({
181+
...label.layerProps,
182+
selection: label.transformSourceSelection(layerProps.selections[0]),
183+
})
184+
: null,
184185
);
185186
}),
186187
);

vite.config.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import * as path from "node:path";
33
import react from "@vitejs/plugin-react";
44
import { defineConfig } from "vite";
55

6-
const source = process.env.VIZARR_DATA || "https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.1/6001253.zarr";
7-
86
/**
97
* Writes a new entry point that exports contents of an existing chunk.
108
* @param {string} entryPointName - Name of the new entry point
@@ -44,6 +42,6 @@ export default defineConfig({
4442
},
4543
},
4644
server: {
47-
open: `?source=${source}`,
45+
open: `?source=${process.env.VIZARR_DATA || "https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.1/6001253.zarr"}`,
4846
},
4947
});

0 commit comments

Comments
 (0)