2015-03-22 2 views
0

У меня есть шесть родительских элементов (6 раз «div»), и я добавляю трех детей, по одному для каждого из трех последних родителей.Как ввести вложенный элемент?

d3.select("body").selectAll("div") 
    .data(["one", "two", "three", "four", "five", "six"]) 
    .enter().append("div") 
    .attr("class", "parent") 
    .text(function (d) { 
    return d; 
}); 

d3.selectAll("div") 
    .filter(function (d, i) { 
    return i > 2 ? true : false; 
}) 
    .append("div") 
    .attr("class", "children") 
    .text(function (d) { 
    return "Name of child: " + d; 
}); 

Это приводит следующий вывод:

one 
two 
three 
four 
Name of child: four 
five 
Name of child: five 
six 
Name of child: six 

Теперь я хочу, чтобы обновить детей на основе данных. Результат должен иметь детей в три, четыре и пять.

Проблема заключается в том, чтобы добавить входной дочерний элемент три в правильном положении в DOM. Например. Следующая попытка:

var newChildren = ["three", "four", "five"]; 

var updateSel = d3.selectAll(".children").data(newChildren, function (d) { 
    return d; 
}); 
updateSel.exit().remove(); 
updateSel.enter().append("div") 
    .attr("class", "children") 
    .text(function (d) { 
    return "Name of child: " + d; 
}); 

вводит дочерние три в неправильном месте, так как родители не указаны в качестве родительского узла.

one 
two 
three 
four 
Name of child: four 
five 
Name of child: five 
six 
Name of child: three 

Here's the JSFiddle.

ответ

1

Ваш updateSel должен основываться на родительских узлах, а не на дочерних узлах, так как это родительские узлы, к которым вы хотите потенциально добавить детей.

Таким образом, ваш первоначальный выбор становится:

var updateSel = d3.selectAll(".parent").data(newChildren, function (d) { 
    return d; 
}); 

Тогда ваша команде удалить придется удалить ребенок вместо узлов в выборе выхода:

updateSel.exit().selectAll("*").remove(); 

Наконец, ваша команда Append должна быть отфильтрована применять только к тем узлам, у которых еще нет детей:

updateSel.filter(function() { 
    return d3.select(this).select(".children").empty(); 
}).append("div") 
    .attr("class", "children") 
    .text(function (d) { 
    return "Name of child: " + d; 
}); 
+0

Спасибо! Это работает отлично! Пока вы ответили на мой вопрос, рассмотрите случай, данные будут связаны только с тремя детьми (а не с родительскими узлами). Было бы здорово, если бы вы могли добавить к своему ответу, как с этим бороться? – ee2Dev

+1

Хм ... если данные не привязаны к родителям, а только к детям, то на каком основании вы могли бы определить, какие родители должны добавлять к ним новых детей? – leekaiinthesky

+0

Вы правы, мой вопрос не указан! В моем заявлении родители имеют одинаковые данные в нем, и, как вы говорите, по уважительной причине. Полагаю, почему я думал об этом направлении изначально и сейчас (на неправильном пути), так это то, что я думал, что мои дети обновляются, а не родители. Но я могу просто реализовать стандартное обновление для детей, если у каждого родителя есть свои дети, поэтому он полностью указан, в моем случае я должен проконсультироваться с родителями :) Большое спасибо, был очень полезен! – ee2Dev

Смежные вопросы