Comments (1)
It turned out that this is in fact an issue with the current implementation which uses the stroke width to draw the links - which breaks down if the link is shorter than wide.
You can find more details on this issue here: https://observablehq.com/@enjalot/weird-sankey-links
The solution is to actually draw the outline of the link.
You can find my full solution here: https://stackoverflow.com/a/72593081/2230045
Feel free to use and adapt this code:
/** @type {Function} [linkWidth=d => '0.9'] - A function to return a float to scale the link width. */
export let linkWidth = (d) => 0.9;
/**
* This function is a drop in replacement for d3.sankeyLinkHorizontal().
* Except any accessors/options.
* @param {Object} link - Link object.
* @param {Number} link.y0 - y coordinate for the start of the link.
* @param {Number} link.y1 - y coordinate for the end of the link.
* @param {Number} link.width - Width of the link.
* @param {Object} link.source - Source node object.
* @param {Number} link.source.x1 - x coordinate for the start of the link.
* @param {Object} link.target - Target node object.
* @param {Number} link.target.x0 - x coordinate for the end of the link.
**/
function sankeyLinkPathHorizontal(link) {
// Start and end of the link
let sx1 = link.source.x1;
let tx0 = link.target.x0 + 1;
// All four outer corners of the link
// where e.g. lsy0 is the upper corner of the link on the source side
let lsy0 = link.y0 - (link.width / 2) * linkWidth(link);
let lsy1 = link.y0 + (link.width / 2) * linkWidth(link);
let lty0 = link.y1 - (link.width / 2) * linkWidth(link);
let lty1 = link.y1 + (link.width / 2) * linkWidth(link);
// Center (x) of the link
let lcx = sx1 + (tx0 - sx1) / 2;
// Define outline of link as path
let path = d3.path();
path.moveTo(sx1, lsy0);
path.bezierCurveTo(lcx, lsy0, lcx, lty0, tx0, lty0);
path.lineTo(tx0, lty1);
path.bezierCurveTo(lcx, lty1, lcx, lsy1, sx1, lsy1);
path.lineTo(sx1, lsy0);
return path.toString();
}
/**
* This function is a drop in replacement for d3.sankeyLinkVertical().
* Except any accessors/options.
* @param {Object} link - Link object.
* @param {Number} link.y0 - y coordinate for the start of the link.
* @param {Number} link.y1 - y coordinate for the end of the link.
* @param {Number} link.width - Width of the link.
* @param {Object} link.source - Source node object.
* @param {Number} link.source.x1 - x coordinate for the start of the link.
* @param {Object} link.target - Target node object.
* @param {Number} link.target.x0 - x coordinate for the end of the link.
**/
function sankeyLinkPathVertical(link) {
// Start and end of the link
let sy1 = link.source.x1;
let ty0 = link.target.x0 + 1;
// All four outer corners of the link
// where e.g. lsx0 is the right corner of the link on the source side
let lsx0 = link.y0 - (link.width / 2) * linkWidth(link);
let lsx1 = link.y0 + (link.width / 2) * linkWidth(link);
let ltx0 = link.y1 - (link.width / 2) * linkWidth(link);
let ltx1 = link.y1 + (link.width / 2) * linkWidth(link);
// Center (y) of the link
let lcy = sy1 + (ty0 - sy1) / 2;
// Define outline of link as path
let path = d3.path();
path.moveTo(lsx0, sy1);
path.bezierCurveTo(lsx0, lcy, ltx0, lcy, ltx0, ty0);
path.lineTo(ltx1, ty0);
path.bezierCurveTo(ltx1, lcy, lsx1, lcy, lsx1, sy1);
path.lineTo(lsx0, sy1);
return path.toString();
}
from d3-sankey.
Related Issues (20)
- Support to apply styles to node title HOT 2
- D3 Sankey customization HOT 1
- nodeAlign not aligning the nodes properly HOT 1
- Y coordinates of links control points calculates with error
- Distribute or normalize nodes to fill available space
- Documentation image screenshots look strange with github's dark mode
- Uncaught RangeError: Invalid array length computeNodeBreadths
- Reconsider adding maintainers HOT 1
- Is it possible to sort source or target nodes in one column?
- Little to no activity on this plugin HOT 2
- Issues With Zero Values
- Issues with 0 values
- c.length undefined HOT 3
- what algorithm the sankey uses to arrange the node positions
- Unwanted overlap of multiple/parallel links with sankeyLinkHorizontal
- sankey with mouseover links not working with d3@6 HOT 1
- Different Link Width at Source and Target HOT 3
- sourceLinks `y0` and `y1` calculated the wrong way round HOT 1
- Setting min height of node to avoid overlap issue HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from d3-sankey.