d3js v4:力指向グラフにノードを追加します

behas

d3js v4で力指向グラフをレンダリングし、シミュレーションに新しいノードとリンク動的に追加するための関数を提供したい思います。私の最初の試み(以下を参照)には、まだいくつかの大きな問題があります。

  • リンクを追加した後、既存のノードとリンクは力シミュレーションによって無視されているようです
  • シミュレーションノードとリンクおよびそれらのSVG対応物の間のバインディングがどういうわけか機能しません

私はすべての例(例えば、知っていると思う[1 2]をv3のための同様の機能を発揮)が、私はV4でそれを行うしたいと思います。

ご協力いただきありがとうございます!

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3 Test</title>
        <script type="text/javascript" src="js/d3.js"></script>
        <script type="text/javascript" src="js/graph.js"></script>
        <style type="text/css">
            .links line {
                stroke: #aaa;
            }

            .nodes circle {
              pointer-events: all;
              stroke: none;
              stroke-width: 40px;
            }
        </style>
    </head>
    <body>
        <div class="chart-container" style="max-width: 1000px;"></div>

        <button class="expand">Expand graph</button>

        <script type="text/javascript">
            //sample graph dataset
            var graph = {
                "nodes": [
                    {"id": "A"},
                    {"id": "B"},
                    {"id": "C"},
                    {"id": "D"},
                    {"id": "E"},
                    {"id": "F"}
                ],
                "links": [
                    {"source": "B", "target": "A"},
                    {"source": "C", "target": "A"},
                    {"source": "D", "target": "A"},
                    {"source": "D", "target": "C"},
                    {"source": "E", "target": "A"},
                    {"source": "F", "target": "A"}
                ]
            }
            //graph container
            var targetElement = document.querySelector('.chart-container');

            var graph = new Graph(targetElement, graph);

            d3.selectAll('button.expand').on('click', function (){
                var nodes = [
                    {"id": "G", "group": 1}
                ];

                var links = [
                    {"source": "F", "target": "G", "value": 1}
                ];

                graph.expandGraph(links, nodes);
            });

        </script>
    </body>
</html>     

graph.js

var Graph = function(targetElement, graph) {

    var self = this,

        width = targetElement.offsetWidth,

        height = width / 2,

        svg = d3.select(targetElement).append('svg')
            .attr("width", width)
            .attr("height", height),

        simulation = d3.forceSimulation()
                       .force("link", d3.forceLink().id(function(d) { return d.id; }))
                       .force("charge", d3.forceManyBody())
                       .force("center", d3.forceCenter(width / 2, height / 2)),

        link = svg.append("g")
                  .attr("class", "links")
                  .selectAll("line"),

        node = svg.append("g")
                  .attr("class", "nodes")
                  .selectAll("circle"),

        update = function() {

            // Redefine and restart simulation
            simulation.nodes(graph.nodes)
                      .on("tick", ticked);

            simulation.force("link")
                      .links(graph.links);

            // Update links
            link = link.data(graph.links);

            // Enter links
            link = link.enter().append("line");

            // Exit any old links
            link.exit().remove();

            // Update the nodes
            node = node.data(graph.nodes);

            // Enter any new nodes
            node = node.enter().append("circle")
                       .attr("r", 5)
                       .call(d3.drag()
                            .on("start", dragstarted)
                            .on("drag", dragged)
                            .on("end", dragended));

            // Exit any old nodes
            node.exit().remove();

            function ticked() {
                link
                    .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; });

                node
                    .attr("cx", function(d) { return d.x; })
                    .attr("cy", function(d) { return d.y; });
            }


        },

        dragstarted = function(d) {
            if (!d3.event.active) simulation.alphaTarget(0.3).restart();
            d.fx = d.x;
            d.fy = d.y;
        },

        dragged = function(d) {
            d.fx = d3.event.x;
            d.fy = d3.event.y;
        },

        dragended = function(d) {
            if (!d3.event.active) simulation.alphaTarget(0);
            d.fx = null;
            d.fy = null;
        },

        expandGraph = function(links, nodes) {

            for (var i=0; i < nodes.length; i++) {
                console.log('adding node', nodes[i]);
                graph.nodes.push(nodes[i]);
            }

            for (var i=0; i < links.length; i++) {
                console.log('adding link', links[i]);
                graph.links.push(links[i]);
            }

            update();

        };

        // Public functions
        this.expandGraph = expandGraph;

    update();

};
FredTheBread

あなたはmerge()あなたのノードを忘れました私はあなたのコードをすぐに更新しました:

graph.js

var Graph = function(targetElement, graph) {

var self = this,

    width = targetElement.offsetWidth,

    height = width / 2,

    svg = d3.select(targetElement).append('svg')
        .attr("width", width)
        .attr("height", height),

    simulation = d3.forceSimulation()
                   .force("link", d3.forceLink().id(function(d) { return d.id; }))
                   .force("charge", d3.forceManyBody())
                   .force("center", d3.forceCenter(width / 2, height / 2)),

    linkGroup = svg.append("g")
              .attr("class", "links"),

    nodeGroup = svg.append("g")
              .attr("class", "nodes"),

    update = function() {

        // Redefine and restart simulation
        simulation.nodes(graph.nodes)
                  .on("tick", ticked);

        simulation.force("link")
                  .links(graph.links);

        // Update links
        link = linkGroup
            .selectAll("line")
            .data(graph.links);

        // Enter links
        linkEnter = link
            .enter().append("line");

        link = linkEnter
            .merge(link);

        // Exit any old links
        link.exit().remove();

        // Update the nodes
        node = nodeGroup.selectAll("circle").data(graph.nodes);

        // Enter any new nodes
        nodeEnter = node.enter().append("circle")
                   .attr("r", 5)
                   .call(d3.drag()
                        .on("start", dragstarted)
                        .on("drag", dragged)
                        .on("end", dragended));

        node = nodeEnter.merge(node);

        // Exit any old nodes
        node.exit().remove();



        function ticked() {
            link
                .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; });

            node
                .attr("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; });
        }


    },

    dragstarted = function(d) {
        if (!d3.event.active) simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
    },

    dragged = function(d) {
        d.fx = d3.event.x;
        d.fy = d3.event.y;
    },

    dragended = function(d) {
        if (!d3.event.active) simulation.alphaTarget(0);
        d.fx = null;
        d.fy = null;
    },

    expandGraph = function(links, nodes) {

        for (var i=0; i < nodes.length; i++) {
            console.log('adding node', nodes[i]);
            graph.nodes.push(nodes[i]);
        }

        for (var i=0; i < links.length; i++) {
            console.log('adding link', links[i]);
            graph.links.push(links[i]);
        }

        update();

    };

    // Public functions
    this.expandGraph = expandGraph;

