Search code examples
d3.js

How to get rid of stroke lines between cells in D3?


I've been experimenting with D3 for a few days and one of things I could not figure out hot to do, is how to get rid of the the strokes between the cells. My first though was to scale them up a bit, but I can't seem to make it work. Is there any way to get rid of them at all, using some built-in method?

   const generateSvgNode = (width, height) => {
  const svg = d3.create("svg").attr("viewBox", [0, 0, width, height])

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

  const points = d3.range(200).map(function() {
        return [
              Math.random() * width,
              Math.random() * height
        ];
  });

  const delaunay = d3.Delaunay.from(points)
  const voronoi = delaunay.voronoi([0.5, 0.5, width - 0.5, height - 0.5])
  const polygons = voronoi.cellPolygons() 

  const palette = ['#8EB338', '#9DBF3E', '#9BBD3D', '#94B93B', '#9EC03F', '#97BB3B', '#94B93B', '#9EC03F', '#9EC03F', '#9BBD3D', '#A6C542', '#93B83A', '#92B73A', '#9ABE3D', '#96B93B', '#90B439', '#97BB3B', '#93B73B', '#9EC03F', '#97BA3C', '#90B439', '#A1C140', '#9BBD3D', '#90B239', '#95BA3B', '#9EC03F', '#A2C241', '#8FB339', '#93B83A', '#A2C241']


  g.selectAll("path")
    .data(polygons)
    .enter()
    .append("path")
    .attr("d", (d) => `M${d.join("L")}Z`)
    .attr('fill', (d, i) => palette[Math.floor(Math.random()*palette.length)])
    .attr("stroke", 'none')

  

  return svg.node()
}


const onResize = () => {
  document.querySelector('svg').remove();

  const width = window.innerWidth;
  const height = window.innerHeight;
  const svg = generateSvgNode(width, height)
  document.body.appendChild(svg);
}

const onLoad = () => {
  const width = window.innerWidth;
  const height = window.innerHeight;
  const svg = generateSvgNode(width, height)
  document.body.appendChild(svg);
}

window.onload = onLoad;
window.onresize = onResize;
html,
body {
  padding: 0;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.4/d3.min.js"></script>


Solution

  • As a workaround we can set stroke colour to be the same as fill colour, then stroke lines will be indistinguishable. For that we may generate colours deterministically (or alternatively store them for each polygon)

    E.g.:

    const colorGetter = (d,i) => palette[( i + Math.floor((d[0][0] * d[1][1])*1000) ) % palette.length]
      
    g.selectAll("path")
        .data(polygons)
        ...
        .attr("fill", colorGetter)
        .style("stroke-width", 1)
        .attr("stroke", colorGetter)