Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

351
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda