从 neo4j 中检索节点和关系的密码查询将是:
MATCH p=() <-[:REPORTS8TO]- ()
UNWIND nodes(p) AS n UNWIND rels(p) AS r
WITH n, r ORDER BY n.Name
RETURN {nodes: COLLECT(DISTINCT n), links: COLLECT(DISTINCT {source: id(endNode(r)), target: id(startNode(r))})}
因此,javascript 和 d3 代码:
- 从 json 中提取节点和关系
var obj = JSON.parse(xmlhttp.responseText);
var json = obj.data[0][0];
var nodeMap = {};
json.nodes.forEach(function(x) {
nodeMap[x.id] = x;
nodeMap[x.id].children = [];
});
var links = json.links.map(function(x) {
nodeMap[x.source].children.push(nodeMap[x.target]);
return { source: nodeMap[x.source], target: nodeMap[x.target] };
});
画树
d3.select("#tree").select("svg").remove();
var width = 280, height = 870;
var margin = {
top: 0,
bottom: 0,
left: 10,
right: 120
}
var tree = d3.layout.tree()
.size([height - margin.top - margin.bottom, width - margin.left - margin.right]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var vis = d3.select("#tree").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom )
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Compute the new tree layout from root
var nodes = tree.nodes(root).reverse(), links = tree.links(nodes);
var link = vis.selectAll("path.link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + ", " + d.x + ")"; })
node.append("rect")
.attr("width", 9)
.attr("height", 9)
.attr("y", -4)
.attr("class", function(d) { return "node "+d.type; } );
node.append("text")
.attr("dx", function(d) { return d.children ? -14 : 14; })
.attr("dy", 4)
.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
.attr("class", function(d) {return "node "+d.type+" text"; })
.attr("style", "stroke-wdth: 0.5px; font: 10px sans-serif;")
.text(function(d) { if (d.Name != "Panel") { return d.Name; }});