block by Fil 3eb6ad8e16a83a65c1e86ec8d02e8ed9

Tricontour flower

Full Screen

Simple demonstration of d3-tricontour, reproducing this matplotlib demo.

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
<script src="https://unpkg.com/d3@5"></script>
<script src="https://unpkg.com/d3-delaunay@5"></script>
<script src="https://unpkg.com/d3-tricontour@0.0.6"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
  </style>
</head>

<body>
<script>

  const data = [];
  for (let r = 0; r < 1; r += 0.1)
    for (let angle = 0; angle < 2 * Math.PI; angle += (2 * Math.PI) / 48)
      data.push([
        r * Math.cos(angle),
        r * Math.sin(angle),
        Math.cos(r) * Math.cos(3 * angle) * (r >= 0.1)
      ]);

  const tric = d3.tricontour();
  const contours = tric(data);
  

  
  
  const width = 500, height = 300;
  const show = ["contours", "points", /*"delaunay" */];
  
  const scales = ({
    x: d3.scaleLinear().range(d3.extent(data, d => d[0])),
    y: d3.scaleLinear().range(d3.extent(data, d => d[1])),
    color: d3
      .scaleSequential(d3.interpolateTurbo)
      .domain(d3.extent(data, d => d[2]))
  });
  
  const svg = d3.select("body").append("svg")
    .style("background", "#333")
    .attr("viewBox", [
      scales.x(-1.5 / 20),
      scales.y(-1.5 / 20),
      scales.x(1 + 1.5 / 20) - scales.x(-1.5 / 20),
      scales.y(1 + 1.5 / 20) - scales.y(-1.5 / 20)
    ]);

  const g = svg.append("g");

  const path = d3.geoPath().pointRadius(scales.x(2 / width) - scales.x(0));

  if (show.indexOf("contours") > -1) {
    g.append("g")
      .selectAll("path")
      .data(contours)
      .join("path")
      .attr("d", path)
      .attr("fill", d => scales.color(d.value))
      .attr("fill-opacity", 0.8)
      .append("title")
      .text(d => d.value);
  }

  if (show.indexOf("delaunay") > -1) {
    g.append("path")
      .attr("vector-effect", "non-scaling-stroke")
      .attr("d", d3.Delaunay.from(data).render())
      .attr("fill", "none")
      .attr("stroke-width", 0.5)
      .attr("stroke", "white");
  }

  if (show.indexOf("points") > -1) {
    const pts = g
      .append("g")
      .selectAll("circle")
      .data(data)
      .join("path")
      .attr("d", d => path({ type: "Point", coordinates: d }))
      .attr("fill", d => scales.color(d[2]));
  }
  
  
</script>
</body>