Published
Edited
Jan 11, 2020
4 forks
12 stars
Insert cell
Insert cell
{
const boxHeight = 200;
const svg = d3.create('svg').attr('viewBox', [0, 0, width, boxHeight]);

// Define the arrowhead marker variables
const markerBoxWidth = 20;
const markerBoxHeight = 20;
const refX = markerBoxWidth / 2;
const refY = markerBoxHeight / 2;
const markerWidth = markerBoxWidth / 2;
const markerHeight = markerBoxHeight / 2;
const arrowPoints = [[0, 0], [0, 20], [20, 10]];

const circles = [
{ x: width / 3, y: boxHeight / 1.5, r: 50 },
{ x: width / 1.5, y: boxHeight / 3, r: 50 }
];

// N.B. For horizontal links, the x position of the link must account for circle radius
// and the dimensions of the arrowhead.

// Source node position of the link must account for radius of the circle
const linkSource = {
x: circles[0].x + circles[0].r,
y: circles[0].y
};

// Target node position of the link must account for radius + arrow width
const linkTarget = {
x: circles[1].x - circles[0].r - markerWidth,
y: circles[1].y
};

// Define a horizontal link from the first circle to the second
const link = d3
.linkHorizontal()
.x(d => d.x)
.y(d => d.y)({
source: linkSource,
target: linkTarget
});

// Add the arrowhead marker definition to the svg element
svg
.append('defs')
.append('marker')
.attr('id', 'arrow')
.attr('viewBox', [0, 0, markerBoxWidth, markerBoxHeight])
.attr('refX', refX)
.attr('refY', refY)
.attr('markerWidth', markerBoxWidth)
.attr('markerHeight', markerBoxHeight)
.attr('orient', 'auto-start-reverse')
.append('path')
.attr('d', d3.line()(arrowPoints))
.attr('stroke', 'black');

// Add circles to the svg element
svg
.selectAll('circle')
.data(circles)
.join('circle')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('r', d => d.r)
.style('fill', 'green');

// Add the link with arrowhead at the end
svg
.append('path')
.attr('d', link)
.attr('marker-end', 'url(#arrow)')
.attr('stroke', 'black')
.attr('fill', 'none');

return svg.node();
}
Insert cell
{
const boxHeight = 600;
const svg = d3.create('svg').attr('viewBox', [0, 0, width, boxHeight]);

// Define the arrowhead marker variables
const markerBoxWidth = 20;
const markerBoxHeight = 20;
const refX = markerBoxWidth / 2;
const refY = markerBoxHeight / 2;
const markerWidth = markerBoxWidth / 2;
const markerHeight = markerBoxHeight / 2;
const arrowPoints = [[0, 0], [0, 20], [20, 10]];

const circles = [
{ x: width / 3, y: boxHeight / 1.25, r: 50 },
{ x: width / 1.5, y: boxHeight / 4, r: 50 }
];

// N.B. For vertical links, the y position of the link must account for circle radius
// and the dimensions of the arrowhead.

// Source node position of the link must account for radius of the circle
const linkSource = {
x: circles[0].x,
y: circles[0].y - circles[0].r
};

// Target node position of the link must account for radius + arrow width
const linkTarget = {
x: circles[1].x,
y: circles[1].y + circles[0].r + markerWidth
};

// Define a horizontal link from the first circle to the second
const link = d3
.linkVertical()
.x(d => d.x)
.y(d => d.y)({
source: linkSource,
target: linkTarget
});

// Add the arrowhead marker definition to the svg element
svg
.append('defs')
.append('marker')
.attr('id', 'arrow')
.attr('viewBox', [0, 0, markerBoxWidth, markerBoxHeight])
.attr('refX', refX)
.attr('refY', refY)
.attr('markerWidth', markerBoxWidth)
.attr('markerHeight', markerBoxHeight)
.attr('orient', 'auto-start-reverse')
.append('path')
.attr('d', d3.line()(arrowPoints))
.attr('stroke', 'black');

// Add circles to the svg element
svg
.selectAll('circle')
.data(circles)
.join('circle')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('r', d => d.r)
.style('fill', 'green');

// Add the link with arrowhead at the end
svg
.append('path')
.attr('d', link)
.attr('marker-end', 'url(#arrow)')
.attr('stroke', 'black')
.attr('fill', 'none');

return svg.node();
}
Insert cell
d3 = require('d3')
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