是否可以指定rangePoints来处理不同大小的圆圈,以便距离是通过边缘而不是中心来计算的?
例如,这就是我得到的:
()表示圆边; < ---->表示由rangePoints计算的距离
( <----)---(-><-)-------(-> )
^注意中间圆圈看起来更接近最左边的圆圈。相反,我想看到以下内容:
( )<---->( )<---->( )
我正在使用的功能类似于:
var y = d3.scale.ordinal()
.domain(data.map(function(d) { return d.value}))
.rangePoints([0, width]);
var item = chart.append("g")
.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cy", function(d) { return y(d.value); })
答案 0 :(得分:1)
正如@LarsKotthoff所提到的,你需要一个自定义比例实现来做到这一点。
在这种情况下,这有点复杂,因为规模不仅需要考虑域中元素的数量,还需要考虑它们的确切值。基本上,在计算每个元素的位置时,您的比例需要考虑其前面每个元素所占用的空间,并且还包括基于总空间划分的间隔。
以下是它必须做的事情:
首先,在设置比例时,您需要执行以下操作:
这将为您提供每个圆圈之间所需空间的值。
然后对每个元素:
因此,您的比例需要基于索引和基准。
这是一个相当粗略的实现,假设域是一个半径数组,范围是输出的端点:
var customPointScale = function() {
var domain,
range;
// returned scale fn takes datum and index
function scale(d,i) {
var n = domain.length,
totalSpan = range[1] - range[0],
// loop over the domain to find the sum of the diameters
sumDiameters = (function(){
var output = 0;
for (var a = 0; a < n; a++) {
// add radius * 2 to get diameter
output += domain[a] * 2;
}
return output;
})(),
remainingSpace = totalSpan - sumDiameters,
// there is one fewer space than the number of elements
spacer = remainingSpace / (n-1);
// loop over the elements that came before to find the distance spanned
var distanceSoFar = (function() {
var output = 0;
for(var a = 0; a < i; a++) {
// diameter + spacer, for each element traversed
output += (domain[a] * 2) + spacer;
}
return output;
})();
// return the radius plus the distance traversed so far
return d + distanceSoFar;
}
scale.domain = function(_) {
if (!arguments.length) return domain;
domain = _;
return scale;
};
scale.range = function(_) {
if (!arguments.length) return range;
range = _;
return scale;
};
return scale;
};
这是一个JSBin,它将此实现与一些示例数据结合使用。希望有所帮助。