d3使用节点名称为链接强制有向图

时间:2015-11-19 05:39:05

标签: json d3.js

D3.js强制有向图需要格式为

的json数据
{
  "nodes" : [{"name" : "User Login"},
             {"name" : "Appointments"},
             {"name" : "Store Visit"},
             {"name" : "Visit History"},
             {"name" : "Resume Store Visit"}],

 "links" : [{"source" : 1, "target" : 0, "value" : 1},
            {"source" : 2, "target" : 0, "value" : 8},
            {"source" : 3, "target" : 0, "value" : 10},
            {"source" : 3, "target" : 2, "value" : 6},
            {"source" : 4, "target" : 0, "value" : 1}]
};

有没有办法将链接源和目标值指定为节点名称而不是索引?

请注意,我正在尝试根据链接json来渲染图形 链接:[{node1,node2},         {node1,node3}];而不是指定索引等。

1 个答案:

答案 0 :(得分:3)

使用数组映射函数。

var graph = {
  "nodes": [{
    "name": "User Login"
  }, {
    "name": "Appointments"
  }, {
    "name": "Store Visit"
  }, {
    "name": "Visit History"
  }, {
    "name": "Resume Store Visit"
  }],

  "links": [{
    "source": "Appointments",
    "target": "User Login",
    "value": 1
  }, {
    "source": "Store Visit",
    "target": "User Login",
    "value": 8
  }, {
    "source": "Visit History",
    "target": "User Login",
    "value": 10
  }, {
    "source": "Visit History",
    "target": "Store Visit",
    "value": 6
  }, {
    "source": "Resume Store Visit",
    "target": "User Login",
    "value": 1
  }]
};


graph.links = graph.links.map(function(l) {
    var sourceNode = graph.nodes.filter(function(n) {
        return n.name === l.source;
    })[0],
        targetNode = graph.nodes.filter(function(n) {
            return n.name === l.target;
        })[0];

    return {
        source: sourceNode,
        target: targetNode,
        value: l.value
    };
});

var width = 960,
  height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
  .charge(-120)
  .linkDistance(30)
  .size([width, height]);

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);

var graph = {
  "nodes": [{
    "name": "User Login"
  }, {
    "name": "Appointments"
  }, {
    "name": "Store Visit"
  }, {
    "name": "Visit History"
  }, {
    "name": "Resume Store Visit"
  }],

  "links": [{
    "source": "Appointments",
    "target": "User Login",
    "value": 1
  }, {
    "source": "Store Visit",
    "target": "User Login",
    "value": 8
  }, {
    "source": "Visit History",
    "target": "User Login",
    "value": 10
  }, {
    "source": "Visit History",
    "target": "Store Visit",
    "value": 6
  }, {
    "source": "Resume Store Visit",
    "target": "User Login",
    "value": 1
  }]
};

graph.links = graph.links.map(function(l) {
  var sourceNode = graph.nodes.filter(function(n) {
      return n.name === l.source;
    })[0],
    targetNode = graph.nodes.filter(function(n) {
      return n.name === l.target;
    })[0];

  return {
    source: sourceNode,
    target: targetNode,
    value: l.value
  };
});

force
  .nodes(graph.nodes)
  .links(graph.links)
  .start();

var link = svg.selectAll(".link")
  .data(graph.links)
  .enter().append("line")
  .attr("class", "link")
  .style("stroke-width", function(d) {
    return Math.sqrt(d.value);
  });

var node = svg.selectAll(".node")
  .data(graph.nodes)
  .enter().append("circle")
  .attr("class", "node")
  .attr("r", 5)
  .style("fill", function(d) {
    return color(d.group);
  })
  .call(force.drag);

node.append("title")
  .text(function(d) {
    return d.name;
  });

force.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.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;
    });
});
.node {
  stroke: #fff;
  stroke-width: 1.5px;
}
.link {
  stroke: #999;
  stroke-opacity: .6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>