简体   繁体   中英

D3 centre point of a line (not path)

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?

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');

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> 

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM