Updating nested elements in d3 when data in a 3D array is modified

Viewed 18

Consider data as a 3D array

function initData() {
    var d = new Array();

    for (var i = 0; i < 3; i++) {
        var data = new Array();
        for (var j = 0; j < 3; j++) {
            data.push( new Array() );
            for (var k = 0; k < 3; k++) {
                data[row].push({
                    i: i,
                    j: j,
                    k: k,
                    focus: false,
                })
            }
        }

        d.push(data);
    }

    return d;
}

This data is bound to nested visual elements as follows

data = initData()
var root = d3.select("body").append("svg")

var X = root.selectAll("g").data(data).join("g")
var Y = X.selectAll("g").data(d => d).join("g")
var Z = Z.selectAll("g").data(d => d).join("rect")
    .attr("x", function(d) { return d.i + d.j + d.k; })
    .attr("y", function(d) { return d.i + d.j + d.k; })
    .attr("width", 8)
    .attr("height", 8)
    .style("fill", function(d) { 
        if (d.focus) {
            return "#ADD8E6"
        }
        return "#fff"; 
    })

This renders correctly. Now if I update the data, say

data[0][0][0].focus = true;

What should I do, to reflect this change in the visual elements as well. I tried

data[0][0][0].focus = true;

X.data(data);
Y.data(d => d);
Z.data(d => d);

This doesn't update the visual elements.

1 Answers

Call the style fn again

Z.data(d => d)
    .style("fill", function(d) { 
        if (d.focus) {
            return "#ADD8E6"
        }
        return "#fff"; 
    })
Related