Public
Edited
Mar 30
Insert cell
Insert cell
Insert cell
Insert cell
viewof selected = Inputs.table(search,{required:false})
Insert cell
chart = {
// Specify the dimensions of the chart.
const width = 928;
const height = 680;

// Specify the color scale.
const color = d3.scaleOrdinal(d3.schemeCategory10);

// The force simulation mutates links and nodes, so create a copy
// so that re-evaluating this cell produces the same result.
const links = current_graph.edges.map(d => ({...d}));
const nodes = current_graph.nodes.map(d => ({...d}));

// Create a simulation with several forces.
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id))
.force("charge", d3.forceManyBody())
.force("x", d3.forceX(d => ))
.force("y", d3.forceY())
;

// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "max-width: 100%; height: auto;");

// Add a line for each link, and a circle for each node.
const link = svg.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.join("g")
.call(edge);

const node = svg.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("r", 5)
.attr("fill", d => color(d.group));

node.append("title")
.text(d => d.id);

// Add a drag behavior.
node.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
// Set the position attributes of links and nodes each time the simulation ticks.
let time = 0;
simulation.on("tick", () => {
time++;
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);

const prog = 1 - (time/47 % 1);

link.selectAll("circle")
.attr("r", 2)
.attr("cx", d => d.target.x + (d.source.x - d.target.x) * prog)
.attr("cy", d => d.target.y + (d.source.y - d.target.y) * prog)
.attr("fill", d => "black");

node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
});

// Reheat the simulation when drag starts, and fix the subject position.
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}

// Update the subject (dragged node) position during drag.
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}

// Restore the target alpha so the simulation cools after dragging ends.
// Unfix the subject position now that it’s no longer being dragged.
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}

// When this cell is re-run, stop the previous simulation. (This doesn’t
// really matter since the target alpha is zero and the simulation will
// stop naturally, but it’s a good practice.)
invalidation.then(() => simulation.stop());

return svg.node();
}
Insert cell
edge = {
return selection => {
selection.append("line")
.attr("stroke-width", 11)
.attr("stroke", "white")
selection.append("line")
.attr("stroke-width", 8)
selection.append("circle")
.attr("r", 1)
};
}
Insert cell
selected
Insert cell
Insert cell
data = {

// mat_1 + mat_2 -> result is commutative, but the table contains both versions
// lexical sort mats to dedupe
const data = raw_data.split("\n").map(line => {
const [result, mat_1, mat_2] = line.split("|");
const [m_1, m_2] = [mat_1, mat_2].sort();
return {
m_1,
m_2,
result
}
});

let count = 0;
const deduped = Object.values(data.reduce((deduped, fusion) => {
const key = fusion.m_1 + fusion.m_2;
if (deduped[key]) {
console.log(`skipped ${++count} duplicates`)
return deduped;
}
return {
...deduped,
[key]: fusion
};
},{}));

return deduped;
}
Insert cell
raw_data= fetch("https://gist.githubusercontent.com/jimmcnulty41/36fbf0e46972fd6acabd105b8fc10ed2/raw/488d52fdf1814a781f2b908b03b99d9080e829fb/fmr_data").then((response) => response.text())
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