Home > Software design >  D3.js Heatmap colors based on variable value instead of value for the whole table
D3.js Heatmap colors based on variable value instead of value for the whole table

Time:05-01

I want to create a heatmap which shows the heat/color based on the value of one variable over all groups but not over all variables. Currently I have the following, where the color is based on the value over all values in the map: enter image description here

Thats why almost everything is yellow because the Household net wealth in Luxembourg is just to high. My code for the rectangles is the following:

// Color Scale
var myColor = d3.scaleSequential()
    .interpolator(d3.interpolateViridis)
    .domain([d3.max(data, d=>d.value),d3.min(data, d=>d.value)]);

// add the squares
svg.selectAll()
    .data(data, function (d) { return d.Country   ':'   d.variable; })
    .enter()
    .append("rect")
    .attr("x", function (d) { return x(d.Country) })
    .attr("y", function (d) { return y(d.variable) })
    .attr("rx", 4)
    .attr("ry", 4)
    .attr("width", x.bandwidth())
    .attr("height", y.bandwidth())
    .style("fill", function (d) { return myColor(d.value) })
    .style("stroke-width", 4)
    .style("stroke", "none")
    .style("opacity", 0.8)
    .on("mouseover", mouseover)
    .on("mousemove", mousemove)
    .on("mouseleave", mouseleave)
}

My data is in long format like this:

Country Variable Value
Australia Var 1 Value 1
Australia Var 2 Value 2
... ... ...
Australia Var 24 Value 24
Austria Var 1 Value 25
... ... ...
South Africa Var 24 Value 960

Do you have any ideas of how to change this so this would work? I could also transform the data.

Thanks you so much for your help and have great Tuesday!

CodePudding user response:

I changed the data I am supplying to the front end, by adding two columns: one column regarding the minimum value of the variable over all groups/countries and one column regarding the maximum value of the variable over all groups/countries. My dataset now looks the following way:

Country Variable Value min max
Australia Var 1 Value 1 Min(Var1) Max(Var1)
Australia Var 2 Value 2 Min(Var2) Max(Var2)
... ... ... ... ...
Australia Var 24 Value 24 Min(Var24) Max(Var24)
Austria Var 1 Value 25 Min(Var1) Max(Var1)
... ... ... ... ...
South Africa Var 24 Value 960 Min(Var24) Max(Var24)

By including a function which gives me the color variable based on the current variables min and max value I changed the code to the following:

//Color scale function
function colorPerVariable(minimun, maximum, value) {
        var myColor = d3.scaleSequential()
            .interpolator(d3.interpolateViridis)
            .domain([minimum, maximum]);
        return myColor(value);
}

// add the squares
    svg.selectAll()
        .data(data, function (d) { return d.Country   ':'   d.variable; })
        .enter()
        .append("rect")
        .attr("x", function (d) { return x(d.Country) })
        .attr("y", function (d) { return y(d.variable) })
        .attr("rx", 4)
        .attr("ry", 4)
        .attr("width", x.bandwidth())
        .attr("height", y.bandwidth())
//Changed part
        .style("fill", function (d) { return colorPerVariable(minimum = d.min, maximum = d.max, value = d.value) })
// 
        .style("stroke-width", 4)
        .style("stroke", "none")
        .style("opacity", 0.8)
        .on("mouseover", mouseover)
        .on("mousemove", mousemove)
        .on("mouseleave", mouseleave)
}
  • Related