我为一系列数据集构建了一个D3 Hive图。对于大多数数据集,结果与预期一致,但对于一个数据集,轴严重行为不端。
特别是,轴不尊重内半径,因此它们向内延伸并相交:
我想知道我们如何定义导致这种情况的轴是否存在错误;这是这些函数的代码:
radius.domain(d3.extent(visa_lengths, function(d){ return d.length; }));
svg.selectAll(".axis")
.data(visa_lengths)
.enter().append("line")
.attr("class", "axis")
.attr("transform", function(d, i){ return "rotate(" + degrees(angle(i)) + ")";})
.attr("x1", radius.range()[0])
.attr("x2", function(d){return radius(d.length);})
;
这里提供了完整的HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hive Link Plot</title>
<style type="text/css">
.link{
fill: none;
stroke: #000;
stroke-width: 1px;
stroke-opacity: .1;
}
.axis {
stroke: #000;
stroke-width: 1.5px;
}
.link.active {
stroke-width: 3px;
stroke-opacity: 1;
}
.node {
stroke: #000;
}
.node.active {
stroke: red;
stroke-width: 3px;
stroke-opacity: 1;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="../static/d3.hive.min.js"></script>
<script type="text/javascript">
var source_cont = "Asia";
var target_cont = "Asia";
plot(source_cont, target_cont);
function plot(source_cont, target_cont){
var width = 1200;
var height = 1200;
var outerRadius = 500;
var innerRadius = 50;
var minLength = 5;
var visa_types = {'free': 1, 'required': 4, 'refused': 2, 'onarrival': 3, 'origin': 0};
var angle = d3.scale.ordinal()
.domain(["origin", "free", "refused", "onarrival", "required"])
.range([0, Math.PI/2, 11 * Math.PI / 12, 13 * Math.PI / 12, 3 * Math.PI / 2]);
var radius = d3.scale.linear()
.range([innerRadius, outerRadius]);
var color = d3.scale.ordinal()
.domain(["origin", "free", "refused", "onarrival", "required"])
.range(["yellow", "blue", "red", "orange", "green"]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/2 + "," + height/2 + ")");
d3.json("reduced_pairwise_datasets.json", function(error, graph){
nodes = graph.pairwise_nodes[source_cont + "-" + target_cont];
links = graph.pairwise_links[source_cont + "-" + target_cont];
// var origin_links =
var free_links = new Set(links.filter(function(p){ return p.target.type == 'free';}).map(function(d){return d.target.name}));
var onarrival_links = new Set(links.filter(function(p){ return p.target.type == 'onarrival';}).map(function(d){return d.target.name}));
var required_links = new Set(links.filter(function(p){ return p.target.type == 'required';}).map(function(d){return d.target.name}));
var refused_links = new Set(links.filter(function(p){ return p.target.type == 'refused';}).map(function(d){return d.target.name}));
var visa_lengths = [{'name': 'origin', 'length': 50}, {'name': 'free', 'length': free_links.size}, {'name': 'refused', 'length': refused_links.size}, {'name': 'onarrival', 'length': onarrival_links.size}, {'name': 'required', 'length': required_links.size}];
var visa_obj = {'origin': 55, 'free': free_links.size, 'required': required_links.size, 'onarrival': onarrival_links.size, 'refused': refused_links.size};
radius.domain(d3.extent(visa_lengths, function(d){ return d.length; }));
svg.selectAll(".axis")
.data(visa_lengths)
.enter().append("line")
.attr("class", "axis")
.attr("transform", function(d, i){ return "rotate(" + degrees(angle(i)) + ")";})
.attr("x1", radius.range()[0])
.attr("x2", function(d){return radius(d.length);})
;
svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", d3.hive.link()
.angle(function(d) { return angle(visa_types[d.type]); })
.radius(function(d) { return radius(visa_obj[d.type] * d.y); }))
.style("stroke", function(d) { return color(d.target.type);})
;
svg.selectAll(".node")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("transform", function(d) { return "rotate(" + degrees(angle(visa_types[d.type])) + ")"; })
.attr("cx", function(d) { return radius(visa_obj[d.type] * d.y); })
.attr("r", 5)
.style("fill", function(d) { return color(d.type);})
;
});
}
function degrees(radians) {
return radians / Math.PI * 180 - 90;
}
</script>
</body>
</html>