Published
Edited
Dec 15, 2020
1 fork
2 stars
Insert cell
Insert cell
{
const width = 1024;
const height = 720;
var minv = Number.MAX_VALUE, maxv = 0;
for (let i = 1; i < graph.links.length; i++) {
let linkVal = graph.links[i].value;
minv = (linkVal < minv) ? linkVal : minv;
maxv = (linkVal > maxv) ? linkVal : maxv;
}
var minn = Number.MAX_VALUE, maxn = 0;
for (let i = 1; i < graph.nodes.length; i++) {
let nodeVal = graph.nodes[i].value;
minn = (nodeVal < minn) ? nodeVal : minn;
maxn = (nodeVal > maxn) ? nodeVal : maxn;
}
const norm = d => (d.value - minv) / (maxv - minv);
const normN = d => (d.value - minn) / (maxn - minn);

var overLink = null;
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
const link = svg
.selectAll(".link")
.data(graph.links)
.join("line")
.on("mouseover", link_mouseover)
.on("mouseout", link_mouseout)
.on("click", link_click)
.attr("stroke-width", d => Math.max(0.5, 30 * norm(d)) + "px")
.attr("stroke-opacity", d => Math.max(0.05, 100 - 1 / norm(d)));
const node = svg
.selectAll(".node")
.data(graph.nodes);
const nodeEnter = node.enter()
.append("g")
.classed("node", true)
.classed("fixed", d => d.fx !== undefined);
const nodeCircle = nodeEnter
.append("circle")
.attr("r", d => Math.max(6, 36 * normN(d)))
.attr("fill", color);

const nodeText = nodeEnter.append("text")
.text(d => d.id);
yield svg.node();
const simulation = d3
.forceSimulation()
.nodes(graph.nodes)
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.force("link", d3
.forceLink(graph.links)
.id(d => d.id)
.distance(d => Math.min(width/2, 10/(norm(d)+.0001)))
.strength(d => Math.max(0, norm(d))))
.on("tick", tick);

const drag = d3
.drag()
.on("start", dragstart)
.on("drag", dragged);

nodeEnter.call(drag).on("click", click);

function tick() {
const bbox = nodeText.node().getBBox();
const r = nodeCircle.attr("r");
const xr = Math.max(r, bbox.width);
const yr = Math.max(r, bbox.height);
nodeEnter
.attr("transform", d => {
const dx = Math.max(xr, Math.min(width - xr, d.x));
const dy = Math.max(yr, Math.min(height - yr, d.y));
return 'translate(' + [dx, dy] + ')'
});
link
.attr("x1", d => Math.max(xr, Math.min(width - xr, d.source.x)))
.attr("y1", d => Math.max(yr, Math.min(height - yr, d.source.y)))
.attr("x2", d => Math.max(xr, Math.min(width - xr, d.target.x)))
.attr("y2", d => Math.max(yr, Math.min(height - yr, d.target.y)))
.classed("link", d => {
return d !== overLink;
})
.classed("linkover", d => d === overLink);
}

function click(event, d) {
delete d.fx;
delete d.fy;
d3.select(this).classed("fixed", false);
simulation.alpha(1).restart();
}

function dragstart() {
d3.select(this).classed("fixed", true);
}

function dragged(event, d) {
d.fx = clamp(event.x, 0, width);
d.fy = clamp(event.y, 0, height);
simulation.alpha(1).restart();
}
// select target node for new node connection
function link_mouseover(evt) {
overLink = d3.select(this).datum();
tick();
}

function link_mouseout(evt) {
overLink = null;
tick();
}
function link_click(evt) {
const linkData = d3.select(this).datum();
console.log('source: ', linkData.source.id, 'target: ', linkData.target.id);
}
}
Insert cell
d3 = require("d3@6")
Insert cell
height = Math.min(500, width * 0.6)
Insert cell
function clamp(x, lo, hi) {
return x < lo ? lo : x > hi ? hi : x;
}
Insert cell
color = {
const scale = d3.scaleOrdinal(d3.schemeCategory10);
return d => scale(d.group);
}
Insert cell
html`<style>

.link {
stroke: #000;
}

.linkover {
stroke: #f00;
stroke-width: 5px;
stroke-opacity: 100%;
}

.node {
cursor: move;
stroke: #000;
stroke-width: 1.5px;
}

.node.fixed {
fill: #f00;
}

</style>`
Insert cell
graph = ({
"nodes": [
{
"group": 0,
"id": "benzene",
"value": 477
},
{
"group": 1,
"id": "polyimide",
"value": 3171
},
{
"group": 2,
"id": "copolymer",
"value": 4377
},
{
"group": 3,
"id": "hydrogen",
"value": 2084
},
{
"group": 4,
"id": "monomer",
"value": 5659
},
{
"group": 5,
"id": "oligomer",
"value": 1152
},
{
"group": 6,
"id": "styrene",
"value": 689
},
{
"group": 7,
"id": "aromatic",
"value": 3355
},
{
"group": 8,
"id": "polymerization",
"value": 2672
},
{
"group": 9,
"id": "methanol",
"value": 190
},
{
"group": 10,
"id": "refractive index",
"value": 3009
},
{
"group": 11,
"id": "cyano",
"value": 144
},
{
"group": 12,
"id": "heat resistance",
"value": 207
},
{
"group": 13,
"id": "solvent",
"value": 7797
},
{
"group": 14,
"id": "tetrahydrofuran",
"value": 106
}
],
"links": [
{
"source": "benzene",
"target": "benzene",
"value": 477
},
{
"source": "benzene",
"target": "polyimide",
"value": 20
},
{
"source": "benzene",
"target": "copolymer",
"value": 32
},
{
"source": "benzene",
"target": "hydrogen",
"value": 21
},
{
"source": "benzene",
"target": "monomer",
"value": 28
},
{
"source": "benzene",
"target": "oligomer",
"value": 11
},
{
"source": "benzene",
"target": "styrene",
"value": 14
},
{
"source": "benzene",
"target": "aromatic",
"value": 66
},
{
"source": "benzene",
"target": "polymerization",
"value": 27
},
{
"source": "benzene",
"target": "methanol",
"value": 2
},
{
"source": "benzene",
"target": "refractive index",
"value": 1
},
{
"source": "benzene",
"target": "cyano",
"value": 2
},
{
"source": "benzene",
"target": "heat resistance",
"value": 2
},
{
"source": "benzene",
"target": "solvent",
"value": 59
},
{
"source": "benzene",
"target": "tetrahydrofuran",
"value": 1
},
{
"source": "polyimide",
"target": "benzene",
"value": 20
},
{
"source": "polyimide",
"target": "polyimide",
"value": 3171
},
{
"source": "polyimide",
"target": "copolymer",
"value": 106
},
{
"source": "polyimide",
"target": "hydrogen",
"value": 31
},
{
"source": "polyimide",
"target": "monomer",
"value": 127
},
{
"source": "polyimide",
"target": "oligomer",
"value": 26
},
{
"source": "polyimide",
"target": "styrene",
"value": 14
},
{
"source": "polyimide",
"target": "aromatic",
"value": 234
},
{
"source": "polyimide",
"target": "polymerization",
"value": 60
},
{
"source": "polyimide",
"target": "methanol",
"value": 4
},
{
"source": "polyimide",
"target": "refractive index",
"value": 42
},
{
"source": "polyimide",
"target": "cyano",
"value": 5
},
{
"source": "polyimide",
"target": "heat resistance",
"value": 20
},
{
"source": "polyimide",
"target": "solvent",
"value": 339
},
{
"source": "polyimide",
"target": "tetrahydrofuran",
"value": 1
},
{
"source": "copolymer",
"target": "benzene",
"value": 32
},
{
"source": "copolymer",
"target": "polyimide",
"value": 106
},
{
"source": "copolymer",
"target": "copolymer",
"value": 4377
},
{
"source": "copolymer",
"target": "hydrogen",
"value": 68
},
{
"source": "copolymer",
"target": "monomer",
"value": 1037
},
{
"source": "copolymer",
"target": "oligomer",
"value": 66
},
{
"source": "copolymer",
"target": "styrene",
"value": 219
},
{
"source": "copolymer",
"target": "aromatic",
"value": 417
},
{
"source": "copolymer",
"target": "polymerization",
"value": 214
},
{
"source": "copolymer",
"target": "methanol",
"value": 9
},
{
"source": "copolymer",
"target": "refractive index",
"value": 73
},
{
"source": "copolymer",
"target": "cyano",
"value": 15
},
{
"source": "copolymer",
"target": "heat resistance",
"value": 4
},
{
"source": "copolymer",
"target": "solvent",
"value": 456
},
{
"source": "copolymer",
"target": "tetrahydrofuran",
"value": 6
},
{
"source": "hydrogen",
"target": "benzene",
"value": 21
},
{
"source": "hydrogen",
"target": "polyimide",
"value": 31
},
{
"source": "hydrogen",
"target": "copolymer",
"value": 68
},
{
"source": "hydrogen",
"target": "hydrogen",
"value": 2084
},
{
"source": "hydrogen",
"target": "monomer",
"value": 92
},
{
"source": "hydrogen",
"target": "oligomer",
"value": 24
},
{
"source": "hydrogen",
"target": "styrene",
"value": 11
},
{
"source": "hydrogen",
"target": "aromatic",
"value": 93
},
{
"source": "hydrogen",
"target": "polymerization",
"value": 81
},
{
"source": "hydrogen",
"target": "methanol",
"value": 20
},
{
"source": "hydrogen",
"target": "refractive index",
"value": 38
},
{
"source": "hydrogen",
"target": "cyano",
"value": 14
},
{
"source": "hydrogen",
"target": "heat resistance",
"value": 5
},
{
"source": "hydrogen",
"target": "solvent",
"value": 159
},
{
"source": "hydrogen",
"target": "tetrahydrofuran",
"value": 5
},
{
"source": "monomer",
"target": "benzene",
"value": 28
},
{
"source": "monomer",
"target": "polyimide",
"value": 127
},
{
"source": "monomer",
"target": "copolymer",
"value": 1037
},
{
"source": "monomer",
"target": "hydrogen",
"value": 92
},
{
"source": "monomer",
"target": "monomer",
"value": 5659
},
{
"source": "monomer",
"target": "oligomer",
"value": 435
},
{
"source": "monomer",
"target": "styrene",
"value": 122
},
{
"source": "monomer",
"target": "aromatic",
"value": 475
},
{
"source": "monomer",
"target": "polymerization",
"value": 872
},
{
"source": "monomer",
"target": "methanol",
"value": 22
},
{
"source": "monomer",
"target": "refractive index",
"value": 131
},
{
"source": "monomer",
"target": "cyano",
"value": 17
},
{
"source": "monomer",
"target": "heat resistance",
"value": 5
},
{
"source": "monomer",
"target": "solvent",
"value": 919
},
{
"source": "monomer",
"target": "tetrahydrofuran",
"value": 8
},
{
"source": "oligomer",
"target": "benzene",
"value": 11
},
{
"source": "oligomer",
"target": "polyimide",
"value": 26
},
{
"source": "oligomer",
"target": "copolymer",
"value": 66
},
{
"source": "oligomer",
"target": "hydrogen",
"value": 24
},
{
"source": "oligomer",
"target": "monomer",
"value": 435
},
{
"source": "oligomer",
"target": "oligomer",
"value": 1152
},
{
"source": "oligomer",
"target": "styrene",
"value": 13
},
{
"source": "oligomer",
"target": "aromatic",
"value": 70
},
{
"source": "oligomer",
"target": "polymerization",
"value": 91
},
{
"source": "oligomer",
"target": "methanol",
"value": 3
},
{
"source": "oligomer",
"target": "refractive index",
"value": 18
},
{
"source": "oligomer",
"target": "cyano",
"value": 5
},
{
"source": "oligomer",
"target": "heat resistance",
"value": 1
},
{
"source": "oligomer",
"target": "solvent",
"value": 113
},
{
"source": "oligomer",
"target": "tetrahydrofuran",
"value": 0
},
{
"source": "styrene",
"target": "benzene",
"value": 14
},
{
"source": "styrene",
"target": "polyimide",
"value": 14
},
{
"source": "styrene",
"target": "copolymer",
"value": 219
},
{
"source": "styrene",
"target": "hydrogen",
"value": 11
},
{
"source": "styrene",
"target": "monomer",
"value": 122
},
{
"source": "styrene",
"target": "oligomer",
"value": 13
},
{
"source": "styrene",
"target": "styrene",
"value": 689
},
{
"source": "styrene",
"target": "aromatic",
"value": 48
},
{
"source": "styrene",
"target": "polymerization",
"value": 28
},
{
"source": "styrene",
"target": "methanol",
"value": 5
},
{
"source": "styrene",
"target": "refractive index",
"value": 23
},
{
"source": "styrene",
"target": "cyano",
"value": 4
},
{
"source": "styrene",
"target": "heat resistance",
"value": 0
},
{
"source": "styrene",
"target": "solvent",
"value": 56
},
{
"source": "styrene",
"target": "tetrahydrofuran",
"value": 3
},
{
"source": "aromatic",
"target": "benzene",
"value": 66
},
{
"source": "aromatic",
"target": "polyimide",
"value": 234
},
{
"source": "aromatic",
"target": "copolymer",
"value": 417
},
{
"source": "aromatic",
"target": "hydrogen",
"value": 93
},
{
"source": "aromatic",
"target": "monomer",
"value": 475
},
{
"source": "aromatic",
"target": "oligomer",
"value": 70
},
{
"source": "aromatic",
"target": "styrene",
"value": 48
},
{
"source": "aromatic",
"target": "aromatic",
"value": 3355
},
{
"source": "aromatic",
"target": "polymerization",
"value": 196
},
{
"source": "aromatic",
"target": "methanol",
"value": 4
},
{
"source": "aromatic",
"target": "refractive index",
"value": 48
},
{
"source": "aromatic",
"target": "cyano",
"value": 29
},
{
"source": "aromatic",
"target": "heat resistance",
"value": 13
},
{
"source": "aromatic",
"target": "solvent",
"value": 365
},
{
"source": "aromatic",
"target": "tetrahydrofuran",
"value": 2
},
{
"source": "polymerization",
"target": "benzene",
"value": 27
},
{
"source": "polymerization",
"target": "polyimide",
"value": 60
},
{
"source": "polymerization",
"target": "copolymer",
"value": 214
},
{
"source": "polymerization",
"target": "hydrogen",
"value": 81
},
{
"source": "polymerization",
"target": "monomer",
"value": 872
},
{
"source": "polymerization",
"target": "oligomer",
"value": 91
},
{
"source": "polymerization",
"target": "styrene",
"value": 28
},
{
"source": "polymerization",
"target": "aromatic",
"value": 196
},
{
"source": "polymerization",
"target": "polymerization",
"value": 2672
},
{
"source": "polymerization",
"target": "methanol",
"value": 5
},
{
"source": "polymerization",
"target": "refractive index",
"value": 52
},
{
"source": "polymerization",
"target": "cyano",
"value": 11
},
{
"source": "polymerization",
"target": "heat resistance",
"value": 4
},
{
"source": "polymerization",
"target": "solvent",
"value": 392
},
{
"source": "polymerization",
"target": "tetrahydrofuran",
"value": 25
},
{
"source": "methanol",
"target": "benzene",
"value": 2
},
{
"source": "methanol",
"target": "polyimide",
"value": 4
},
{
"source": "methanol",
"target": "copolymer",
"value": 9
},
{
"source": "methanol",
"target": "hydrogen",
"value": 20
},
{
"source": "methanol",
"target": "monomer",
"value": 22
},
{
"source": "methanol",
"target": "oligomer",
"value": 3
},
{
"source": "methanol",
"target": "styrene",
"value": 5
},
{
"source": "methanol",
"target": "aromatic",
"value": 4
},
{
"source": "methanol",
"target": "polymerization",
"value": 5
},
{
"source": "methanol",
"target": "methanol",
"value": 190
},
{
"source": "methanol",
"target": "refractive index",
"value": 2
},
{
"source": "methanol",
"target": "cyano",
"value": 1
},
{
"source": "methanol",
"target": "heat resistance",
"value": 0
},
{
"source": "methanol",
"target": "solvent",
"value": 57
},
{
"source": "methanol",
"target": "tetrahydrofuran",
"value": 7
},
{
"source": "refractive index",
"target": "benzene",
"value": 1
},
{
"source": "refractive index",
"target": "polyimide",
"value": 42
},
{
"source": "refractive index",
"target": "copolymer",
"value": 73
},
{
"source": "refractive index",
"target": "hydrogen",
"value": 38
},
{
"source": "refractive index",
"target": "monomer",
"value": 131
},
{
"source": "refractive index",
"target": "oligomer",
"value": 18
},
{
"source": "refractive index",
"target": "styrene",
"value": 23
},
{
"source": "refractive index",
"target": "aromatic",
"value": 48
},
{
"source": "refractive index",
"target": "polymerization",
"value": 52
},
{
"source": "refractive index",
"target": "methanol",
"value": 2
},
{
"source": "refractive index",
"target": "refractive index",
"value": 3009
},
{
"source": "refractive index",
"target": "cyano",
"value": 0
},
{
"source": "refractive index",
"target": "heat resistance",
"value": 3
},
{
"source": "refractive index",
"target": "solvent",
"value": 106
},
{
"source": "refractive index",
"target": "tetrahydrofuran",
"value": 1
},
{
"source": "cyano",
"target": "benzene",
"value": 2
},
{
"source": "cyano",
"target": "polyimide",
"value": 5
},
{
"source": "cyano",
"target": "copolymer",
"value": 15
},
{
"source": "cyano",
"target": "hydrogen",
"value": 14
},
{
"source": "cyano",
"target": "monomer",
"value": 17
},
{
"source": "cyano",
"target": "oligomer",
"value": 5
},
{
"source": "cyano",
"target": "styrene",
"value": 4
},
{
"source": "cyano",
"target": "aromatic",
"value": 29
},
{
"source": "cyano",
"target": "polymerization",
"value": 11
},
{
"source": "cyano",
"target": "methanol",
"value": 1
},
{
"source": "cyano",
"target": "refractive index",
"value": 0
},
{
"source": "cyano",
"target": "cyano",
"value": 144
},
{
"source": "cyano",
"target": "heat resistance",
"value": 1
},
{
"source": "cyano",
"target": "solvent",
"value": 13
},
{
"source": "cyano",
"target": "tetrahydrofuran",
"value": 0
},
{
"source": "heat resistance",
"target": "benzene",
"value": 2
},
{
"source": "heat resistance",
"target": "polyimide",
"value": 20
},
{
"source": "heat resistance",
"target": "copolymer",
"value": 4
},
{
"source": "heat resistance",
"target": "hydrogen",
"value": 5
},
{
"source": "heat resistance",
"target": "monomer",
"value": 5
},
{
"source": "heat resistance",
"target": "oligomer",
"value": 1
},
{
"source": "heat resistance",
"target": "styrene",
"value": 0
},
{
"source": "heat resistance",
"target": "aromatic",
"value": 13
},
{
"source": "heat resistance",
"target": "polymerization",
"value": 4
},
{
"source": "heat resistance",
"target": "methanol",
"value": 0
},
{
"source": "heat resistance",
"target": "refractive index",
"value": 3
},
{
"source": "heat resistance",
"target": "cyano",
"value": 1
},
{
"source": "heat resistance",
"target": "heat resistance",
"value": 207
},
{
"source": "heat resistance",
"target": "solvent",
"value": 9
},
{
"source": "heat resistance",
"target": "tetrahydrofuran",
"value": 0
},
{
"source": "solvent",
"target": "benzene",
"value": 59
},
{
"source": "solvent",
"target": "polyimide",
"value": 339
},
{
"source": "solvent",
"target": "copolymer",
"value": 456
},
{
"source": "solvent",
"target": "hydrogen",
"value": 159
},
{
"source": "solvent",
"target": "monomer",
"value": 919
},
{
"source": "solvent",
"target": "oligomer",
"value": 113
},
{
"source": "solvent",
"target": "styrene",
"value": 56
},
{
"source": "solvent",
"target": "aromatic",
"value": 365
},
{
"source": "solvent",
"target": "polymerization",
"value": 392
},
{
"source": "solvent",
"target": "methanol",
"value": 57
},
{
"source": "solvent",
"target": "refractive index",
"value": 106
},
{
"source": "solvent",
"target": "cyano",
"value": 13
},
{
"source": "solvent",
"target": "heat resistance",
"value": 9
},
{
"source": "solvent",
"target": "solvent",
"value": 7797
},
{
"source": "solvent",
"target": "tetrahydrofuran",
"value": 28
},
{
"source": "tetrahydrofuran",
"target": "benzene",
"value": 1
},
{
"source": "tetrahydrofuran",
"target": "polyimide",
"value": 1
},
{
"source": "tetrahydrofuran",
"target": "copolymer",
"value": 6
},
{
"source": "tetrahydrofuran",
"target": "hydrogen",
"value": 5
},
{
"source": "tetrahydrofuran",
"target": "monomer",
"value": 8
},
{
"source": "tetrahydrofuran",
"target": "oligomer",
"value": 0
},
{
"source": "tetrahydrofuran",
"target": "styrene",
"value": 3
},
{
"source": "tetrahydrofuran",
"target": "aromatic",
"value": 2
},
{
"source": "tetrahydrofuran",
"target": "polymerization",
"value": 25
},
{
"source": "tetrahydrofuran",
"target": "methanol",
"value": 7
},
{
"source": "tetrahydrofuran",
"target": "refractive index",
"value": 1
},
{
"source": "tetrahydrofuran",
"target": "cyano",
"value": 0
},
{
"source": "tetrahydrofuran",
"target": "heat resistance",
"value": 0
},
{
"source": "tetrahydrofuran",
"target": "solvent",
"value": 28
},
{
"source": "tetrahydrofuran",
"target": "tetrahydrofuran",
"value": 106
}
]
}
)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more