-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathBrushableScatterplot.js
52 lines (46 loc) · 1.51 KB
/
BrushableScatterplot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import React, {useRef, useEffect, useState} from "react";
import {Runtime, Inspector} from "@observablehq/runtime";
function BrushableScatterplot({height, setSelection}) {
const ref = useRef();
const [module, setModule] = useState();
useEffect(() => {
async function load() {
// Dynamically load the latest published version of the notebook,
// https://observablehq.com/@d3/brushable-scatterplot.
const {default: notebook} = await import("https://api.observablehq.com/@d3/brushable-scatterplot.js?v=3");
const runtime = new Runtime();
const main = runtime.module(notebook, name => {
// Embed the chart.
if (name === "viewof selection") {
return new Inspector(ref.current);
}
// Propagate selection state from Observable to React.
if (name === "selection") {
return {fulfilled: setSelection};
}
});
setModule(main);
return runtime;
}
const promise = load();
return () => {
promise.then((runtime) => {
setModule(undefined);
runtime.dispose();
});
};
}, []);
// Propagate height state from React to Observable.
useEffect(() => {
if (module !== undefined) {
module.redefine("height", height);
}
}, [height, module]);
return (
<div className="BrushableScatterplot">
<div ref={ref}></div>
<p>Credit: <a href="https://observablehq.com/@d3/brushable-scatterplot">Mike Bostock</a></p>
</div>
);
}
export default BrushableScatterplot;