1

I have included a legend to my Heat Map following this example, built with the threshold scale, and a Linear scale for its axis. The axis is created without issue, the problem is, I believe, in the code where I'm appending its rect elements. Note: heatMap is a svg element.

The D3.js library version I'm using is D3.v5, in case this might be relevant to mention.

function (dataset,xScale,yScale,heatMap,w,h,p,colorScale,colorDomain)
    {
        let variance = dataset.monthlyVariance.map(function(val){
            return val.variance;
        });
        const legendColors= [0,1.4,2.8,5.2,6.6,8,9.4,10.8,12.2,13.6].map((n)=> colorScale(n));
        const minTemp = dataset.baseTemperature + Math.min.apply(null, variance);
        const maxTemp = dataset.baseTemperature + Math.max.apply(null, variance);
        const legendDomain= ((min,max,len)=>
        {
            let arr= [];
            let step=(max-min)/len;
            for (let i=0; i<len; i++)
            {
                let eq=min+i*step;
                arr.push(eq.toFixed(2));
            }
            return arr;
        })(minTemp,maxTemp,legendColors.length);

        //The legend scaling threshold
        let threshold= d3.scaleThreshold()
        .domain(legendDomain)
        .range(legendColors);
        //Legend's axis scaling
        let legendBar= d3.scaleLinear()
        .domain([minTemp,maxTemp])
        .range([0,w/3]);
        **//Legend's axis**
        let legendAxis= d3.axisBottom(legendBar)
        .tickSize(6)
        .tickValues(threshold.domain())
        .tickFormat(d3.format(".1f"));

        //append legend's element
        let legendEle= heatMap.append("g")
        .attr("id","legend")
        .classed("legend",true)
        .attr("transform", `translate(62,${h-p.bottom+60})`);

        //Map legend
        legendEle.append("g")
        .selectAll("rect")
        .data(threshold.range().map(function(color){
          let d = threshold.invertExtent(color);
          if(d[0] == null) d[0] = legendBar.domain()[0];
          if(d[1] == null) d[1] = legendBar.domain()[1];
          return d;
        }))
        .enter()
        .append('rect')
        .attr('x',(d)=> legendAxis(d[0]))
        .attr('y', 0)
        .attr('width', (d)=> legendAxis(d[1])-legendAxis(d[0]))
        .attr('height', 20)
        .attr("fill", function(d) { return threshold(d[0]); });

        //append legend's axis
        legendEle.append("g").call(legendAxis);

        //rect grid map
        heatMap.selectAll("rect")
        .data(dataset.monthlyVariance)
        .enter()
        .append("rect")
        .attr("class","cell")
        .attr('data-month',function(d){
         return d.month;
        })
        .attr('data-year',function(d){
         return d.year;
        })
        .attr('data-temp',function(d){
         return dataset.baseTemperature + d.variance;
        })
        .attr('x', (d)=> xScale(d.year))
        .attr('y', (d)=> yScale(d.month))
        .attr("width", function(d,i){
          return 5;
        })
        .attr("height", function(d,i){
          return yScale.bandwidth(d.month);
        })
        .attr("fill", (d)=> colorScale(dataset.baseTemperature + d.variance))
        .attr("transform", `translate(62,0)`);
    }
  • 1
    This will be happening because of an argument you pass to a d3.js function. Click the line number next to the 'b.selectAll is not a function' error in the console and place a breakpoint there. Once the code stops, you can look at the call stack in the bottom right to see which one of your functions passed in a bad value. – stewartmcgown Apr 21 '19 at 17:26
  • 1
    Found it. Indeed was for the arguments I was passing. Instead of the scaling data points with legendBar, i used legendAxis. Solved – sharkantropo Apr 21 '19 at 18:26

0 Answers0