update();

};

実際、私はこの新しい関数を100%理解していませんが、常に新しいリンクとノード(つまりlinkEnternodeEnter)を既存のグラフとマージする必要がありますこれを行わないと、古いグラフのようなものが死んでしまいます...

Mike Bostockは、mergeここで使用方法の例を作成しました:https
//bl.ocks.org/mbostock/3808218

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

d3jsを使用して、力有向グラフの特定のノードに子要素を追加する

分類Dev

d3.jsにノードを動的に追加する力指向グラフ

分類Dev

D3v4の力指向グラフ-localStorageはリンクとノードを切断します

分類Dev

D3の力指向グラフ(v4)はノードとしてimgを受け入れていません

分類Dev

D3jsは力指向レイアウトに円を追加します

分類Dev

d3jsグラフに画像を追加できますか?

分類Dev

D3.JS V4は、データを追加/更新した後にグラフ要素を更新します

分類Dev

d3js v3: Selecting a Node on click

分類Dev

d3jsは多数のノードを強制します

分類Dev

Border-radiusプロパティをD3jsドーナツグラフに追加します

分類Dev

新しいノードを追加するD3力指向グラフにより、xとyはNaNになります

分類Dev

D3ノードの色を動的に変更します(力指向グラフ)

分類Dev

D3jsデータ形式

分類Dev

3d.js-力指向グラフのノードを更新

分類Dev

d3jsの線要素に境界線を追加します

分類Dev

更新してD3JSに入力します

分類Dev

ノードがドラッグされたときにd3jsの力指向グラフの揺れを少なくするにはどうすればよいですか?

分類Dev

d3js:d3jsバブルチャートに遷移を適用します

分類Dev

d3jsはノードxyの開始位置を強制します

分類Dev

D3jsはenter()で重複ノードを強制します

分類Dev

d3の力指向グラフに新しいノードのみを追加するにはどうすればよいですか?

分類Dev

scaleTimeを使用したD3JS棒グラフ

分類Dev

折れ線グラフにD3.js(v4)を入力する

分類Dev

d3jsを使用したワードクラウド

分類Dev

データ値を使用してd3js棒グラフに背景色を追加する

分類Dev

d3js v5x軸棒グラフ

分類Dev

d3jsツリーレイアウトのルートノードにクラスを追加する

分類Dev

D3js v4:scaleOrdinalにはrangePoints()がありません

分類Dev

D3jsの力指向グラフでノードのハイライトと遷移効果を実装するにはどうすればよいですか?

Related 関連記事

  1. 1

    d3jsを使用して、力有向グラフの特定のノードに子要素を追加する

  2. 2

    d3.jsにノードを動的に追加する力指向グラフ

  3. 3

    D3v4の力指向グラフ-localStorageはリンクとノードを切断します

  4. 4

    D3の力指向グラフ(v4)はノードとしてimgを受け入れていません

  5. 5

    D3jsは力指向レイアウトに円を追加します

  6. 6

    d3jsグラフに画像を追加できますか?

  7. 7

    D3.JS V4は、データを追加/更新した後にグラフ要素を更新します

  8. 8

    d3js v3: Selecting a Node on click

  9. 9

    d3jsは多数のノードを強制します

  10. 10

    Border-radiusプロパティをD3jsドーナツグラフに追加します

  11. 11

    新しいノードを追加するD3力指向グラフにより、xとyはNaNになります

  12. 12

    D3ノードの色を動的に変更します(力指向グラフ)

  13. 13

    D3jsデータ形式

  14. 14

    3d.js-力指向グラフのノードを更新

  15. 15

    d3jsの線要素に境界線を追加します

  16. 16

    更新してD3JSに入力します

  17. 17

    ノードがドラッグされたときにd3jsの力指向グラフの揺れを少なくするにはどうすればよいですか?

  18. 18

    d3js:d3jsバブルチャートに遷移を適用します

  19. 19

    d3jsはノードxyの開始位置を強制します

  20. 20

    D3jsはenter()で重複ノードを強制します

  21. 21

    d3の力指向グラフに新しいノードのみを追加するにはどうすればよいですか?

  22. 22

    scaleTimeを使用したD3JS棒グラフ

  23. 23

    折れ線グラフにD3.js(v4)を入力する

  24. 24

    d3jsを使用したワードクラウド

  25. 25

    データ値を使用してd3js棒グラフに背景色を追加する

  26. 26

    d3js v5x軸棒グラフ

  27. 27

    d3jsツリーレイアウトのルートノードにクラスを追加する

  28. 28

    D3js v4:scaleOrdinalにはrangePoints()がありません

  29. 29

    D3jsの力指向グラフでノードのハイライトと遷移効果を実装するにはどうすればよいですか?

ホットタグ

アーカイブ