Public
Edited
Jul 18, 2023
Fork of Simple D3
1 star
Insert cell
# force network with images and bbox

Mobile: 12 r, 340
Desktop: 16 r, 960
Tablet: 14 r, 540
Insert cell
viewof radius = slider({
min: 0.1,
max: 50,
step: 0.01,
value: 10,
description: "Circle radius"
})
Insert cell
Insert cell
viewof ratioXmargin = slider({
min: 0.01,
max: 1,
step: 0.03,
value: 0.15,
description: "Ratio of height to x margins"
})
Insert cell
viewof width = slider({
min: 300,
max: 1440,
step: 0.01,
value: 340
,
description: "Width of svg image"
})
Insert cell
Insert cell
Insert cell
DOM.download(() => serialize(mobile), undefined, "Save as SVG")
Insert cell
mobile = {
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);

svg.append("rect")
.attr("height", height)
.attr("width", width)
.style("fill", "none")
.style("stroke", "none");

const sim = d3.forceSimulation(nodes)
// .force("collide", d3.forceCollide().radius(d => d.r*2))
// .force("charge", d3.forceManyBody().strength(d => -d.r/2))
.force("collide", d3.forceCollide().radius(d => d.r))
.force("charge", d3.forceManyBody().strength(1))
.force("bounding-circle", () => {
nodes.forEach(node => {
node.x = Math.max(margin.left, Math.min(width - margin.right, node.x));
node.y = Math.max(margin.top, Math.min(height - margin.bottom, node.y));
})
})
.alphaDecay(0.5);
const [node, edge] = draw_nodes(svg, nodes, null, true, false);
// update each node upon simulation tick
sim.on("tick", () => {
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);

node.attr('transform', d => `translate(${d.x},${d.y})`);
});
return svg.node()
}
Insert cell
// chart2 = {
// let width = 250;
// let height = 250;
// const svg = d3.create("svg")
// .attr("width", width)
// .attr("height", height);

// svg.append("rect")
// .attr("height", height)
// .attr("width", width)
// .style("fill", "none")
// .style("stroke", "gray");

// const sim = d3.forceSimulation(nodes)
// // .force("collide", d3.forceCollide().radius(d => d.r*2))
// // .force("charge", d3.forceManyBody().strength(d => -d.r/2))
// .force("collide", d3.forceCollide().radius(d => d.r + 1.5))
// .force("charge", d3.forceManyBody().strength(d => -d.r / 1.5))
// .force("bounding-circle", () => {
// nodes.forEach(node => {
// node.x = Math.max(margin.left, Math.min(width - margin.right, node.x));
// node.y = Math.max(margin.top, Math.min(height - margin.bottom, node.y));
// })
// })
// .alphaDecay(0.9);
// const [node, edge] = draw_nodes(svg, nodes, null, true, false);
// // update each node upon simulation tick
// sim.on("tick", () => {
// node
// .attr("cx", d => d.x)
// .attr("cy", d => d.y);

// node.attr('transform', d => `translate(${d.x},${d.y})`);
// });
// return svg.node()
// }
Insert cell
Insert cell
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
margin = ({ top: ratioYmargin * height, bottom: ratioYmargin * height, left: ratioXmargin * width, right: ratioXmargin * width})
Insert cell
Insert cell
Insert cell
Insert cell
distance = ([x1, y1], [x2, y2]) => Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {serialize} from "@mbostock/saving-svg"
Insert cell
import { slider, button, select, text, radio, checkbox, number } from "@jashkenas/inputs"
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