Skip to content Skip to sidebar Skip to footer

D3.js Scatter Plot Connecting Dots With Line

I am new to d3.js and i have been given a task to create a feet like in the image below. I have its X and Y coordinates and I am using scatter plot and line plot to create this but

Solution 1:

Just modified orderSequence to move up/down instead of left/right. Does it help?

const orderSequence = seq => {
    let goUp = false;
    let input = [...seq];
  let output = [input.shift()];
  while(input.length > 0) {
    const last = output[output.length - 1];
    const points = [...input].filter(({y}) => 
        goUp ? y < last.y : y >= last.y);
    if (points.length === 0) {
        goUp = !goUp;
    } else {
      const closest = findClosestPoint(last, points);
      output.push(closest);
      const index = input.findIndex(p => 
        p.x === closest.x && p.y === closest.y);
      input.splice(index, 1);  
    }  
  }

Solution 2:

The orderSequence routine is an example of how to order the sequence of points to form a loop.

The left sequence in the snippet is unordered and the right is an ordered one:

let i;
const randomPoints = [];
for (i = 0; i < 50; i++) {
    const angle = Math.random() * 2 * Math.PI;
  const x = 100 + Math.sin(angle) * 50;
  const y = 75 + Math.cos(angle) * 50;
  randomPoints.push({x, y});
}

const distance = (from, to) => 
    Math.hypot(from.x - to.x, from.y - to.y);
  
const findClosestPoint = (point, seq) => 
    seq.reduce((closest, current) => 
        closest === null ? 
        current : 
        (distance(current, point) < distance(closest, point) ? 
        current : closest), 
      null);

const orderSequence = seq => {
    let goLeft = false;
    let input = [...seq];
  let output = [input.shift()];
  while(input.length > 0) {
    const last = output[output.length - 1];
    const points = [...input].filter(({x}) => 
        goLeft ? x < last.x : x >= last.x);
    if (points.length === 0) {
        goLeft = !goLeft;
    } else {
      const closest = findClosestPoint(last, points);
      output.push(closest);
      const index = input.findIndex(p => 
        p.x === closest.x && p.y === closest.y);
      input.splice(index, 1);  
    }  
  }
  return output;
}

const ordered = orderSequence(randomPoints);

const svg = d3.select('svg')

const drawSequence = (seq, container) => 
    seq.forEach(({x, y}, index) => {
        container.append('circle')
      .attr('cx', x).attr('cy', y)
      .attr('r', 3).style('fill', 'red');
    
  if (index > 0) {
    const prev = seq[index - 1];
    container.append('line')
        .attr('x1', prev.x).attr('y1', prev.y)
      .attr('x2', x).attr('y2', y)
      .style('stroke', 'blue');
  }  
});

const c1 = svg.append('g')
    .attr('transform', 'translate(0, 0)');
drawSequence(randomPoints, c1);

const c2 = svg.append('g')
    .attr('transform', 'translate(200, 0)');
drawSequence(ordered, c2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="150">
  
</svg>

Post a Comment for "D3.js Scatter Plot Connecting Dots With Line"