ノードからすべての子要素を削除してから、異なる色とサイズで再度適用するにはどうすればよいですか?


87

したがって、ノード、リンク、その他の要素を設定するための次の力レイアウトグラフコードがあります。

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

これで、色とサイズの依存関係が変更され、異なる色と半径でグラフの円(+追加されたすべての要素)を再描画する必要があります。問題があります。

私がすることができます:

visualRoot.selectAll(".circle").remove();

'.circles'でも、添付したすべての画像はまだそこにあります。

いずれにせよ、助けていただければ幸いです。説明が十分に明確でない場合はお知らせください。修正を試みます。

PSの違いは何であるgraphData.nodes とはd3.selectAll('.nodes')

回答:


129

あなたの答えはうまくいくでしょうが、後世のために、これらの方法はより一般的です。

HTMLからすべての子を削除します。

d3.select("div.parent").html("");

SVG / HTMLからすべての子を削除します。

d3.select("g.parent").selectAll("*").remove();

この.html("")呼び出しは私のSVGで機能しますが、innerSVGを使用した場合の副作用である可能性があります。


3
残念ながら、.html( "")はSafariでは機能しません。他のすべてのブラウザで正常に動作します。
グリフ2014

1
@glyph:これを行う公式の方法についてはstackoverflow.com/a/43661877/1587329を参照してください
serv-inc

8

私の最初のアドバイスは、d3.js選択に関するAPIを読む必要があるということです:https//github.com/mbostock/d3/wiki/Selections

enter()コマンドがどのように機能するかを理解する必要がありますAPI)。新しいノードを処理するためにそれを使用しなければならないという事実は、あなたを助ける意味を持っています。

これがあなたが扱うときの基本的なプロセスですselection.data()

  • まず、いくつかのデータを選択範囲に「添付」します。だからあなたは持っています:

    var nodes = visualRoot.selectAll(".node")
        .data(graphData.nodes)
    
  • 次に、データが変更されるたびにすべてのノードを変更できます(これにより、必要な処理が正確に実行されます)。たとえば、ロードした新しいデータセットにある古いノードの半径を変更した場合

    nodes.attr("r", function(d){return d.radius})
    
  • 次に、新しいノードを処理する必要があります。このために、新しいノードを選択する必要があります。これがselection.enter()目的です。

    var nodesEnter = nodes.enter()
        .attr("fill", "red")
        .attr("r", function(d){return d.radius})
    
  • 最後に、あなたは確かにあなたがもう必要としないノードを削除したいです、これをするために、あなたはそれらを選択しなければなりません、これはのselection.exit()ために作られているものです。

    var nodesRemove = nodes.exit().remove()
    

プロセス全体の良い例は、API wikiにもあります:https//github.com/mbostock/d3/wiki/Selections#wiki-exit


こんにちはクリス、提案とポイントをありがとう。事実、私は新しいデータを持っていません。データはまだ同じです。すべて同じです。フォースプロセス全体をもう一度やりたくありません。私が理解している限り(私が間違っている場合は訂正してください)。私がしなければならないのは
HotFrost 2013年

私がしなければならないのは、「。circle」クラスとその子を持つdom要素を見つけることだけです。それらを削除します。'.node'クラスでsvg要素を見つけ、 'applyvisualelements'関数で説明されているsvg円およびその他のビジュアルに対して 'attach'プロセスを再適用しますが、今回は半径が計算されるときに、計算方法が異なります。
HotFrost 2013年

とにかく、私はそれを非常に簡単に解決しました、visualRoot.selectAll( "。circle")。remove(); VisualRoot.selectAll( "。image")。remove();
HotFrost 2013年

7

このようにして、私はそれを非常に簡単に解決しました、

visualRoot.selectAll(".circle").remove();
visualRoot.selectAll(".image").remove();

次に、半径と色を計算するためのコードのプロパティが変更されたため、レンダリングが異なる視覚要素を再度追加しました。ありがとうございました。


6

要素自体を削除するelement.remove()場合は、そのまま使用します。要素のコンテンツを削除したいが、要素はそのままにしておく場合は、f.exを使用できます。

visualRoot.selectAll(".circle").html(null);
visualRoot.selectAll(".image").html(null);

代わりに.html("")(どの要素の子を削除したいかわかりませんでした)。これにより、要素自体は保持されますが、含まれているすべてのコンテンツがクリーンアップされます。これを行う公式の方法なので、クロスブラウザで動作する必要があります。

PS:あなたは円のサイズを変更したかった。やってみました

d3.selectAll(".circle").attr("r", newValue);

html(null)Internet Explorer 11で私のために働いていません
ロバート

@Robert:「null値はコンテンツをクリアします。」バグのようです。コンソールに報告されたものはありますか?
SERV-INC

いいえ、エラーや警告はありません。選択したオブジェクトを返すだけです。d3.select($0).html('')選択した回答からの回答は、IEでも機能しませんが、d3.select($0).selectAll('*').remove()機能します。
ロバート

@ロバート:これ報告しますか?
SERV-INC

3

ノードからすべての要素を削除するには:

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

あなたは何かを引用するために継ぎ目があります、ソースは何ですか?
Christopher Chiche 2013年

本当にそれらのノードをすべて自分のノードから削除する必要がありますか?確かに、ノードが現在のノードから外れることはないので、DOMが推奨する方法で十分です。また、引き裂く必要もありません。
2016年

var element = document.getElementById( "top"); while(element.firstChild){element.removeChild(element.firstChild); }
2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.