JSFiddle - React, Tailwind, and code Playground

by Dogbert

CSS

body {
  background: white;
}

svg {
  border: 1px solid #ddd;
}

JavaScript

var svg = d3.select(document.body)
  .append("svg")
  .attr("width", 400)
  .attr("height", 400);

createZigZagLine({
    x1: 10,
    y1: 10,
    x2: 375,
    y2: 300,
    steps: 40,
    appendTo: svg
  })
  .attr("stroke", "steelblue")
  .attr("fill", "none");

createZigZagLine({
    x1: 260,
    y1: 10,
    x2: 10,
    y2: 200,
    steps: 10,
    appendTo: svg
  })
  .attr("stroke", "green")
  .attr("fill", "none");

createZigZagLine({
    x1: 50,
    y1: 10,
    x2: 20,
    y2: 320,
    steps: 40,
    appendTo: svg
  })
  .attr("stroke", "violet")
  .attr("fill", "none");

createZigZagLine({
    x1: 100,
    y1: 200,
    x2: 70,
    y2: 70,
    steps: 20,
    appendTo: svg
  })
  .attr("stroke", "red")
  .attr("fill", "none");

function createZigZagLine(options) {
  // Always draw the line from up to down.
  if (options.y1 > options.y2) {
    var tmp;
    tmp = options.y1;
    options.y1 = options.y2;
    options.y2 = tmp;
    tmp = options.x1;
    options.x1 = options.x2;
    options.x2 = tmp;
  }

  var distance = Math.sqrt(Math.pow(options.x1 - options.x2, 2) + Math.pow(options.y1 - options.y2, 2));
  var distanceAxis = Math.sqrt(Math.pow(distance, 2) / 2);
  var dx = distanceAxis / options.steps;
  var dy = distanceAxis / options.steps;
  var datum = [{
    x: options.x1,
    y: options.y1
  }];
  
  for (var i = 0; i < options.steps * 2; i++) {
    var last = datum[datum.length - 1];
    if (i % 2 == 0) {
      datum.push({
        x: last.x,
        y: last.y + dy
      });
    } else {
      datum.push({
        x: last.x + dx,
        y: last.y
      });
    }
  }
  
  var line = d3.svg.line()
    .x(function(d) {
      return d.x;
    })
    .y(function(d) {
      return d.y;
    });
    
  var rotate = 45 - (180 / Math.PI) * Math.atan((options.x2 - options.x1) / (options.y2 - options.y1));
  
  // DEBUG
  options.appendTo.append("circle").attr("cx", options.x1).attr("cy", options.y1).attr("r", 1);
  options.appendTo.append("circle").attr("cx",...