Ext 4图表:当鼠标悬停线不仅仅在标记上方时突出显示线条?(Ext 4 chart: Highlight line when mouseover line not just over marker?

编程入门 行业动态 更新时间:2024-10-28 13:21:16
Ext 4图表:当鼠标悬停线不仅仅在标记上方时突出显示线条?(Ext 4 chart: Highlight line when mouseover line not just over marker?)

我有一个带有系列的图表,配置了一个高亮显示,标记没有显示。

对于一些数据,标记彼此足够远,当鼠标悬停在线上时,它可能会突出显示,也可能不突出显示,具体取决于鼠标光标与(隐藏)标记的接近程度。 因为没有显示标记,所以这给出了当鼠标悬停在线上时高度随机且断裂的外观; 有时它突出显示,有时它不突出。

我尝试增加selectionTolerance,但这是不可接受的,因为它基本上是标记周围的半径,因此当鼠标光标甚至不接近线时,将鼠标悬停在距离标记越来越远的位置会导致线条突出显示。

所以,我想要一个小的selectionTolerance,所以鼠标必须接近线,但我希望当鼠标接近线时应用高光 ,而不是当它接近(隐藏) 标记时

怎么做到这一点?

谢谢。

编辑:进一步观察,我相信答案是我为Ext.chart.series.Line重载isItemInPoint函数。 就我而言,当showMarkers为false时,我只希望线条突出显示在线上。 当ShowMarkers为true时,当前行为是可接受的。 所以,它应该是一个非常干净的覆盖。 仍然必须弄清楚如何确定一个点是否在线上,以及返回哪个项目,但这可能仅仅是一些数学问题。

I have a chart with a line series, with a highlight configured, markers are not shown.

With some data, the markers are far enough apart from each other that when mousing over the line it may or may not highlight depending on how close the mouse cursor is to a (hidden) marker. Because markers are not shown, this gives the appearance that the highlghting when hovering the mouse over the line is random and broken; sometimes it highlights, sometimes it doesn't.

I tried increasing selectionTolerance, but this isn't acceptable as that is essentially a radius around the marker, such that hovering farther and farther away from the marker causes the line to highlight when the mouse cursor isn't even close to the line.

So, I want a small selectionTolerance so the mouse has to be close to the line, but I want the highlight to be applied when the mouse is close to the line, not just when it is close to a (hidden) marker.

How to accomplish this?

Thanks.

Edit: upon looking further, I believe the answer is for me to overload the isItemInPoint function for Ext.chart.series.Line. In my case, I only want the line to highlight when hovering over the line when showMarkers is false. When ShowMarkers is true, the current behavior is acceptable. So, it should be a pretty clean override. Still have to figure out how to determine if a point is on the line, and which item to return, but that's probably just a matter of some maths.

最满意答案

所以,这就是我最终做的事情,并且它可以按照需要运行。 我将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; } });

So, here's what I ended up doing, and it works as desired. I extended chart.series.line into betterline. Then I make my series type "betterline" and set lineSelectionTolerance in the config as well.

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; } });

更多推荐

本文发布于:2023-08-04 21:49:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1422359.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:图表   线条   标记   当鼠标   Ext

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!