My question is as follows:
(a) I am plotting two paths in D3 that have exactly the same coordinates. The same paths.
(b) I would now like to transform one of the paths so that they run parallel and that the 'width' between the paths is always equal to x pixels. My code is as follows:
d3.select("#path2")
.attr("transform", "translate(15,0)");
Unfortunately, the code yields the following:
As you can see the lines are not parallel and are intersecting. In fact it's a bit of a dog's breakfast. I have a feeling this could be alot more complicated than it sounds to achieve. Or is it? Any ideas?
Thank you all
I have a different approach to propose: create two identical paths, like you're doing right now. Then, if you want a distance of, for instance, 16px, set the stroke-width
of one of the paths bigger than that and use the other path as an SVG mask, with a stroke-width
of 16, at the very same position of the other path.
That way, one path will make a "hollow space" in the other one, without any complicated math.
Here is a demo. I put a circle just for showing that the path is hollow:
var svg = d3.select("svg")
var dataset = [
[0, 30],
[20, 30],
[50, 55],
[60, 70],
[100, 120],
[110, 90],
[135, 121],
[200, 70],
[300, 130]
];
var line = d3.line()
.x(function(d) {
return d[0];
})
.y(function(d) {
return d[1];
});
svg.append("circle")
.attr("cx", 200)
.attr("cy", 70)
.attr("r", 30)
.attr("fill", "teal")
var defs = svg.append("defs");
var mask = defs.append("mask")
.attr("id", "pathMask");
mask.append("rect")
.attr("width", 300)
.attr("height", 150)
.attr("fill", "white");
mask.append("path")
.attr("d", line(dataset))
.attr("stroke", "black")
.attr("fill", "none")
.attr("stroke-width", 16);
var path = svg.append("path")
.attr("d", line(dataset))
.attr("mask", "url(#pathMask)")
.attr("stroke", "red")
.attr("stroke-width", 20)
.attr("fill", "none");
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
</svg>
If you don't need a transparent fill, the solution is even easier: draw two paths, one over the other, with different stroke-width
, and fill the upper one (with the smaller stroke width) with the same colour of the background.