我有一个带有系列的图表,配置了高亮显示,标记未显示。
对于某些数据,标记相距足够远,当鼠标悬停在线上时,它可能会突出显示,也可能不突出显示,具体取决于鼠标光标与(隐藏)标记的接近程度。因为没有显示标记,所以这给出了当鼠标悬停在线上时高度随机且断裂的外观;有时它会突出显示,有时却没有。
我尝试增加selectionTolerance,但这是不可接受的,因为它基本上是标记周围的半径,这样当鼠标光标甚至不接近时,将鼠标悬停在距标记越来越远的位置会导致线条突出显示线。
所以,我想要一个小的selectionTolerance,所以鼠标必须接近该线,但我希望当鼠标接近线时应用高光,而不是当它是接近(隐藏)标记。
如何做到这一点?
感谢。
编辑:进一步观察,我相信答案是让我重载Ext.chart.series.Line的 isItemInPoint 函数。就我而言,当showMarkers为false时,我只希望线条突出显示在线上。当ShowMarkers为true时,当前行为是可接受的。所以,它应该是一个非常干净的覆盖。还是要弄清楚如何确定一个点是否在线上,以及返回哪个项目,但这可能仅仅是一些数学问题。
答案 0 :(得分:0)
所以,这就是我最终做的事情,它可以按照需要运作。我将chart.series.line扩展为betterline。然后我制作了我的系列类型" betterline"并在配置中设置lineSelectionTolerance。
Ext.define('MyExtends.SeriesLine', {
extend: 'Ext.chart.series.Line',
alias: ['series.betterline', 'Ext.chart.series.BetterLine'],
type: 'betterline',
isItemInPoint: function (x, y, item, i)
{
var me = this,
items = me.items,
ln = items.length,
tolerance = me.selectionTolerance,
prevItem,
nextItem,
prevPoint,
nextPoint,
x1, x2,
y1, y2,
dist1, dist2, dist,
sqrt = Math.sqrt;
nextItem = items[i];
prevItem = i && items[i - 1];
if (i >= ln)
{
prevItem = items[ln - 1];
}
prevPoint = prevItem && prevItem.point;
nextPoint = nextItem && nextItem.point;
x1 = prevItem ? prevPoint[0] : nextPoint[0] - tolerance;
y1 = prevItem ? prevPoint[1] : nextPoint[1];
x2 = nextItem ? nextPoint[0] : prevPoint[0] + tolerance;
y2 = nextItem ? nextPoint[1] : prevPoint[1];
dist1 = sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
dist2 = sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
dist = Math.min(dist1, dist2);
if (dist <= tolerance)
{
return dist == dist1 ? prevItem : nextItem;
}
if (me.lineSelectionTolerance)
{
if (prevItem && nextItem && prevItem != nextItem)
{
tolerance = me.lineSelectionTolerance;
x1 = parseFloat(prevPoint[0]);
y1 = parseFloat(prevPoint[1]);
x2 = parseFloat(nextPoint[0]);
y2 = parseFloat(nextPoint[1]);
if (x > x1 && x < x2)
{
var slope = (y2 - y1) / (x2 - x1);
var slopePerp = -1 / slope;
var xIntercept = (x2 * (x * slopePerp - y + y1) + x1 * (x * -slopePerp + y - y2)) / (slopePerp * (x2 - x1) + y1 - y2);
var yIntercept = slopePerp * xIntercept - slopePerp * x + y;
if (!(y2 - y1)) // Horizontal line
{
xIntercept = x;
yIntercept = y1;
}
var a = (x - xIntercept);
var b = (y - yIntercept);
var distPointToIntercept = sqrt(a * a + b * b); // Pythagorean
if (distPointToIntercept < tolerance)
{
dist1 = sqrt((xIntercept - x1) * (xIntercept - x1) + (yIntercept - y1) * (yIntercept - y1));
dist2 = sqrt((xIntercept - x2) * (xIntercept - x2) + (yIntercept - y2) * (yIntercept - y2));
dist = Math.min(dist1, dist2);
return dist == dist1 ? prevItem : nextItem;
}
}
}
}
return false;
}
});