我在rails中有一个查询,如下所示:
class User < ActiveRecord::Base
has_many :relationships
def self.including_relationships
User.joins("INNER JOIN relationships ON users.id = relationships.source").select("users.name, users.`group`, relationships.source, relationships.target, relationships.value").each_with_object(Hash.new{|h, k| h[k] = []}) do |a, obj|
obj['nodes'] << a.slice('name','group')
obj['links'] << a.slice('source', 'target', 'value')
end
end
end
导致以下json:
{"nodes":[
{"name":"A Voluptatem Quo","group":2},{"name":"Debitis Ut","group":1},{"name":"A Voluptatem Quo","group":2},{"name":"Eos","group":1},{"name":"Eos","group":1},{"name":"Debitis Ut","group":1},{"name":"Debitis Ut","group":1},{"name":"Placeat Aliquam Cumque","group":5},{"name":"Placeat Aliquam Cumque","group":5},{"name":"Placeat Aliquam Cumque","group":5},{"name":"Debitis Ut","group":1},{"name":"Error In","group":4},{"name":"Eos","group":1},{"name":"A Voluptatem Quo","group":2}],
"links":[
{"source":1,"target":1,"value":4},{"source":4,"target":1,"value":4},{"source":1,"target":3,"value":4},{"source":3,"target":5,"value":2},{"source":3,"target":5,"value":4},{"source":4,"target":1,"value":5},{"source":4,"target":5,"value":1},{"source":5,"target":5,"value":2},{"source":5,"target":5,"value":1},{"source":5,"target":3,"value":5},{"source":4,"target":4,"value":3},{"source":2,"target":2,"value":5},{"source":3,"target":1,"value":5},{"source":1,"target":5,"value":2}]}
我希望节点是唯一的,而不是像在这里一样重复。因此我改变了
的代码obj['nodes'] << a.slice('name','group')
到
obj['nodes'] << a.slice('name','group')
obj['nodes'] = obj['nodes'].uniq
那给了我
{"nodes":[{"name":"A Voluptatem Quo","group":2},{"name":"Debitis Ut","group":1},{"name":"Eos","group":1},{"name":"Placeat Aliquam Cumque","group":5},{"name":"Error In","group":4}],"links":[{"source":1,"target":1,"value":4},{"source":4,"target":1,"value":4},{"source":1,"target":3,"value":4},{"source":3,"target":5,"value":2},{"source":3,"target":5,"value":4},{"source":4,"target":1,"value":5},{"source":4,"target":5,"value":1},{"source":5,"target":5,"value":2},{"source":5,"target":5,"value":1},{"source":5,"target":3,"value":5},{"source":4,"target":4,"value":3},{"source":2,"target":2,"value":5},{"source":3,"target":1,"value":5},{"source":1,"target":5,"value":2}]}
太棒了!正是我想要的。虽然现在d3.js没有给我我想要的图表。
查看javascript我得到错误:
Uncaught TypeError: Cannot read property 'weight' of undefined.
然而。如果我不使用uniq,我不会收到此错误。 json看起来格式很好,所以我不知道为什么会出现这个错误。
d3代码如下:
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-10)
.linkDistance(230)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var endpoint = window.location.href+".json"
d3.json(endpoint, function(graph) {
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; });
});
});