我用d3.js插件创建了一个力导向图,我想根据它们所属的组为不同颜色的节点和标签着色。
我添加了颜色比例:
var color = d3.scale.category20();
和我添加的节点变量:
.style("fill", function(d) { return color(d.group); })
但是所有节点都是相同的颜色..
以下是我目前的情况:http://jsfiddle.net/WBkw9/
完整的脚本:
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);
}
我对每组的不同颜色缺少什么?
答案 0 :(得分:4)
这是我的代码(基于http://bl.ocks.org/mbostock/4062045)。它工作得很好。 你可以在这里看到它的样子:http://jsfiddle.net/Rom2BE/H2PkT/
每个组都有不同的颜色。
**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 :(得分:3)
您的问题是没有为您的数据定义group
。因此,所有节点都为组'undefined'着色。您的圈子是为force.nodes()
中的数据定义的,其中包含index
name
px
py
weight
x
和{{}} {1}}。 y
仅针对链接定义,这些链接从未应用过颜色。
目前看来,还没有一种明确的方法来确定节点应该是什么颜色。如果多个链接连接到节点,并且这些链接位于不同的组中会发生什么?
答案 2 :(得分:1)
您的群组信息仅在links
对象中可用,就像@ckersch已经指出的那样。您还需要将组信息添加到nodes
对象中。对于此示例,可以通过将第16行更改为:
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target, group: link.group});
但对于更复杂的数据,如果有多个source
,所有来源都会有相同的颜色(或者可以吗?)。
我在这个小提琴中做了那个改变:http://jsfiddle.net/WBkw9/19/。
答案 3 :(得分:0)
我认为您需要更改圈子的样式属性,而不是g
元素。
node.append("circle").style("fill", function(d) { return color(d.group); })
编辑:数据中的组属性也必须更改为整数,或稍后进行转换。
答案 4 :(得分:0)
你有没有解决过这个问题?如果没有可能的解决方案:http://jsfiddle.net/adeaver/F2fbu/1/
通过添加以下内容,每个组/节点的颜色与相应的文本不同:
.style("fill", function(d) { return color(d.group); })
文本追加和group: link.group
到从链接计算节点的函数