我的D3穿孔卡有两个问题(插件在这里:https://plnkr.co/edit/vIejaTBrGrV07B8UWxOb):
它看起来很拥挤,我有缩放设置,但我无法弄清楚如何将初始视图设置为更“可读”的比例,点更加间隔。我打算在工具提示中加入不同的半径。
//Create scale functions
var xScale = d3.scale.linear()
.domain([1900, 2020])
.range([0, w]);
var yScale = d3.scale.linear()
.domain([0, (deptlist.length)])
.range([h, 0]);
//console.log(deptlist.length);
//var rScale = d3.scale.linear()
//.domain([0, d3.max(dataset, function(d) { return d[1]; })])
//.range([2, 5]);
//Define X axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(function(d) {
//console.log(d);
return d;
});
//Define Y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.tickFormat(function(d) {
//console.log(deptlist[d]);
return deptlist[d];
})
.ticks(deptlist.length - 1);
我无法按照字母顺序对我的deptlist []进行排序。
这也很慢......
答案 0 :(得分:3)
如果你最初使它们变小,你将能够更好地区分这些点,然后在缩放级别增加时使它们更大。
d3.selectAll('.dot')
// ...
.attr('r', 2)
然后,当您放大时,可以使r
值成为xScale.domain
中值之差的乘积。例如......
function zoomed() {
svg.selectAll(".dot")
.attr("cx", function(d) { return xScale(+d.year); })
.attr("cy", function(d) { return yScale(deptlist.indexOf(d.dept)); })
.attr('r', function(d) {
return 120 / (xScale.domain()[1] - xScale.domain()[0]);
});
svg.select(".x.axis").call(xAxis);
svg.select(".y.axis").call(yAxis);
}
有许多不同的方法可以缩放你的点,这只是一种方法。您的xScale.domain()
会返回xScale
的域名,例如[1900, 2020]
。通过从第二个值中减去第一个值,我们得到一个可以用作参考点的值,从中可以缩放点。
我只取最大可能的差值120,并将其除以比例的当前值(在缩放时更改)。这会创建一个更大的值,缩放越多。
使用D3's array methods中的一些内容,可以使代码更具声明性。
而不是这样做:
var deptlist = [];
dataset.forEach(function(d) {
if(deptlist.indexOf(d.dept) == -1) deptlist.push(d.dept);
});
您可以使用d3.map
,array.keys()
和d3.descending
来(a)仅向您的数组返回d.dept
,(b)仅获取数组中的唯一值,(c)将JS原生sort
array method与d3.ascending
结合使用,按字母顺序排序。
var deptlistUnsorted = d3.map(dataset, function(d) {
return d.dept;
}).keys();
var deptlist = deptlistUnsorted.sort(d3.descending);
最后请注意,您的代码运行缓慢,因为在一个包含数千个对象的数组的console.log
循环内部有forEach
语句。这给浏览器带来了很大的压力,在处理那么大的数组时通常要避免。
我更新了您的plunkr以反映上述代码。