gpt4 book ai didi

javascript - 使用 D3 使圆圈不超出图表边界

转载 作者:行者123 更新时间:2023-11-30 17:28:05 24 4
gpt4 key购买 nike

我现在正在制作一个如下所示的图表: Chart

我使用 d3 比例和范围从 JSON 数据设置圆的大小和坐标。

一切正常,但我需要确保那些接近极值的圆圈不会与图表的两侧重叠(例如右上角的橙色圆圈和底部的蓝色圆圈),所以我想我需要调整范围并更改坐标以防它们重叠,或者是否有更好的尝试方法来做到这一点?

最佳答案

画圆时,除了xy 缩放函数外,我们还使用r 缩放函数:

    var rScale = d3.scale.linear()
.domain([0, maxR])
.range([0, maxBubbleRadius]);

var xScale = d3.scale.linear()
.domain([minX, maxX])
.range([0, chartWidth]);

var yScale = d3.scale.linear()
.domain([minY, maxY])
.range([chartHeight, 0]);

其中 maxR 是数据集中最大的 r 值,maxBubbleRadius 是您在绘制时希望最大圆圈的大小。

使用 x 和 y 缩放函数很容易计算出每个圆的中心将被绘制的位置,然后我们可以添加(缩放的)r 值以查看圆是否会溢出图表边界。在像下面第一个图表这样的场景中,我们可以看到有 4 个圆圈溢出。解决这个问题的第一步是找出我们溢出了多少垂直和水平单位,然后在重新计算 xScaleyScale 变量。如果我们再次绘制图表,边界会移出,但可能仍然会有一些可见的溢出(取决于使用的实际值);这是因为给定圆的半径是固定数量的像素,因此将在图表上占据不同数量的 x 和 y 单位,这与我们最初计算它溢出的数量不同。因此,我们需要采用迭代方法并继续应用上述逻辑,直到我们到达我们想要的位置。

spilling circles

下面的代码展示了我如何迭代地获得一个可接受的比例因子,这样所有的圆圈都不会溢出。请注意,我这样做了 10 次(如循环中所示)——我刚刚发现这个数字适用于我目前绘制的所有数据。 理想情况下,我应该计算一个 delta(溢出量)并迭代直到它为零(这也需要在第一次迭代时超调,否则我们永远无法找到我们的解决方案!)。

updateXYScalesBasedOnBubbleEdges = function() {
var bubbleEdgePixels = [];

// find out where the edges of each bubble will be, in terms of pixels
for (var i = 0; i < dataLength; i++) {
var rPixels = rScale(_data[i].r),
rInTermsOfX = Math.abs(minX - xScale.invert(rPixels)),
rInTermsOfY = Math.abs(maxY - yScale.invert(rPixels));
var upperPixelsY = _data[i].y + rInTermsOfY;
var lowerPixelsY = _data[i].y - rInTermsOfY;
var upperPixelsX = _data[i].x + rInTermsOfX;
var lowerPixelsX = _data[i].x - rInTermsOfX;
bubbleEdgePixels.push({
highX: upperPixelsX,
highY: upperPixelsY,
lowX: lowerPixelsX,
lowY: lowerPixelsY
});
}

var minEdgeX = d3.min(bubbleEdgePixels, function(d) {
return d.lowX;
});
var maxEdgeX = d3.max(bubbleEdgePixels, function(d) {
return d.highX;
});
var minEdgeY = d3.min(bubbleEdgePixels, function(d) {
return d.lowY;
});
var maxEdgeY = d3.max(bubbleEdgePixels, function(d) {
return d.highY;
});

maxY = maxEdgeY;
minY = minEdgeY;
maxX = maxEdgeX;
minX = minEdgeX;

// redefine the X Y scaling functions, now that we have this new information
xScale = d3.scale.linear()
.domain([minX, maxX])
.range([0, chartWidth]);

yScale = d3.scale.linear()
.domain([minY, maxY])
.range([chartHeight, 0]);
};

// TODO: break if delta is small, rather than a specific number of interations
for (var scaleCount = 0; scaleCount < 10; scaleCount++) {
updateXYScalesBasedOnBubbleEdges();
}

no spill

关于javascript - 使用 D3 使圆圈不超出图表边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23827522/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com