D3 - 分层数据集,布局有效,但无法更新数据

时间:2018-06-12 15:04:59

标签: javascript d3.js

见这里。 https://bl.ocks.org/dooglz/9b4d979d31d3ef10ab4f65c085e43b10

我有一个Hierarchical数据集,一些节点有不同数量的子节点,有些节点没有。我想将它显示为一组嵌套的div。我已经在上面的部分中实现了这一点,虽然我不确定我是否已经以最好的方式解决了这个问题。但这就是我想要的样子,布局很好。

每个节点都有一个.val属性,它显示在每个div的.html()的末尾。一些节点的孩子是一组相同的类型',我将它们组合在一起作为选择。再次不确定这是否是实现这一目标的最佳方式。

我遇到的问题是,如果数据发生变化(节点内的值,结构永远不会改变),如果重新运行布局功能,数据在div中不会改变。

我认为我已经完成了嵌套选择错误(https://bost.ocks.org/mike/nest/)并打破了数据链,我不确定如何修复它。

我知道我需要添加额外的

ComputeUnits.html(....); / SimdUnits.html(....); ... etc

某处,但我不确定如何或在哪里。

这里有长寿的原始代码片段:

function hardcoded(){
    let container = d3.select("body");
    let ComputeUnits = container.selectAll(".ComputeUnit")
        .data(data)
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-' + d.id})
        .attr("class",(d)=>{return d.type})
        .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")})
    let Salus = ComputeUnits.selectAll(".SALU")
        .data(function(d) { return d.children.filter(c => c.type == "SALU"); })
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-'+d.id})
        .attr("class",(d)=>{return d.type})
       .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")})
    let SimdUnits = ComputeUnits.selectAll(".SimdUnit")
        .data(function(d) { return d.children.filter(c => c.type == "SimdUnit"); })
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-'+d.id})
        .attr("class",(d)=>{return d.type})
       .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")})
    let SimdLanes = SimdUnits.selectAll(".SimdLane")
        .data(function(d) { return d.children; })
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-'+d.id})
        .attr("class",(d)=>{return d.type})
        .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")})
}

我原以为这会起作用:

    function hardcoded(){
    let container = d3.select("body");
    let ComputeUnits = container.selectAll(".ComputeUnit").data(data);
    ComputeUnits
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-' + d.id})
        .attr("class",(d)=>{return d.type});
    ComputeUnits
        .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")});

    let Salus = ComputeUnits.selectAll(".SALU")
        .data(function(d) { return d.children.filter(c => c.type == "SALU"); });
    Salus
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-'+d.id})
        .attr("class",(d)=>{return d.type});
    Salus
        .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")});

    let SimdUnits = ComputeUnits.selectAll(".SimdUnit")
        .data(function(d) { console.log(1,d); return d.children.filter(c => c.type == "SimdUnit"); });
    SimdUnits
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-'+d.id})
        .attr("class",(d)=>{return d.type});
    SimdUnits
        .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")});

    let SimdLanes = SimdUnits.selectAll(".SimdLane")
        .data(function(d) { console.log(2,d);return d.children; });
    SimdLanes
        .enter().append("div")
        .attr("id", (d)=>{return d.type + '-'+d.id})
        .attr("class",(d)=>{return d.type});
    SimdLanes
        .html((d)=>{return d.type + '-' + d.id+(d.val?("_"+d.val):"")});

但似乎数据更新时,所有.enter()再次触发,但不是更新" .html((d)......"

加分点:我需要将其作为递归函数使用,如块中所示,硬编码方法只是为了清晰起见。

1 个答案:

答案 0 :(得分:0)

我想我找到了一个解决方案,我不知道新的V4更新/合并模式。

此外,关键是: ComputeUnits = ComputeUnits.merge(cuenter)

这似乎应该工作,但它仍然在每个元素上调用.enter(),只要数据变化。但现在它确实调用了Update / merge,所以它看起来很有效。

function hardcoded() {
    let container = d3.select("body");
    let ComputeUnits = container.selectAll(".ComputeUnit").data(data);

    let cuenter = ComputeUnits
        .enter().append("div")
        .attr("id", (d) => {
            return d.type + '-' + d.id
        })
        .attr("class", (d) => {
            return d.type
        });

    ComputeUnits = ComputeUnits.merge(cuenter)
        .text((d) => {
            console.log("cu update");
            return d.type + '-' + d.id + '-' + d.val;
        });

    let Salus = ComputeUnits.selectAll(".SALU")
        .data(function (d) {return d.children.filter(c => (c.type === "SALU"));
        });

    let saenter = Salus
        .enter().append("div")
        .attr("id", (d) => {
            console.log("salu enter")
            return d.type + '-' + d.id
        })
        .attr("class", (d) => {
            return d.type
        });

    Salus = Salus.merge(saenter)
        .text((d) => {
            console.log("salu update");
            return d.type + '-' + d.id + '-' + d.val;
        });

    let SimdUnits = ComputeUnits.selectAll(".SimdUnit")
        .data(function (d) {
            console.log(1, d);
            return d.children.filter(c => c.type === "SimdUnit");
        });

    let suenter = SimdUnits
        .enter().append("div")
        .attr("id", (d) => {
            return d.type + '-' + d.id
        })
        .attr("class", (d) => {
            return d.type
        });

    SimdUnits = SimdUnits.merge(suenter)
        .text((d) => {
            console.log("simdu update");
            return d.type + '-' + d.id + '-' + d.val;
        });

    let SimdLanes = SimdUnits.selectAll(".SimdLane")
        .data(function (d) {
            return d.children;
        });

    let slenter = SimdLanes
        .enter().append("div")
        .attr("id", (d) => {
            return d.type + '-' + d.id
        })
        .attr("class", (d) => {
            return d.type
        });

    SimdLanes = SimdLanes.merge(slenter)
        .text((d) => {
            console.log("siml update");
            return d.type + '-' + d.id + '-' + d.val;
        });
}