How to remove white line in d3.js legnd

Viewed 87

How can I remove white line (space) in d3.js legend? I am defining a colorscale range and it works perfectly except it adds white line sapce between values. Here is an example https://jsfiddle.net/aba2s/u46xoh97/1/

function drawLinkLegend(colorscale, min, max) {
    linkLabel.style.display = 'block'
    var legendWidth = 100
        legendMargin = 10
        legendLength = document.getElementById('legend-links-container').offsetHeight - 2*legendMargin

    var legendSvg = d3.select('#legend-links-svg')
                .append('g')
                .attr("id", "linkLegendSvg");

    var dif = colorscale.domain()[1] - colorscale.domain()[0];
    var intervals = d3.range(400).map(function(d,i) {
        return dif * i / 400 + colorscale.domain()[0]
    })
    intervals.push(colorscale.domain()[1]);
    var intervalHeight = legendLength / intervals.length;    
    var bars = legendSvg.selectAll(".bars")
      .data(intervals)
      .enter().append("rect")
        .attr("class", "bars")
        .attr("x", 0)
        .attr("y", function(d, i) { return Math.round((intervals.length - 1 - i)  * intervalHeight) + legendMargin; })
        .attr("height", intervalHeight)
        .attr("width", legendWidth-50)
        .style("fill", function(d, i) { return colorscale(d) })
        .attr("stroke-width",0)
    var legendAxis = d3.scaleLinear()
        .domain([min, max])
        .range([legendLength, 0]);
    legendSvg.append("g")
         .attr("class", "legend axis")
         .attr("transform", "translate(" + (legendWidth - 50) + ", " + legendMargin + ")")
         .call(d3.axisRight().scale(legendAxis).ticks(10))
}
2 Answers

The white lines are comming from the white background, the height of each element is to small or the svg can't render the decimal height and then the background is comes to the front.

You can fix this with (Up-rounding):

        .attr("height", Math.ceil(intervalHeight))

https://jsfiddle.net/falkedesign/1am0b3xu/

When creating your legend, you're setting a height of intervalHeight for each of the legend colour blocks, and you're calculating a y attribute for where to place each of the legend blocks based on that intervalHeight, however, you're rounding that calculated y attribute, which is sometimes making that yvalue higher than it should be, resulting in a gap.

To solve this, you could modify your y to be set to

function(d, i) { return ((intervals.length - 1 - i)  * intervalHeight) + legendMargin; }

without the rounding, or a neat solution I found was to make the height just a little bigger to bridge that gap be setting

.attr("height", intervalHeight + 1)

This way, the height of each bar is a little bit too tall, but it will be masked by the next one anyway. The only visual difference is that the white gap is no longer there.

Related