我看过很多关于这个主题的帖子,但这个问题似乎没有得到妥善解决。
我们有一个很大的散点,大约有 30 个点(没有什么压倒性的)。但在某些情况下,这些点会非常靠近或重叠(我想我们对此无能为力)。
主要问题是我们希望数据标签始终可见,并且当点彼此靠近时这些数据标签会重叠。
我们尝试过allowOverlap: false,但这并不是我们真正需要/想要的。我们理想的结果是允许所有数据标签显示在分散内的屏幕上,同时仍然能够始终读取每个数据标签。
我们是否通过调整点的间距或调整数据标签的间距/填充来解决此问题?有什么建议么?谢谢。
最佳答案
我还没有从 Highcharts 中找到此问题的有效配置解决方案(尽管我不能保证最新版本中没有)。然而,有一些算法可以对分割数据标签的标签坐标进行可接受的随机化。
以下是一些有用的链接,可以帮助您了解该算法:
wordcloud package in R (cloud.R是包含算法的文件)
R 代码的 JavaScript 中的一些虚拟伪代码翻译如下:
splitLabels: function() {
// Create an array of x-es and y-es that indicate where your data lie
var xArr = getAllDataX();
var yArr = getAllDataY();
var labelsInfo = {};
this.chartSeries.forEach(function(el) {
var text = el.data.name;
labelsInfo[el.data.id] = {
height: getHeight(text),
width: getWidth(text),
text: text
};
}, this);
var sdx = getStandardDeviation(xArr);
var sdy = getStandardDeviation(yArr);
if(sdx === 0) sdx = 1;
if(sdy === 0) sdy = 1;
var boxes = [];
var xlim = [], ylim = [];
xlim[0] = this.chart.xAxis[0].getExtremes().min;
xlim[1] = this.chart.xAxis[0].getExtremes().max;
ylim[0] = this.chart.yAxis[0].getExtremes().min;
ylim[1] = this.chart.yAxis[0].getExtremes().max;
for (var i = 0; i < data.length; i++) {
var pointX = data[i].x;
var pointY = data[i].y;
if (pointX<xlim[0] || pointY<ylim[0] || pointX>xlim[1] || pointY>ylim[1]) continue;
var theta = Math.random() * 2 * Math.PI,
x1 = data[i].x,
x0 = data[i].x,
y1 = data[i].y,
y0 = data[i].y,
width = labelsInfo[data[i].id].width,
height = labelsInfo[data[i].id].height ,
tstep = Math.abs(xlim[1] - xlim[0]) > Math.abs(ylim[1] - ylim[0]) ? Math.abs(ylim[1] - ylim[0]) / 100 : Math.abs(xlim[1] - xlim[0]) / 100,
rstep = Math.abs(xlim[1] - xlim[0]) > Math.abs(ylim[1] - ylim[0]) ? Math.abs(ylim[1] - ylim[0]) / 100 : Math.abs(xlim[1] - xlim[0]) / 100,
r = 0;
var isOverlapped = true;
while(isOverlapped) {
if((!hasOverlapped(x1-0.5*width, y1-0.5*height, width, height, boxes)
&& x1-0.5*width>xlim[0] && y1-0.5*height>ylim[0] && x1+0.5*width<xlim[1] && y1+0.5*height<ylim[1]) )
{
boxes.push({
leftX: x1-0.5*width,
bottomY: y1-0.5*height,
width: width,
height: height,
icon: false,
id: data[i].id,
name: labelsInfo[data[i].id].text
});
data[i].update({
name: labelsInfo[data[i].id].text,
dataLabels: {
x: (x1 - data[i].x),
y: (data[i].y - y1)
}
}, false);
isOverlapped = false;
} else {
theta = theta+tstep;
r = r + rstep*tstep/(2*Math.PI);
x1 = x0+sdx*r*Math.cos(theta);
y1 = y0+sdy*r*Math.sin(theta);
}
}
}
// You may have to redraw the chart here
},
您可以在重绘时调用此函数或优化以减少调用它的频率。
请注意,如果您有一些大点、形状或图标指示数据项所在的位置,您将必须检查任何建议的解决方案是否不会干扰(重叠)图标。
关于Highcharts 散点图 - 如何修复重叠的数据标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29624572/