D3 - Иерархический набор данных, макет работает, но не может обновить данные

1

Посмотреть здесь. https://bl.ocks.org/dooglz/9b4d979d31d3ef10ab4f65c085e43b10

У меня есть Иерархический набор данных, некоторые узлы имеют разное количество детей, а некоторые - нет. Я хочу, чтобы это отображалось как набор вложенных div. Я достиг этого в вышеуказанном блоке, хотя я не уверен, что я сделал это наилучшим образом. Но это то, как я хочу, чтобы это выглядело, макет в порядке.

Каждый узел имеет свойство.val, это отображается в конце каждого div.html(). Некоторые дочерние узлы представляют собой набор идентичных "типов", я сгруппировал их вместе как выбор. Опять не уверен, что это лучший способ добиться этого.

Проблема в том, что если данные изменяются (значения внутри узлов, структура никогда не изменяется), данные не изменяются в divs, если функция макета повторно запускается.

Я думаю, что неправильно сделал вложенные выборы (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)..."

Бонусные очки: мне нужно, чтобы это работало как рекурсивная функция, как показано в блоке, жесткий код предназначен только для ясности.

Теги:
d3.js

1 ответ

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;
        });
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню