Published
Edited
Apr 5, 2022
2 forks
29 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function sankeyLinkPath(link) {
// this is a drop in replacement for d3.sankeyLinkHorizontal()
// well, without the accessors/options
let sx = link.source.x1
let tx = link.target.x0 + 1
let sy0 = link.y0 - link.width/2
let sy1 = link.y0 + link.width/2
let ty0 = link.y1 - link.width/2
let ty1 = link.y1 + link.width/2
let halfx = (tx - sx)/2

let path = d3.path()
path.moveTo(sx, sy0)

let cpx1 = sx + halfx
let cpy1 = sy0 + offset
let cpx2 = sx + halfx
let cpy2 = ty0 - offset
path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, tx, ty0)
path.lineTo(tx, ty1)

cpx1 = sx + halfx
cpy1 = ty1 - offset
cpx2 = sx + halfx
cpy2 = sy1 + offset
path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, sx, sy1)
path.lineTo(sx, sy0)
return path.toString()
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
x0 = 100
Insert cell
x1 = x0 + separation
Insert cell
y0 = 70
Insert cell
y1 = 200
Insert cell
h = 70
Insert cell
w = 20
Insert cell
height = 300
Insert cell
colorA = "aquamarine"
Insert cell
colorB = "teal"
Insert cell
strokeWidth = 2*h
Insert cell
function makeGradient(svg, id) {
let defs = d3.select(svg).append("defs")
let linearGradient = defs.append("linearGradient").attr("id", id)
linearGradient.selectAll("stop")
.data([
{offset: "0%", color: d3.rgb(colorA).brighter(0.15) },
{offset: "2%", color: colorA },
{offset: "98%", color: colorB },
{offset: "100%", color: d3.rgb(colorB).brighter(0.15) }
])
.enter().append("stop")
.attr("offset", d => d.offset)
.attr("stop-color", d => d.color)
}
Insert cell
Insert cell
horizontalLink(link)
Insert cell
Insert cell
Insert cell
Insert cell
sankey = {
const sankey = d3.sankey()
.nodeId(d => d.name)
.nodeAlign(d3[`sankey${align[0].toUpperCase()}${align.slice(1)}`])
.nodeWidth(15)
.nodePadding(10)
.extent([[1, 5], [sankeyWidth - 1, height - 5]]);
return ({nodes, links}) => sankey({
nodes: nodes.map(d => Object.assign({}, d)),
links: links.map(d => Object.assign({}, d))
});
}
Insert cell
import {slider} from "@jashkenas/inputs"
Insert cell
Insert cell
import { youtubePlayer } from "@radames/youtube-player-api"
Insert cell
color = {
// https://observablehq.com/@d3/d3-scaleordinal
const color = d3.scaleOrdinal(d3.schemeCategory10);
return d => color(d.category === undefined ? d.name : d.category);
}
Insert cell
format = {
const format = d3.format(",.0f");
return data.units ? d => `${format(d)} ${data.units}` : format;
}
Insert cell
import {energy} from "@d3/sankey"
Insert cell
data = {
const links = energy
const nodes = Array.from(new Set(links.flatMap(l => [l.source, l.target])), name => ({name, category: name.replace(/ .*/, "")}));
return {nodes, links, units: "TWh"};
}
Insert cell
// import {format, data, color} from "@d3/sankey-diagram"
Insert cell
// mport {data} from "@mariodelgadosr/sankey-diagram-with-draggable-nodes"
Insert cell
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