簡體   English   中英

如何在d3 v4中繪制力圖?

[英]How to draw the force chart in d3 v4?

我是d3的新手,當我學習了如何繪制力圖時,我遇到了一些問題。 首先,讓我們在這里查看我的代碼:

<html>
<head>
<meta charset="UTF-8">
<title>the force chart</title>
</head>
 
<body>
    <script src="http://d3js.org/d3.v4.min.js"></script>
    <script> 
        var width = 400;        
        var height = 400;    
        var svg = d3.select("body")    
                    .append("svg")     
                    .attr("width",width)      
                    .attr("height",height);     
        var nodes = [ { "id": "English" },{ "id": "Italy" },
                      { "id": "America" },{ "id": "Canada" },
                      { "id": "Australia" },{ "id": "Japan" },
                      { "id": "China" } ];
        var edges = [ { "source": 0 , "target": 1 } , { "source": 0 , "target": 2 },
                      { "source": 0 , "target": 3 } , { "source": 1 , "target": 4 },
                      { "source": 1 , "target": 5 } , { "source": 1 , "target": 6 }, ];


        var force = d3.forceSimulation(nodes)  
                    .force("link",d3.forceLink()
                    .id(function(d){return d.id})
                    .distance(function(d){return 150}).strength([-400]))
                    .force("charge",d3.forceManyBody())
                    .force("center",d3.forceCenter(width , height));

            force.restart(); //start

        var svg_edges = svg.selectAll("line")
            .data(edges)
            .enter()
            .append("line")
            .style("stroke","#ccc")
            .style("stroke-width",1);

        var color = d3.scaleOrdinal(d3.schemeCategory20);

        //add nodes
        var svg_nodes = svg.selectAll("circle")
            .data(nodes)
            .enter()
            .append("r",20)
            .style("fill",function(d,i){
                return color(i);
            })
            .call(d3.drag());   //to drag the nodes

        //add information
        var svg_texts = svg.selectAll("text")
            .data(nodes)
            .enter()
            .append("text")
            .style("fill", "black")
            .attr("dx", 20)
            .attr("dy", 8)
            .text(function(d){
                return d.id;
            });

        force.on("tick", function(){ //update the position of lines
            svg_edges.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; })

            //update the position of nodes
            svg_nodes.attr("cx",function(d){ return d.x; })
                .attr("cy",function(d){ return d.y; });

            //update the position of information
            svg_texts.attr("x",function(d){ return d.x; })
                .attr("y",function(d){ return d.y; });

        });
    </script>     
</body>
</html>

我想這樣畫一幅畫: 在此處輸入圖片說明

但是我的代碼只能顯示一個節點,如下所示:

在此處輸入圖片說明

所以我感到困惑,因為開發人員工具中沒有錯誤。 當我布置力時,我推斷出https://github.com/d3/d3-force/blob/master/README.md#links 因此,我解決了不同版本導致的問題。 但是為什么它仍然不起作用? 你可以幫幫我嗎? 如果您能幫助我,我將非常感激! 謝謝!

除了@Vinod已解釋的要點外:

.append("circle")

.force("center", d3.forceCenter(width/2, height/2));

您有逗號結尾。 但是最重​​要的是要顯示邊緣:

首先,將邊緣添加到模擬中:

force.force("link")
    .links(edges);

然后,更改鏈接ID。 目前,沒有名為id屬性。 因此,應為:

.force("link", d3.forceLink()
    .id(function(d,i) {
        return i
    })
    //the rest of the function

這是一個演示:

  var width = 400; var height = 400; var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height); var nodes = [{ "id": "English" }, { "id": "Italy" }, { "id": "America" }, { "id": "Canada" }, { "id": "Australia" }, { "id": "Japan" }, { "id": "China" }]; var edges = [{ "source": 0, "target": 1 }, { "source": 0, "target": 2 }, { "source": 0, "target": 3 }, { "source": 1, "target": 4 }, { "source": 1, "target": 5 }, { "source": 1, "target": 6 }]; var force = d3.forceSimulation() .force("link", d3.forceLink() .id(function(d,i) { return i }) .distance(function(d) { return 150 })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width/2, height/2)); force.restart(); //start var svg_edges = svg.selectAll("line") .data(edges) .enter() .append("line") .style("stroke", "#ccc") .style("stroke-width", 1); var color = d3.scaleOrdinal(d3.schemeCategory20); //add nodes var svg_nodes = svg.selectAll("circle") .data(nodes) .enter() .append("circle") .attr("r", 20) .style("fill", function(d, i) { return color(i); }) .call(d3.drag()); //to drag the nodes //add information var svg_texts = svg.selectAll("text") .data(nodes) .enter() .append("text") .style("fill", "black") .attr("dx", 20) .attr("dy", 8) .text(function(d) { return d.id; }); force.nodes(nodes); force.force("link") .links(edges); force.on("tick", function() { //update the position of lines svg_edges.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; }) //update the position of nodes svg_nodes.attr("cx", function(d) { return dx; }) .attr("cy", function(d) { return dy; }); //update the position of information svg_texts.attr("x", function(d) { return dx; }) .attr("y", function(d) { return dy; }); }); 
 <script src="https://d3js.org/d3.v4.min.js"></script> 

您的代碼中有幾個錯誤

首先,您需要像這樣添加圓圈

  var svg_nodes = svg.selectAll("circle")

        .data(nodes)
        .enter()
        .append("circle")
        .attr("r",20)
        .style("fill",function(d,i){
            return color(i);
        })
        .call(d3.drag());   //to drag the nodes

其中,作為您的代碼附加r,它也不是SVG標簽,因此圖形的中心不應為width和height,而應將其寬度為width / 2和height / 2才能使其居中

看到這個小提琴http://jsfiddle.net/Qh9X5/9515/

類似地,對於使用不具有x,y值的邊數據的線條,您需要傳遞xy值以繪制線條

有關v3.3中完整的解決方案說明,請參閱此https://jsfiddle.net/3uehrfj8/1/,其中包含所有節點和邊緣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM