Mam więc następny kod wykresu układu siły do ustawiania węzłów, linków i innych elementów:
var setLinks = function ()
{
link = visualRoot.selectAll("line.link")
.data(graphData.links)
.enter().append("svg:line")
.attr("class", "link")
.style("stroke-width", function (d) { return nodeStrokeColorDefault; })
.style("stroke", function (d) { return fill(d); })
.attr("x1", function (d) { return d.source.x; })
.attr("y1", function (d) { return d.source.y; })
.attr("x2", function (d) { return d.target.x; })
.attr("y2", function (d) { return d.target.y; });
graphData.links.forEach(function (d)
{
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
};
var setNodes = function ()
{
node = visualRoot.selectAll(".node")
.data(graphData.nodes)
.enter().append("g")
.attr("id", function (d) { return d.id; })
.attr("title", function (d) { return d.name; })
.attr("class", "node")
.on("click", function (d, i) { loadAdditionalData(d.userID, this); })
.call(force.drag)
.on("mouseover", fadeNode(.1)).on("mouseout", fadeNode(1));
};
//append the visual element to the node
var appendVisualElementsToNodes = function ()
{
node.append("circle")
.attr("id", function (d) { return "circleid_" + d.id; })
.attr("class", "circle")
.attr("cx", function (d) { return 0; })
.attr("cy", function (d) { return 0; })
.attr("r", function (d) { return getNodeSize(d); })
.style("fill", function (d) { return getNodeColor(d); })
.style("stroke", function (d) { return nodeStrokeColorDefault; })
.style("stroke-width", function (d) { return nodeStrokeWidthDefault; });
//context menu:
d3.selectAll(".circle").on("contextmenu", function (data, index)
{
d3.select('#my_custom_menu')
.style('position', 'absolute')
.style('left', d3.event.dx + "px")
.style('top', d3.event.dy + "px")
.style('display', 'block');
d3.event.preventDefault();
});
//d3.select("svg").node().oncontextmenu = function(){return false;};
node.append("image")
.attr("class", "image")
.attr("xlink:href", function (d) { return d.profile_image_url; })//"Images/twitterimage_2.png"
.attr("x", -12)
.attr("y", -12)
.attr("width", 24)
.attr("height", 24);
node.append("svg:title")
.text(function (d) { return d.name + "\n" + d.description; });
};
Teraz zmieniły się zależności kolorów i rozmiaru i muszę przerysować koła wykresu (+ wszystkie dołączone elementy) z innym kolorem i promieniem. Mam z tym problem.
Mogę to zrobić:
visualRoot.selectAll(".circle").remove();
ale wciąż mam wszystkie obrazy, do których dołączyłem '.circles'
.
W każdym razie każda pomoc zostanie doceniona, daj mi znać, jeśli wyjaśnienie nie jest wystarczająco jasne, spróbuję to naprawić.
PS Jaka jest różnica między graphData.nodes
i d3.selectAll('.nodes')
?
źródło
Moja pierwsza rada jest taka, że powinieneś przeczytać
d3.js
API o wyborach: https://github.com/mbostock/d3/wiki/SelectionsMusisz zrozumieć, jak
enter()
działa polecenie ( API ). Fakt, że musisz go używać do obsługi nowych węzłów, ma znaczenie, które ci pomoże.Oto podstawowy proces, gdy masz do czynienia z
selection.data()
:najpierw chcesz „dołączyć” jakieś dane do zaznaczenia. Więc masz:
var nodes = visualRoot.selectAll(".node") .data(graphData.nodes)
Następnie możesz modyfikować wszystkie węzły za każdym razem, gdy dane są zmieniane (zrobi to dokładnie to, co chcesz). Jeśli na przykład zmienisz promień starych węzłów, które są w nowym załadowanym zbiorze danych
nodes.attr("r", function(d){return d.radius})
Następnie musisz obsłużyć nowe węzły, w tym celu musisz wybrać nowe węzły, oto co
selection.enter()
jest stworzone dla:var nodesEnter = nodes.enter() .attr("fill", "red") .attr("r", function(d){return d.radius})
Wreszcie na pewno chcesz usunąć węzły, których już nie chcesz, aby to zrobić, musisz je wybrać, do tego właśnie
selection.exit()
służy.var nodesRemove = nodes.exit().remove()
Dobry przykład całego procesu można również znaleźć na wiki API: https://github.com/mbostock/d3/wiki/Selections#wiki-exit
źródło
w ten sposób bardzo łatwo to rozwiązałem,
visualRoot.selectAll(".circle").remove(); visualRoot.selectAll(".image").remove();
a potem po prostu ponownie dodałem elementy wizualne, które były renderowane inaczej, ponieważ kod do obliczania promienia i koloru zmienił właściwości. Dziękuję Ci.
źródło
Jeśli chcesz usunąć sam element, po prostu użyj
element.remove()
, tak jak zrobiłeś. W przypadku, gdy chcesz po prostu usunąć zawartość elementu, ale zachować element tak, jak jest, możesz użyć f.ex.visualRoot.selectAll(".circle").html(null); visualRoot.selectAll(".image").html(null);
zamiast
.html("")
(nie byłem pewien, które dzieci elementu chcesz usunąć). To zachowuje sam element, ale czyści całą zawartą w nim zawartość . Jest to oficjalny sposób , więc powinien działać w różnych przeglądarkach.PS: chciałeś zmienić rozmiary kół. Czy próbowałeś
d3.selectAll(".circle").attr("r", newValue);
źródło
html(null)
nie działa dla mnie w przeglądarce Internet Explorer 11d3.select($0).html('')
z wybranej odpowiedzi również nie działa dla mnie w IE, aled3.select($0).selectAll('*').remove()
działa.Aby usunąć cały element z węzła:
var siblings = element.parentNode.childNodes; for (var i = 0; i < siblings.length; i++) { for (var j = 0; j < siblings.length; j++) { siblings[i].parentElement.removeChild(siblings[j]); } }`
źródło