D3JS - 我可以用单个节点制作一个力导向图以及如何制作?

时间:2017-06-12 03:14:53

标签: javascript d3.js

问题:我是否可以单独制作每个节点,然后使用强制布局连接它们?如果没有,我将如何预先放置节点?如果是这样,我可以获得一些语法帮助吗?

背景:我是D3的新手,我正在尝试为一个学术项目的目标网页中的五个节点制作一个强制导向图。我正在使用this示例和this示例,并希望通过将我的节点放在数组中来组合这两者。

例如,我可以这样做:

        var w = 1300;
        var h = 10000;
        //An area for svg elements
        var svgArea = d3.select("body").append("svg")
            .attr("width", w)
            .attr("height", h);

        //All the node definitions
        var nodeMain = svgArea.append("a")
            .attr("height", 300)
            .attr("width", 300)
            .append("circle")
            .attr("r", 300)
            .attr("cx", 650)
            .attr("cy", 700)
            .attr("fill", "orange");

        var nodeMedia = svgArea.append("a")
            .attr("height", 200)
            .attr("width", 200)
            .append("circle")
            .attr("r", 200)
            .attr("cx", 250)
            .attr("cy", 1150)
            .attr("fill", "orange");

        var nodeRef = svgArea.append("a")
            .attr("height", 200)
            .attr("width", 200)
            .append("circle")
            .attr("r", 200)
            .attr("cx", 1050)
            .attr("cy", 1150)
            .attr("fill", "orange");

        //Nodes for the visualization
        var nodes = [nodeMain, nodeMedia, nodeRef];

        //Connected using indices of the array
        var edges = [{source: 1, target: 0}, {source: 2, target: 0}];

        //Force-directed
        var connect = d3.layout.force()
            .size([w, h])
            .gravity(1)             
            .distance(100)
            .charge(-50);

        connect.nodes(nodes).links(edges);

        var orb = svgArea.selectAll(".node").data(nodes)
            .enter().append("g")    
            .call(force.drag);


        var link = svgArea.selectAll(".link").data(edges)
            .enter()
            .append("line")
            .attr("class", "link");

        connect.on("tick", function(){
            link.attr("x1", function(d) {return d.source.x})
                .attr("y1", function(d) {return d.source.y})
                .attr("x2", function(d) {return d.source.x})
                .attr("y2", function(d) {return d.source.y});

            orb.attr("transform", function(d){ return "translate(" + d.x + "," + d.y + ")";});
        });

        connect.start();

(如果我问了一个非常愚蠢的问题,有人会介意指导我一些D3资源,在那里我可以学习更多的概念/语法,而不仅仅依靠实例来模仿/依赖吗?)

提前谢谢大家!

2 个答案:

答案 0 :(得分:0)

我对您的代码段进行了细微更改,并添加了必要的注释。如果有的话,请分享您的疑问。

SELECT B.* FROM
(
    select list_id,user_id ,max(times) times
    from class_history 
    where user_id=8
    group by list_id 
) A INNER JOIN class_history B USING (list_id,user_id,times);
var w = 500;
var h = 500;

//An area for svg elements
var svgArea = d3.select("body").append("svg")
  .attr("width", w)
  .attr("height", h);

//Nodes for the visualization
var nodes = [{
  name: "Main",
  x: 80,
  y: 10
}, {
  name: "Media",
  x: 15,
  y: 40
}, {
  name: "Reference",
  x: 60,
  y: 60
}];

//Connected using indices of the array
var edges = [{
  source: 1,
  target: 0
}, {
  source: 2,
  target: 0
}];

//Force-directed
var connect = d3.layout.force()
  .size([w, h])
  .gravity(1)
  .distance(150)
  .charge(-200);

connect
  .nodes(nodes)
  .links(edges);

//Creating links
var link = svgArea.selectAll(".link")
  .data(edges)
  .enter()
  .append("line")
  .attr("class", "link")
  .style("stroke", "black");

//Creating nodes
var orb = svgArea.selectAll(".node")
  .data(nodes)
  .enter()
  .append("g")
  .attr("class", "node");  

orb.append("circle")
  .attr("r", 10)
  .style("fill", "orange");

//Adding Labels
orb.append("text")
  .attr("dx", 12)
  .attr("dy", ".35em")
  .text(function(d) {
    return d.name
  });
  
//Adding images
orb.append("image")
  .attr("xlink:href", "https://github.com/favicon.ico")
  .attr("x", -10)
  .attr("y", -10)
  .attr("width", 20)
  .attr("height", 20);
  
orb.on("click",function(d){
  alert("clicked "+d.name);
});

connect.on("tick", function() {

  //Updating the link positions during force simulation.
  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
    });

  //Updating the node position during force simulation  
  orb.attr("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")";
  });
});

connect.start();

D3有一个丰富的文档,可在此处找到:GitHub

小提琴:https://jsfiddle.net/gilsha/kv05y1hq/

答案 1 :(得分:0)

如果有任何帮助,我有以下掠夺者......

http://plnkr.co/edit/TiKKmvydqXNipe103juL?p=preview

http://plnkr.co/edit/ZSmvH05nnAD6cYZb0EM4?p=preview

第一个是点击时显示/隐藏元素组。

第二个是演示拖动/缩放。

此外,数据被外部化为json文件并使用...

读入
public class Test {
public static void main(String[] args) {
    System.out.println(tes("s","d","s"));
}

static String tes(String... x)
{
    String y="";
    for(String s:x)
    {
        y=y+s;
    }
    return y;
}
}

这使您可以将节点定义减少到一个函数。