Published
Edited
May 16, 2022
Insert cell
# Collision simulation
Insert cell
graph = {
const svg = d3.create('svg').attr('height', 500).attr('width', 500)
simulate()
return svg.node()
}
Insert cell
simulate = () => {
const simulation = d3.forceSimulation(data)
.force('charge', d3.forceManyBody().strength(5))
.force('collide', d3.forceCollide().radius(function(d) {
return d.power
}))
.force('center', d3.forceCenter(500/2, 500/2))
.force('x', d3.forceX().x((d) => {
return categoryMapped[d.category]
}))
.on('tick', draw)
}
Insert cell
draw = () => {
let circles = d3.select('svg').selectAll('circle').data(data, d => d.id)
const circlesEnter = circles.enter().append('circle').call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
circles = circlesEnter.merge(circles)
circles.attr('r', d => d.power)
.attr('fill', d => colors(d.category))
.attr('stroke', '#b3a2c8')
.style("stroke-width", 4)
.attr('cx', function(d) {
return d.x
})
.attr('cy', function(d) {
return d.y
})
}
Insert cell
function dragstarted(event, d) {
d.fx = d.x;
d.fy = d.y;
}

Insert cell
function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}
Insert cell
function dragended(event, d) {
d.fx = null;
d.fy = null;
}
Insert cell
zoom = (nodes) => {
}
Insert cell
## Data
Insert cell
data = [{category: 'Fire', id: 1, power: 10}, {category: 'Fire', id: 2, power: 25}, {category: 'Fire', id: 3, power: 32}, {category: 'Fire', id: 4, power: 10}, {category: 'Fire', id: 5, power: 25}, {category: 'Fire', id: 6, power: 32},{category: 'Nature', id: 7, power: 10}, {category: 'Nature', id: 8, power: 25}, {category: 'Nature', id: 9, power: 32}, {category: 'Nature', id: 10, power: 10}, {category: 'Nature', id: 11, power: 25}, {category: 'Nature', id: 12, power: 32}]
Insert cell
categoryMapped = data.reduce((accumulator, current) => {
if (!accumulator[current.category]) {
accumulator[current.category] = 200 * (Object.keys(accumulator).length + 1)
}
return accumulator
},{})
Insert cell
## Utils
Insert cell
d3 = require('d3')
Insert cell
colors = d3.scaleOrdinal()
.domain(Object.keys(categoryMapped).map(d => d.name))
.range(d3.schemeCategory10)
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