Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

357
Views
How to get points from a D3 SVG bezier curve with given step size?

So I have a D3 SVG bezier curve like this : enter image description here

I want to get X, Y coordinates of points with given step from the D3 path like so:

enter image description here

So to get an array of coordinate pairs with equal steps. If possible not recalculating bezier curve. How to do such a thing in D3js?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

With the help of a bisection function from here you probably want something like this:

const
  svg = d3.select("svg"),
  width = 512,
  height = 200;
const data = [];
const curve = "curveBasis";

var walk = function() {
  for (let i = 0, v = 2; i < 50; ++i) {
    v += Math.random() - 0.5;
    v = Math.max(Math.min(v, 4), 0);
    data.push({step: i, value: v});
  }
}

walk();

walkX = d3.scaleLinear()
  .domain([0, 49])
  .range([10, width - 10]);

walkY = d3.scaleLinear()
  .domain([0, 4])
  .range([200 - 10, 10]);

const line = d3.line()
  .curve(d3[curve])
  .x(d => walkX(d.step))
  .y(d => walkY(d.value));

svg
  .append("path")
  .attr("id", "svgpath")
  .attr("d", line(data))
  .attr("fill", "none")
  .attr("stroke", "black");

var svgpath = document.getElementById("svgpath");

var findYatXbyBisection = function(x, path, error){
  var length_end = path.getTotalLength(),
  length_start = 0,
  point = path.getPointAtLength((length_end + length_start) / 2), // get the middle point
  bisection_iterations_max = 50,
  bisection_iterations = 0;

  error = error || 0.01;

  while (x < point.x - error || x > point.x + error) {
    // get the middle point
    point = path.getPointAtLength((length_end + length_start) / 2);

    if (x < point.x) {
      length_end = (length_start + length_end)/2;
    } else {
      length_start = (length_start + length_end)/2;
    }

  // Increase iteration
  if (bisection_iterations_max < ++ bisection_iterations)
    break;
  }
  return point.y
}

for (let i = 0; i < data.length; ++i) {
  console.log(findYatXbyBisection(walkX(i), svgpath, 0.01).toFixed(4));
}
<html>
<head>
<meta charset="utf-8" />
<title>SVG Line</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.1.1/d3.min.js" integrity="sha512-COTaPOlz12cG4fSfcBsxZsjauBAyldqp+8FQUM/dZHm+ts/jR4AFoJhCqxy8K10Jrf3pojfsbq7fAPTb1XaVkg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<svg id="chart" width="512" height="200">
</svg>

Do note that Y values returned are SVG coordinates so they start at 0 from the top of page. Check the range function used in the walkY function to refresh how you have to reverse the values for typical line and bar charts in D3.js.

And of course instead of logging to the console you can push the values to your custom array and use different interval value e.g. 1/n of the total line (path) width instead of 1/50 I've used (for 50 data points).

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!