Reputation: 7490
are a few questions on here and on the D3 site about how you'd find the centre point (or any point) along a path
, however I can't seem to find how to do it with a line
.
I've done a simple jsfiddle here. Essentially I need to add a shape (using text in the jsfiddle to make it clearer) at a point along a line (lets say the middle for simplicity)
So I have a svg:
var canvas = d3.select('body').append('svg').attr('width', 500).attr('height', 500);
And add a line (the position is fixed and doesnt come from data)
var line = canvas.append('line').attr('x1', 50).attr('y1', 50).attr('x2', 250).attr('y2', 150);
The I add some text just to demo to the top and bottom of that line
canvas.append('text').attr('x', line.attr('x1')).attr('y', line.attr('y1')).text('top');
canvas.append('text').attr('x', line.attr('x2')).attr('y', line.attr('y2')).text('bottom');
path
's have methods to get the centre point and width/BBox etc, but line
doesnt seem to.
Anyone have any ideas how this can be achieved?
My initial though was to just get the difference between the x1/x2 values, like this:
canvas.append('text')
.attr('x', parseInt(line.attr('x2') - line.attr('x1')))
.attr('y', parseInt(line.attr('y2') - line.attr('y1')))
.text('just looks a bit off');
But as you'll see from the jsfiddle, it's just off somehow.
Anyone want to point out my mistake?
Upvotes: 1
Views: 754
Reputation: 14591
Line
Use simple mathematics, distance formula.
var canvas = d3.select('body').append('svg').attr('width', 500).attr('height', 500);
var line = canvas.append('line').attr('x1', 50).attr('y1', 50).attr('x2', 250).attr('y2', 150);
var x1 = parseInt(line.attr("x1"));
var y1 = parseInt(line.attr("y1"));
var x2 = parseInt(line.attr("x2"));
var y2 = parseInt(line.attr("y2"));
var midPoint = { x: (x1+x2)/2, y: (y1+y2)/2 };
canvas.append('text').attr('x', midPoint.x).attr('y', midPoint.y).text('X');
line{
stroke:#444;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Path
var canvas = d3.select('body').append('svg').attr('width', 500).attr('height', 500);
var line = canvas.append('path').attr('d', "M 50 50 L 250 150");
var path = line.node();
var midPoint = path.getPointAtLength(path.getTotalLength()/2);
canvas.append('text').attr('x', midPoint.x).attr('y', midPoint.y).text('X');
path{
stroke: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Upvotes: 1
Reputation: 748
I guess, this will work:
var lineData = {x1: 50, y1: 50, x2: 250, y2: 150};
var canvas = d3.select('body').append('svg').attr('width', 500).attr('height', 500);
var line = canvas.append('line').attr('x1', lineData.x1).attr('y1', lineData.y1).attr('x2', lineData.x2).attr('y2', lineData.y2);
console.log(line);
var x = lineData.x1 + Math.abs(lineData.x2 - lineData.x1) / 2;
var y = lineData.y1 + Math.abs(lineData.y2 - lineData.y1) / 2;
console.log([x,y]);
canvas.append('text').attr('x', x).attr('y', y).text('X');
Upvotes: 1
Reputation: 7490
Resolved the issue so thought I'd answer it incase anyone else found the question.
Used getBBox()
of the node (using .node()
). Used that to get the width
, height
and xy
:
var canvas = d3.select('body').append('svg')
.attr('width', 500)
.attr('height', 500);
var line = canvas.append('line')
.attr('x1', 50)
.attr('y1', 150)
.attr('x2', 50)
.attr('y2', 250);
Then the middle x
and y
are:
var midX = line.node().getBBox().x + line.node().getBBox().width / 2;
var midY = line.node().getBBox().y + line.node().getBBox().height / 2;
Upvotes: 0