JSFiddle - React, Tailwind, and code Playground
by Ali Khaled
HTML
<svg width="400px" height="200px">
</svg>
CSS
path{
fill: steelblue;
}
svg{
//border: 1px solid #ccc;
}
JavaScript
function chord(sourceX0, sourceX1, sourceY, targetX, targetY){
// Adapted from ProPublica's Quadratic Bezier generator
// http://www.propublica.org/nerds/item/untangling-a-web-of-fec-data
function qBPath(sx, sy, tx, ty) {
var curve = ((tx-sx) * 0.25),
pt = "";
pt += "Q " + (sx) + "," + (sy+curve) + " " + ((sx+tx)/2) +","+ ((sy+ty)/2);
pt += "Q " + (tx) + "," + (ty-curve) + " " + tx + "," + ty;
return pt;
}
var path = '',
padding = 1; // Make the attachment point slightly larger so it can be seen more easily (optional).
// Start off at the top left point
path += 'M' + sourceX0 + ','+ sourceY
// Draw a quadratic bezier curve to the target x,y point
path += qBPath(sourceX0, sourceY, (targetX - padding), targetY);
// Draw a horizontal line the width of the specified padding in order to make the end point visible
path += 'L' + (targetX + padding) + ','+targetY;
// Draw a another quadratic bezier curve back up to the top
path += qBPath(targetX + padding, targetY, sourceX1, sourceY);
// Close the path
path += 'Z';
return path;
}
// Specify the sourceX0, sourceX1, sourceY, targetX, targetY
// where sourceX0 is the starting point and sourceX1 minus sourceX0 is the width
// Tip: One way to figure this out programatically is to plot a bunch of divs, measure each one's page position/width and attach a chord to it.
var chord_path = chord(10, 50, 0, 300, 200);
console.log(chord_path);
// Note, we're using D3 just to add it to the page, but you could also use Raphael.js. The important thing is that we used the `chord` function to generate the SVG path.
d3.select('svg').append('path').attr('d', chord_path);