Demonstration of some odd behaviour of d3-shape's linkTo
and arc
.
The diagrams are generated from the same set of coordinates run through a function that generates variations on paths; for any line from (x0,y0)
to (x1,y1)
, the options are:
curved
: uses one of d3's link
functions, linkHorizontal
, linkVertical
or linkRadial
;direct
: straight line;l_shape
and l_shape_alt
: an L-shaped line, or an arc and straight line if using radial coordinates;dogleg
and dogleg_alt
: a dogleg, or in radial charts, arc-straight line-arc or straight line-arc-straight line.The diagrams demonstrate the odd behaviour of the linkTo
and arc
commands when used in sequence. The uncorrected
radial charts demonstrate the default behaviour, and the corrected
charts have -0.5 Pi radians applied to the angles, i.e. for a line from a
to b
:
context.arc(0, 0, b.y, a.x, b.x);
context.arc(0, 0, b.y, a.x - Math.PI*0.5, b.x - Math.PI*0.5);
xxxxxxxxxx
<head>
<title>Custom paths going off track</title>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="d3-shape.js"></script>
<script src="diagonal-mixin.js"></script>
<style>
.testBox {
float: left;
width: 300px;
margin: 0 0 24px 24px;
padding: 10px;
border: 1px solid #ccc;
text-align: center;
}
path {
fill: none;
stroke: #555;
stroke-width: 1px;
}
.node {
stroke-width: 1px;
stroke: #999;
}
.node.n_0 {
fill: steelblue;
}
.node.n_1 {
fill: deepskyblue;
}
.node.n_2 {
fill: aliceblue;
}
.node.n_3 {
fill: steelblue;
}
.radius {
fill: none;
stroke: #999;
stroke-width: 1px;
stroke-opacity: 0.5;
}
.radius:hover {
stroke-opacity: 1;
}
</style>
</head>
<body>
<h2>Custom path generation</h2>
<div id="test"></div>
<script type="text/javascript">
function go() {
var lineGen = dc.diagonalMixin(dc.orientationMixin(dc.radialLayoutMixin({
_d3: {},
uncorrected: false
})));
lineGen.diagonal('curved');
var points = [{
x: 2.5871939500151235,
y: 156
},
{
x: 2.5871939500151235,
y: 104
},
{
x: 3.9916706657376197,
y: 62
},
{
x: 2.646329811729755,
y: 0
}];
var pt_arr = [1, 2, 3].map(function(e, i) {
return { source: points[i], target: points[e] };
});
[true, true, false].forEach(function(b, i) {
if (!b) {
points.forEach(p => {
p.x = p.x * 180 / Math.PI;
});
}
lineGen.radialLayout(b);
lineGen.uncorrected = (i === 1);
['curved'].concat(Object.keys(dc.link.path)).forEach(function(l) {
lineGen.diagonal(l);
var div = d3.select('#test')
.append('div')
.classed('testBox', true);
div.append('h5')
.text(l + '; ' + (b ?
(lineGen.uncorrected ? 'uncorrected ' : 'corrected ') + 'radial' :
'cartesian'));
var g = div
.append('svg')
.attr('width', 280)
.attr('height', 250)
.append('g')
.attr('transform', function() {
return b ? 'translate(130,90)' : 'translate(-90,60)'
});
g.selectAll('path')
.data(pt_arr)
.enter()
.append("path")
.attr("class", 'cluster-link')
.attr("d", function(d) {
return lineGen._d3.diagonal(d);
});
g.selectAll('circle.node')
.data(points)
.enter()
.append('circle')
.attr('r', 5)
.attr('class', function(d, i) {
return 'node ' + 'n_' + i
})
.attr('transform', function(d) {
return b ?
"translate(" + d3.pointRadial(d.x, d.y) + ")" :
"translate(" + d.x + "," + d.y + ")"
})
.append('title')
.text(function(d, i) { return i });
if (b) {
g.selectAll('circle.radius')
.data(pt_arr)
.enter()
.append('circle')
.attr('class', 'radius')
.attr('fill', 'none')
.attr('r', function(d) {
return d.source.y
});
}
});
});
}
go();
</script>
</body>
</html>
https://d3js.org/d3.v5.min.js