@haniffalab/cherita-react 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/.eslintrc.json +0 -6
- package/babel.config.json +0 -6
- package/src/index.js +0 -6
- package/src/lib/components/Dotplot.js +0 -116
- package/src/lib/components/Heatmap.js +0 -115
- package/src/lib/components/ObsList.js +0 -56
- package/src/lib/components/VarList.js +0 -114
- package/src/lib/constants/constants.js +0 -20
- package/src/lib/context/DatasetContext.js +0 -68
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haniffalab/cherita-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"author": "",
|
|
5
5
|
"license": "",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
|
+
"files": ["dist"],
|
|
8
9
|
"dependencies": {
|
|
9
10
|
"bootstrap": "^5.3.0",
|
|
10
11
|
"jquery": "^3.7.0",
|
package/.eslintrc.json
DELETED
package/babel.config.json
DELETED
package/src/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { ObsColsList } from "./lib/components/ObsList";
|
|
2
|
-
export { VarNamesList } from "./lib/components/VarList";
|
|
3
|
-
export { Heatmap } from "./lib/components/Heatmap";
|
|
4
|
-
export { Dotplot } from "./lib/components/Dotplot";
|
|
5
|
-
export { PLOTLY_COLORSCALES } from "./lib/constants/constants";
|
|
6
|
-
export { DatasetProvider } from "./lib/context/DatasetContext";
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import "bootstrap/dist/css/bootstrap.min.css";
|
|
2
|
-
import Dropdown from "react-bootstrap/Dropdown";
|
|
3
|
-
import { React, useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
-
import Plot from "react-plotly.js";
|
|
5
|
-
import { useDataset, useDatasetDispatch } from "./DatasetContext";
|
|
6
|
-
import { PLOTLY_COLORSCALES } from "./lib/constants/constants";
|
|
7
|
-
|
|
8
|
-
export function DotplotControls() {
|
|
9
|
-
const dataset = useDataset();
|
|
10
|
-
const dispatch = useDatasetDispatch();
|
|
11
|
-
let [active, setActive] = useState(dataset.colorscale);
|
|
12
|
-
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
setActive(dataset.colorscale);
|
|
15
|
-
}, [dataset.colorscale]);
|
|
16
|
-
|
|
17
|
-
const colormapList = PLOTLY_COLORSCALES.map((item) => (
|
|
18
|
-
<Dropdown.Item
|
|
19
|
-
key={item}
|
|
20
|
-
active={active === item}
|
|
21
|
-
onClick={() => {
|
|
22
|
-
dispatch({
|
|
23
|
-
type: "colorscaleSelected",
|
|
24
|
-
colorscale: item,
|
|
25
|
-
});
|
|
26
|
-
}}
|
|
27
|
-
>
|
|
28
|
-
{item}
|
|
29
|
-
</Dropdown.Item>
|
|
30
|
-
));
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<Dropdown>
|
|
34
|
-
<Dropdown.Toggle id="dropdownColorscale" variant="light">
|
|
35
|
-
{dataset.colorscale}
|
|
36
|
-
</Dropdown.Toggle>
|
|
37
|
-
<Dropdown.Menu>{colormapList}</Dropdown.Menu>
|
|
38
|
-
</Dropdown>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function Dotplot() {
|
|
43
|
-
const dataset = useDataset();
|
|
44
|
-
const colorscale = useRef(dataset.colorscale);
|
|
45
|
-
let [data, setData] = useState([]);
|
|
46
|
-
let [layout, setLayout] = useState({});
|
|
47
|
-
let [hasSelections, setHasSelections] = useState(false);
|
|
48
|
-
|
|
49
|
-
const updateColorscale = useCallback((colorscale) => {
|
|
50
|
-
setLayout((l) => {
|
|
51
|
-
return {
|
|
52
|
-
...l,
|
|
53
|
-
coloraxis: { ...l.coloraxis, colorscale: colorscale },
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
}, []);
|
|
57
|
-
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (dataset.selectedObs && dataset.selectedMultiVar.length) {
|
|
60
|
-
setHasSelections(true);
|
|
61
|
-
fetch(new URL("dotplot", process.env.REACT_APP_API_URL), {
|
|
62
|
-
method: "POST",
|
|
63
|
-
mode: "cors",
|
|
64
|
-
headers: {
|
|
65
|
-
"Content-Type": "application/json",
|
|
66
|
-
Accept: "application/json",
|
|
67
|
-
},
|
|
68
|
-
body: JSON.stringify({
|
|
69
|
-
url: dataset.url,
|
|
70
|
-
selectedObs: dataset.selectedObs,
|
|
71
|
-
selectedMultiVar: dataset.selectedMultiVar,
|
|
72
|
-
}),
|
|
73
|
-
})
|
|
74
|
-
.then((response) => response.json())
|
|
75
|
-
.then((data) => {
|
|
76
|
-
setData(data.data);
|
|
77
|
-
setLayout(data.layout);
|
|
78
|
-
updateColorscale(colorscale.current);
|
|
79
|
-
});
|
|
80
|
-
} else {
|
|
81
|
-
setHasSelections(false);
|
|
82
|
-
}
|
|
83
|
-
}, [
|
|
84
|
-
dataset.url,
|
|
85
|
-
dataset.selectedObs,
|
|
86
|
-
dataset.selectedMultiVar,
|
|
87
|
-
updateColorscale,
|
|
88
|
-
]);
|
|
89
|
-
|
|
90
|
-
useEffect(() => {
|
|
91
|
-
console.log("update colorscale");
|
|
92
|
-
colorscale.current = dataset.colorscale;
|
|
93
|
-
updateColorscale(colorscale.current);
|
|
94
|
-
}, [dataset.colorscale, updateColorscale]);
|
|
95
|
-
|
|
96
|
-
if (hasSelections) {
|
|
97
|
-
return (
|
|
98
|
-
<div className="container text-center">
|
|
99
|
-
<h5>{dataset.url}</h5>
|
|
100
|
-
<DotplotControls />
|
|
101
|
-
<Plot
|
|
102
|
-
data={data}
|
|
103
|
-
layout={layout}
|
|
104
|
-
useResizeHandler={true}
|
|
105
|
-
style={{ width: "100%", height: "100%" }}
|
|
106
|
-
/>
|
|
107
|
-
</div>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
return (
|
|
111
|
-
<div className="h-100">
|
|
112
|
-
<h5>{dataset.url}</h5>
|
|
113
|
-
<p>Select OBS and VAR</p>
|
|
114
|
-
</div>
|
|
115
|
-
);
|
|
116
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import "bootstrap/dist/css/bootstrap.min.css";
|
|
2
|
-
import Dropdown from "react-bootstrap/Dropdown";
|
|
3
|
-
import { React, useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
-
import Plot from "react-plotly.js";
|
|
5
|
-
import { useDataset, useDatasetDispatch } from "./DatasetContext";
|
|
6
|
-
import { PLOTLY_COLORSCALES } from "./lib/constants/constants";
|
|
7
|
-
|
|
8
|
-
export function HeatmapControls() {
|
|
9
|
-
const dataset = useDataset();
|
|
10
|
-
const dispatch = useDatasetDispatch();
|
|
11
|
-
let [active, setActive] = useState(dataset.colorscale);
|
|
12
|
-
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
setActive(dataset.colorscale);
|
|
15
|
-
}, [dataset.colorscale]);
|
|
16
|
-
|
|
17
|
-
const colormapList = PLOTLY_COLORSCALES.map((item) => (
|
|
18
|
-
<Dropdown.Item
|
|
19
|
-
key={item}
|
|
20
|
-
active={active === item}
|
|
21
|
-
onClick={() => {
|
|
22
|
-
dispatch({
|
|
23
|
-
type: "colorscaleSelected",
|
|
24
|
-
colorscale: item,
|
|
25
|
-
});
|
|
26
|
-
}}
|
|
27
|
-
>
|
|
28
|
-
{item}
|
|
29
|
-
</Dropdown.Item>
|
|
30
|
-
));
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<Dropdown>
|
|
34
|
-
<Dropdown.Toggle id="dropdownColorscale" variant="light">
|
|
35
|
-
{dataset.colorscale}
|
|
36
|
-
</Dropdown.Toggle>
|
|
37
|
-
<Dropdown.Menu>{colormapList}</Dropdown.Menu>
|
|
38
|
-
</Dropdown>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function Heatmap() {
|
|
43
|
-
const dataset = useDataset();
|
|
44
|
-
const colorscale = useRef(dataset.colorscale);
|
|
45
|
-
let [data, setData] = useState([]);
|
|
46
|
-
let [layout, setLayout] = useState({});
|
|
47
|
-
let [hasSelections, setHasSelections] = useState(false);
|
|
48
|
-
|
|
49
|
-
const updateColorscale = useCallback((colorscale) => {
|
|
50
|
-
setData((d) =>
|
|
51
|
-
d.map((i) => {
|
|
52
|
-
return { ...i, colorscale: colorscale };
|
|
53
|
-
})
|
|
54
|
-
);
|
|
55
|
-
}, []);
|
|
56
|
-
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
if (dataset.selectedObs && dataset.selectedMultiVar.length) {
|
|
59
|
-
setHasSelections(true);
|
|
60
|
-
fetch(new URL("heatmap", process.env.REACT_APP_API_URL), {
|
|
61
|
-
method: "POST",
|
|
62
|
-
mode: "cors",
|
|
63
|
-
headers: {
|
|
64
|
-
"Content-Type": "application/json",
|
|
65
|
-
Accept: "application/json",
|
|
66
|
-
},
|
|
67
|
-
body: JSON.stringify({
|
|
68
|
-
url: dataset.url,
|
|
69
|
-
selectedObs: dataset.selectedObs,
|
|
70
|
-
selectedMultiVar: dataset.selectedMultiVar,
|
|
71
|
-
}),
|
|
72
|
-
})
|
|
73
|
-
.then((response) => response.json())
|
|
74
|
-
.then((data) => {
|
|
75
|
-
setData(data.data);
|
|
76
|
-
setLayout(data.layout);
|
|
77
|
-
updateColorscale(colorscale.current);
|
|
78
|
-
});
|
|
79
|
-
} else {
|
|
80
|
-
setHasSelections(false);
|
|
81
|
-
}
|
|
82
|
-
}, [
|
|
83
|
-
dataset.url,
|
|
84
|
-
dataset.selectedObs,
|
|
85
|
-
dataset.selectedMultiVar,
|
|
86
|
-
updateColorscale,
|
|
87
|
-
]);
|
|
88
|
-
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
console.log("update colorscale");
|
|
91
|
-
colorscale.current = dataset.colorscale;
|
|
92
|
-
updateColorscale(colorscale.current);
|
|
93
|
-
}, [dataset.colorscale, updateColorscale]);
|
|
94
|
-
|
|
95
|
-
if (hasSelections) {
|
|
96
|
-
return (
|
|
97
|
-
<div className="container text-center">
|
|
98
|
-
<h5>{dataset.url}</h5>
|
|
99
|
-
<HeatmapControls />
|
|
100
|
-
<Plot
|
|
101
|
-
data={data}
|
|
102
|
-
layout={layout}
|
|
103
|
-
useResizeHandler={true}
|
|
104
|
-
style={{ width: "100%", height: "100%" }}
|
|
105
|
-
/>
|
|
106
|
-
</div>
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
return (
|
|
110
|
-
<div className="h-100">
|
|
111
|
-
<h5>{dataset.url}</h5>
|
|
112
|
-
<p>Select OBS and VAR</p>
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import "bootstrap/dist/css/bootstrap.min.css";
|
|
2
|
-
import "bootstrap/dist/js/bootstrap.bundle.min.js";
|
|
3
|
-
import { React, useEffect, useState } from "react";
|
|
4
|
-
import { useDataset, useDatasetDispatch } from "./DatasetContext";
|
|
5
|
-
|
|
6
|
-
export function ObsColsList() {
|
|
7
|
-
const dataset = useDataset();
|
|
8
|
-
const dispatch = useDatasetDispatch();
|
|
9
|
-
const [obsColsList, setObsColsList] = useState([]);
|
|
10
|
-
let [active, setActive] = useState(null);
|
|
11
|
-
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
fetch(new URL("obs/cols", process.env.REACT_APP_API_URL), {
|
|
14
|
-
method: "POST",
|
|
15
|
-
mode: "cors",
|
|
16
|
-
headers: {
|
|
17
|
-
"Content-Type": "application/json",
|
|
18
|
-
Accept: "application/json",
|
|
19
|
-
},
|
|
20
|
-
body: JSON.stringify({ url: dataset.url }),
|
|
21
|
-
})
|
|
22
|
-
.then((response) => response.json())
|
|
23
|
-
.then((data) => {
|
|
24
|
-
setObsColsList(data);
|
|
25
|
-
});
|
|
26
|
-
}, [dataset.url]);
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
setActive(dataset.selectedObs);
|
|
30
|
-
}, [dataset.selectedObs]);
|
|
31
|
-
|
|
32
|
-
const obsList = obsColsList.map((item) => (
|
|
33
|
-
<button
|
|
34
|
-
type="button"
|
|
35
|
-
key={item}
|
|
36
|
-
className={`list-group-item list-grou-item-action ${
|
|
37
|
-
active === item && "active"
|
|
38
|
-
}`}
|
|
39
|
-
onClick={() => {
|
|
40
|
-
dispatch({
|
|
41
|
-
type: "obsSelected",
|
|
42
|
-
obs: item,
|
|
43
|
-
});
|
|
44
|
-
}}
|
|
45
|
-
>
|
|
46
|
-
{item}
|
|
47
|
-
</button>
|
|
48
|
-
));
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<div className="h-100">
|
|
52
|
-
<h5>{dataset.url}</h5>
|
|
53
|
-
<div className="list-group overflow-auto mh-100">{obsList}</div>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import "bootstrap/dist/css/bootstrap.min.css";
|
|
2
|
-
import { React, useEffect, useState } from "react";
|
|
3
|
-
import { useDataset, useDatasetDispatch } from "./DatasetContext";
|
|
4
|
-
|
|
5
|
-
export function VarNamesList() {
|
|
6
|
-
const dataset = useDataset();
|
|
7
|
-
const dispatch = useDatasetDispatch();
|
|
8
|
-
let [varNames, setVarNames] = useState([]);
|
|
9
|
-
let [active, setActive] = useState([]);
|
|
10
|
-
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
fetch(new URL("var/names", process.env.REACT_APP_API_URL), {
|
|
13
|
-
method: "POST",
|
|
14
|
-
mode: "cors",
|
|
15
|
-
headers: {
|
|
16
|
-
"Content-Type": "application/json",
|
|
17
|
-
Accept: "application/json",
|
|
18
|
-
},
|
|
19
|
-
body: JSON.stringify({ url: dataset.url }),
|
|
20
|
-
})
|
|
21
|
-
.then((response) => response.json())
|
|
22
|
-
.then((data) => {
|
|
23
|
-
setVarNames(data);
|
|
24
|
-
});
|
|
25
|
-
}, [dataset.url]);
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
setActive(dataset.selectedVar);
|
|
29
|
-
}, [dataset.selectedVar]);
|
|
30
|
-
|
|
31
|
-
const varList = varNames.map((item) => (
|
|
32
|
-
<button
|
|
33
|
-
type="button"
|
|
34
|
-
key={item}
|
|
35
|
-
className={`list-group-item list-grou-item-action ${
|
|
36
|
-
active === item && "active"
|
|
37
|
-
}`}
|
|
38
|
-
onClick={() => {
|
|
39
|
-
dispatch({
|
|
40
|
-
type: "varSelected",
|
|
41
|
-
var: item,
|
|
42
|
-
});
|
|
43
|
-
}}
|
|
44
|
-
>
|
|
45
|
-
{item}
|
|
46
|
-
</button>
|
|
47
|
-
));
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<div className="h-100">
|
|
51
|
-
<h5>{dataset.url}</h5>
|
|
52
|
-
<div className="list-group overflow-auto mh-100">{varList}</div>
|
|
53
|
-
</div>
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function MultiVarNamesList() {
|
|
58
|
-
const dataset = useDataset();
|
|
59
|
-
const dispatch = useDatasetDispatch();
|
|
60
|
-
let [varNames, setVarNames] = useState([]);
|
|
61
|
-
let [active, setActive] = useState([]);
|
|
62
|
-
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
fetch(new URL("var/names", process.env.REACT_APP_API_URL), {
|
|
65
|
-
method: "POST",
|
|
66
|
-
mode: "cors",
|
|
67
|
-
headers: {
|
|
68
|
-
"Content-Type": "application/json",
|
|
69
|
-
Accept: "application/json",
|
|
70
|
-
},
|
|
71
|
-
body: JSON.stringify({ url: dataset.url }),
|
|
72
|
-
})
|
|
73
|
-
.then((response) => response.json())
|
|
74
|
-
.then((data) => {
|
|
75
|
-
setVarNames(data);
|
|
76
|
-
});
|
|
77
|
-
}, [dataset.url]);
|
|
78
|
-
|
|
79
|
-
useEffect(() => {
|
|
80
|
-
setActive(dataset.selectedMultiVar);
|
|
81
|
-
}, [dataset.selectedMultiVar]);
|
|
82
|
-
|
|
83
|
-
const varList = varNames.map((item) => (
|
|
84
|
-
<button
|
|
85
|
-
type="button"
|
|
86
|
-
key={item}
|
|
87
|
-
className={`list-group-item list-grou-item-action ${
|
|
88
|
-
active.includes(item) && "active"
|
|
89
|
-
}`}
|
|
90
|
-
onClick={() => {
|
|
91
|
-
if (active.includes(item)) {
|
|
92
|
-
dispatch({
|
|
93
|
-
type: "multiVarDeselected",
|
|
94
|
-
var: item,
|
|
95
|
-
});
|
|
96
|
-
} else {
|
|
97
|
-
dispatch({
|
|
98
|
-
type: "multiVarSelected",
|
|
99
|
-
var: item,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}}
|
|
103
|
-
>
|
|
104
|
-
{item}
|
|
105
|
-
</button>
|
|
106
|
-
));
|
|
107
|
-
|
|
108
|
-
return (
|
|
109
|
-
<div className="h-100">
|
|
110
|
-
<h5>{dataset.url}</h5>
|
|
111
|
-
<div className="list-group overflow-auto mh-100">{varList}</div>
|
|
112
|
-
</div>
|
|
113
|
-
);
|
|
114
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export const PLOTLY_COLORSCALES = [
|
|
2
|
-
"Blackbody",
|
|
3
|
-
"Bluered",
|
|
4
|
-
"Blues",
|
|
5
|
-
"Cividis",
|
|
6
|
-
"Earth",
|
|
7
|
-
"Electric",
|
|
8
|
-
"Greens",
|
|
9
|
-
"Greys",
|
|
10
|
-
"Hot",
|
|
11
|
-
"Jet",
|
|
12
|
-
"Picnic",
|
|
13
|
-
"Portland",
|
|
14
|
-
"Rainbow",
|
|
15
|
-
"RdBu",
|
|
16
|
-
"Reds",
|
|
17
|
-
"Viridis",
|
|
18
|
-
"YlGnBu",
|
|
19
|
-
"YlOrRd",
|
|
20
|
-
];
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useReducer } from "react";
|
|
2
|
-
|
|
3
|
-
export const DatasetContext = createContext(null);
|
|
4
|
-
export const DatasetDispatchContext = createContext(null);
|
|
5
|
-
|
|
6
|
-
export function DatasetProvider({ dataset_url, children }) {
|
|
7
|
-
const [dataset, dispatch] = useReducer(datasetReducer, {
|
|
8
|
-
url: dataset_url,
|
|
9
|
-
selectedObs: null,
|
|
10
|
-
selectedVar: null,
|
|
11
|
-
selectedMultiObs: [],
|
|
12
|
-
selectedMultiVar: [],
|
|
13
|
-
colorscale: "Viridis",
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<DatasetContext.Provider value={dataset}>
|
|
18
|
-
<DatasetDispatchContext.Provider value={dispatch}>
|
|
19
|
-
{children}
|
|
20
|
-
</DatasetDispatchContext.Provider>
|
|
21
|
-
</DatasetContext.Provider>
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function useDataset() {
|
|
26
|
-
return useContext(DatasetContext);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function useDatasetDispatch() {
|
|
30
|
-
return useContext(DatasetDispatchContext);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function datasetReducer(dataset, action) {
|
|
34
|
-
switch (action.type) {
|
|
35
|
-
case "setDataset": {
|
|
36
|
-
return action.dataset;
|
|
37
|
-
}
|
|
38
|
-
case "obsSelected": {
|
|
39
|
-
return { ...dataset, selectedObs: action.obs };
|
|
40
|
-
}
|
|
41
|
-
case "varSelected": {
|
|
42
|
-
return { ...dataset, selectedVar: action.var };
|
|
43
|
-
}
|
|
44
|
-
case "multiVarSelected": {
|
|
45
|
-
return {
|
|
46
|
-
...dataset,
|
|
47
|
-
selectedMultiVar: [...dataset.selectedMultiVar, action.var],
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
case "multiVarDeselected": {
|
|
51
|
-
return {
|
|
52
|
-
...dataset,
|
|
53
|
-
selectedMultiVar: dataset.selectedMultiVar.filter(
|
|
54
|
-
(a) => a !== action.var
|
|
55
|
-
),
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
case "colorscaleSelected": {
|
|
59
|
-
return {
|
|
60
|
-
...dataset,
|
|
61
|
-
colorscale: action.colorscale,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
default: {
|
|
65
|
-
throw Error("Unknown action: " + action.type);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|