Skip to content

Instantly share code, notes, and snippets.

@brunosiqueira
Created November 8, 2017 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brunosiqueira/c5e6ca06cf88e94430e6160bbc5dc3f4 to your computer and use it in GitHub Desktop.
Save brunosiqueira/c5e6ca06cf88e94430e6160bbc5dc3f4 to your computer and use it in GitHub Desktop.
d3.select('svg').selectAll('*').remove();
let svg = d3.select('svg#sankey');
let width = +window.innerWidth * 0.95;
svg.attr('width', window.innerWidth);
let height = +svg.attr('height');
let formatNumber = d3.format(',.0f'),
format = function (d: any) {
return formatNumber(d) + ' TWh';
},
color = d3.scaleOrdinal(['#8c221b', '#393939', '#d69190']);
let sankeyGraph = sankey()
.nodeWidth(15)
.nodePadding(10)
.extent([[1, 1], [height - 50, width - 1]]);
let link = svg.append('g')
.attr('viewBox', '0 0 ' + Math.min(width, height) + ' ' + Math.min(width, height))
.attr('preserveAspectRatio', 'xMinYMin')
.attr('class', 'links')
.attr('fill', 'none')
.attr('stroke-opacity', 0.2)
.selectAll('path');
let node = svg.append('g')
.attr('class', 'nodes')
.attr('font-family', 'sans-serif')
.attr('font-size', 10)
.selectAll('g');
sankeyGraph(this.sankeyData);
function horizontalSource(d: any): [number, number] {
return [d.y0, d.source.x1];
}
function horizontalTarget(d: any): [number, number] {
return [d.y1, d.target.x0];
}
function wrapText (texts: any) {
texts.each(function() {
let text = d3.select(this);
let words = text.text().split(' ');
if (words.length === 1) {
return;
}
let firstLineCount = Math.ceil(words.length / 2);
let firstLine = words.slice(0, firstLineCount).join(' ');
let secondLine = words.slice(firstLineCount, words.length).join(' ');
let y = text.attr('y'),
x = parseFloat(text.attr('x')),
dy = parseFloat(text.attr('dy'));
text.text(null);
text.append('tspan').attr('x', x + (6 * secondLine.length / 2)).attr('y', y).attr('dy', dy - 0.6 + 'em').text(firstLine);
text.append('tspan').attr('x', x + (6 * firstLine.length / 2)).attr('y', y).attr('dy', dy + 0.6 + 'em').text(secondLine);
});
}
link = link
.data(this.sankeyData.links)
.enter().append('path')
.attr('d', linkVertical()
.source(horizontalSource)
.target(horizontalTarget))
.attr('stroke-width', function (d: any) {
return Math.max(1, d.width);
});
link.append('title')
.text(function (d: any) {
return d.source.name + ' → ' + d.target.name + '\n' + format(d.value);
});
node = node
.data(this.sankeyData.nodes)
.enter().append('g');
function fillColor(d: any) {
if (d.x0 === 1) {
return color(d.name.replace(/ .*/, ''));
} else {
return '#000';
}
}
node.append('rect')
.attr('x', function (d: any) {
return d.y0;
})
.attr('y', function (d: any) {
return d.x0;
})
.attr('height', function (d: any) {
return 40;
})
.attr('width', function (d: any) {
return d.y1 - d.y0;
})
.attr('fill', fillColor)
.attr('stroke', fillColor);
node.append('text')
.attr('y', function (d: any) {
return d.x0 + 20;
})
.attr('x', function (d: any) {
return d.y0 + (d.y1 - d.y0) / 2 - (d.name.length * 6 / 2);
})
.attr('height', function (d: any) {
return d.x1 - d.x0;
})
.attr('width', function (d: any) {
return d.y1 - d.y0;
})
.attr('dy', '0.35em')
.attr('text-anchor', 'end')
.text(function (d: any) {
return d.name.toUpperCase();
})
.attr('fill', function (d: any) {
return '#fff';
})
.filter(function (d: any) {
return d.x0 < width / 2;
})
.attr('text-anchor', 'start');
node.selectAll('text')
.call(wrapText);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment