2013-07-24 65 views
5

Tôi đã tạo đồ thị có hướng lực với plugin d3.js và tôi muốn tô màu các nút và các nhãn có màu khác nhau theo nhóm mà chúng thuộc về.D3.js lực lượng đồ thị hướng, mỗi nhóm màu sắc khác nhau?

Tôi đã thêm quy mô cho màu:

var color = d3.scale.category20(); 

và đến nút biến Tôi đã thêm:

.style("fill", function(d) { return color(d.group); }) 

nhưng tất cả các nút trong cùng một màu sắc ..

đây là tình trạng hiện tại của tôi: http://jsfiddle.net/WBkw9/

toàn bộ tập lệnh:

var links = [ 
    {source: "John", target: "Mike", group: "5"}, 
    {source: "John", target: "Janice", group: "5"}, 
    {source: "John", target: "Caleb", group: "5"}, 
    {source: "John", target: "Anna", group: "4"}, 
    {source: "John", target: "Tommy", group: "3"}, 
    {source: "John", target: "Jack", group: "2"}, 
    {source: "John", target: "Vilma", group: "1"}, 
]; 

var nodes = {}; 

// Compute the distinct nodes from the links. 
links.forEach(function(link) { 
    link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); 
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); 
}); 

var color = d3.scale.category20(); 

var width = 960, 
    height = 500; 

var force = d3.layout.force() 
    .nodes(d3.values(nodes)) 
    .links(links) 
    .size([width, height]) 
    .linkDistance(60) 
    .charge(-300) 
    .on("tick", tick) 
    .start(); 

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

var link = svg.selectAll(".link") 
    .data(force.links()) 
    .enter().append("line") 
    .attr("class", "link"); 

var node = svg.selectAll(".node") 
    .data(force.nodes()) 
    .enter().append("g") 
    .attr("class", "node") 
    .style("fill", function(d) { return color(d.group); }) 
    .on("mouseover", mouseover) 
    .on("mouseout", mouseout) 
    .call(force.drag); 

node.append("circle") 
    .attr("r", 8); 

node.append("text") 
    .attr("x", 12) 
    .attr("dy", ".35em") 
    .text(function(d) { return d.name; }); 

function tick() { 
    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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 
} 

function mouseover() { 
    d3.select(this).select("circle").transition() 
     .duration(750) 
     .attr("r", 16); 
} 

function mouseout() { 
    d3.select(this).select("circle").transition() 
     .duration(750) 
     .attr("r", 8); 
} 

Tôi thiếu gì cho các màu khác nhau trên mỗi nhóm?

Trả lời

3

Vấn đề của bạn là group không được xác định cho dữ liệu của bạn. Kết quả là, tất cả các nút của bạn được tô màu cho nhóm 'không xác định'. Vòng kết nối của bạn được xác định cho dữ liệu trong force.nodes(), có các thuộc tính indexnamepxpyweightxy. group chỉ được xác định cho các liên kết, không bao giờ có màu được áp dụng cho chúng.

Vì nó hiện đang đứng, cũng không phải là một cách rõ ràng để xác định màu sắc một nút nên được. Điều gì sẽ xảy ra nếu nhiều liên kết kết nối với một nút và các liên kết này nằm trong các nhóm khác nhau?

0

Tôi nghĩ bạn cần thay đổi thuộc tính kiểu của vòng tròn, chứ không phải thành phần g.

node.append("circle").style("fill", function(d) { return color(d.group); }) 

Edit: Thuộc tính nhóm trong các dữ liệu cũng phải được thay đổi số nguyên, hoặc đúc sau.

+0

điều này chỉ thay đổi màu theo cách đó để chỉ nút được tô màu và không phải toàn bộ văn bản. Nhưng điều này vẫn không giải quyết được vấn đề của tôi, http://jsfiddle.net/F2fbu/. Tôi muốn nhận được mọi nhóm màu khác nhau, bây giờ dường như với tôi rằng tôi không thể làm điều này với loại dữ liệu đó vì tôi cần xác định nhóm nào là nút nào ... – dzordz

+0

Nhóm phải là một số nguyên chứ không phải là một chuỗi. 'd3.selectAll (" circle ") style (" fill ", function (d) {return color (9)})' thay đổi màu của tất cả các vòng tròn. – user4815162342

0

Bạn đã bao giờ giải quyết vấn đề này chưa? nếu không phải là một giải pháp khả thi là ở đây: http://jsfiddle.net/adeaver/F2fbu/1/

Mỗi nhóm/nút được màu sắc khác nhau cùng với các văn bản tương ứng bằng cách thêm: .style("fill", function(d) { return color(d.group); }) đến append văn bản và group: link.group đến chức năng mà tính các nút từ các liên kết

4

Đây là mã của tôi (dựa trên http://bl.ocks.org/mbostock/4062045). Nó hoạt động hoàn hảo. Bạn có thể thấy nó trông như thế nào ở đây: http://jsfiddle.net/Rom2BE/H2PkT/

Mỗi nhóm có một màu khác nhau.

**index.html** 

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

.node { 
    stroke: #fff; 
    stroke-width: 1.5px; 
} 

.link { 
    stroke: #999; 
    stroke-opacity: .6; 
} 

</style> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 

var width = 650, 
    height = 700; 

var color = d3.scale.category10(); 

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); 

d3.json("data.json", function(error, 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); }); 

    // You define here your nodes and the color will be d.group 
    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); 

    //Display node name when mouse on a node 
    node.append("title") 
     .text(function(d) { return d.name; }); 

    //Where and how nodes are displayed 
    force.on("tick", function() { 
    node.attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 

    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; }); 
    }); 

    //Legend 
    var legend = svg.selectAll(".legend") 
     .data(color.domain()) 
    .enter().append("g") 
     .attr("class", "legend") 
     .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); 

    legend.append("rect") 
     .attr("x", width - 18) 
     .attr("width", 18) 
     .attr("height", 18) 
     .style("fill", color); 

    legend.append("text") 
     .attr("x", width - 24) 
     .attr("y", 9) 
     .attr("dy", ".35em") 
     .style("text-anchor", "end") 
     .text(function(d) { return d; }); 
}); 

</script> 


**data.json** 

{"nodes":[ 
    {"name":"Vertex 5","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 9","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 15","group":"Virtuals-MacBook-Pro-3-53688"},{"name":"Vertex 20","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 26","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 29","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 33","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 37","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 49","group":"Virtuals-MacBook-Pro-3-53688"},{"name":"Vertex 52","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 53","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 58","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 59","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 65","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 73","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 74","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 80","group":"Virtuals-MacBook-Pro-36095"},{"name":"Vertex 84","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 87","group":"Virtuals-MacBook-Pro-4-40842"},{"name":"Vertex 99","group":"Virtuals-MacBook-Pro-4-40842"} 
], 
"links":[ 
    {"source":5,"value":1,"target":11},{"source":5,"value":1,"target":12},{"source":10,"value":1,"target":12},{"source":11,"value":1,"target":5},{"source":11,"value":1,"target":12},{"source":11,"value":1,"target":14},{"source":12,"value":1,"target":5},{"source":12,"value":1,"target":10},{"source":12,"value":1,"target":11},{"source":14,"value":1,"target":11},{"source":16,"value":1,"target":19},{"source":18,"value":1,"target":19},{"source":19,"value":1,"target":16},{"source":19,"value":1,"target":18} 
]} 
1

Thông tin nhóm của bạn chỉ có sẵn trong đối tượng links, như @ckersch đã được chỉ ra. Bạn cũng cần thêm thông tin nhóm cho bạn nodes đối tượng. Ví dụ này có thể được thực hiện bằng cách thay đổi dòng 16 vào:

link.target = nodes[link.target] || (nodes[link.target] = {name: link.target, group: link.group}); 

Nhưng đối với dữ liệu phức tạp hơn, với nhiều hơn một source, tất cả các nguồn sẽ có cùng màu (hoặc đó sẽ là OK?).

Tôi đã thực hiện thay đổi trong Fiddle này: http://jsfiddle.net/WBkw9/19/.