ZedGraph - 如何使水平线可拖动?
我有一些水平直线,我希望用户能够垂直拖动它们。这怎么可能呢?我认为线选择的最佳参数是线附近的固定像素数。因此,如果鼠标为 +/- 2 像素,我应该更改鼠标光标并使线条可拖动。我看到 CurveItem 类具有 IsSelectable 和 IsSelected 属性。这些对于解决这个问题有什么作用吗?通过阅读类文档,我无法真正理解它们的用途。
编辑:
似乎FindNearestPoint(和 FindNearestObject)仅搜索实际点。我如何选择沿着直线的整个部分工作?我想我需要制作自己的自定义“查找”例程,循环遍历我想要检查的所有行,并为每行计算它基于鼠标 X 位置的假想 Y 点(? )我也在考虑为此目的使用倾斜线,对于水平/垂直线,它会稍微简单一些。至少看起来这对于 curveItem 来说是必需的,但我认为选择 LineObj(在中间部分)也必须执行相同的操作?
我实际上不知道 LineObj 的存在。看来 LineObj 无法更改 X2/Y2 坐标,因为它们是只读。那么是否可以拖动 LineObj 的 X2/Y2 点呢?
编辑 2:
这似乎是 JapaneseCandleStick 图表上的 FindNearestPoint 的问题;当我在图表窗格中单击时,它不会返回最近条形的索引,但我相信它会选择具有最接近 Y 值的索引,无论 x 轴有多远这是。有时它是鼠标右侧的一个栏,有时是鼠标左侧的栏。这就是它的工作方式吗?
我自己制作了这个自定义函数,所以我想它没问题。不过,如果能理解为什么 FindNearestPoint 会这样工作,那就太好了。
这是 mouseDown 上的代码:
' Find nearest curve point:
Dim ciNearestCurve As CurveItem
Dim iNearestCurve As Integer
Dim b As Boolean = zgc.GraphPane.FindNearestPoint(mousePt, zgc.GraphPane.CurveList, ciNearestCurve, iNearestCurve)
If b Then
With ciNearestCurve(iNearestCurve)
Debug.Print(Date.FromOADate(.X) & " " & .Y & " " & .Z)
End With
I have some straight horizontal lines that I want the user be able to drag vertically. How would this be possible? I think the best parameter for line selection would be a fixed number of pixels near the line. So if mouse is +/- 2 pixels, I should change the mouse cursor and make the line drag-able.. I see the CurveItem class has properties IsSelectable and IsSelected. Will these have any function in solving this issue? I can’t really understand what they are for from reading the class documentation..
EDIT:
It seems that the FindNearestPoint (and FindNearestObject) only search actual points. How would I make selection to work along the whole section of a straight line? I guess I would need to make make my own custom "Find" routine that loops through all the lines I want to check, and for each calculate it's imaginary Y-point based on the mouse X position (?) I'm also thinking about sloped lines for this purpose, for horizontal/vertical lines it will be slightly simpler. At least it seems this is needed for a curveItem, but I assume the same must be done for selecting (at mid-section of) a LineObj?
I actually didn't know about the LineObj existed. It seems the LineObj is not possible to change the X2/Y2 coordinates, as they are ReadOnly. So is it at all possible to drag the X2/Y2 point of a LineObj?
EDIT 2:
It seems to be an issue with the FindNearestPoint on a JapaneseCandleStick graph; When I click in the graph pane, it does not return the index of the nearest bar, but I believe it instead selects the index with the closest Y-value, no matter how far away on the x axis it is. Sometimes it's a bar to the right of the mouse, sometimes to the left of the mouse. Is this the way it's meant to work?
I made this custom function myself, so I guess it's ok.. Still it would be nice to understand why the FindNearestPoint acts this way.
This is the code on mouseDown:
' Find nearest curve point:
Dim ciNearestCurve As CurveItem
Dim iNearestCurve As Integer
Dim b As Boolean = zgc.GraphPane.FindNearestPoint(mousePt, zgc.GraphPane.CurveList, ciNearestCurve, iNearestCurve)
If b Then
With ciNearestCurve(iNearestCurve)
Debug.Print(Date.FromOADate(.X) & " " & .Y & " " & .Z)
End With
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
查看本教程,了解用鼠标拖动点。
如果您使用的是
LineObj
而不是曲线,请查看FindNearestObject
方法。另外,如果您想为点击创建一些“敏感区域”,此方法应该可以帮助您将鼠标坐标(以像素为单位)转换为窗格比例坐标。
主要思想是:
- 订阅
MouseDown
、MouseUp
和MouseMove
事件- 在
MouseDown
事件的处理程序中检查单击的点是否靠近您要移动的曲线/图形对象- 以与第一个链接示例中所示类似的方式进行更改
编辑
关于您的编辑:
假设您有一条包含两个点的水平曲线
myCurve
。使用FindNearestPoint
,您可以找到最近的点击点和包含该点的曲线。因此,您需要:
接下来处理
MouseMove
和MouseUp
事件,以找出需要移动曲线的距离。您只需要知道 Y(或 Y2)方向的变化,因为曲线是水平的,并且您可能不想沿 X 轴移动它。当您发现需要移动曲线多少(
dy
)时,只需执行以下操作:关于您的第二个问题,请参阅 您拥有的
LineObj.Location.Y2
文档:并且
Width
/Height
属性可以轻松设置,因此您可以这样做。Take a look on this tutorial on dragging the points with mouse.
If you are using a
LineObj
instead of a curve, take a look on theFindNearestObject
method.Also if you want to make some "area of sensitivity" for clicking, this method should help you to transform mouse coordinates in pixels to pane scale coordinates.
The main idea is to:
- subscribe for
MouseDown
,MouseUp
andMouseMove
events- in the handler for
MouseDown
event check if clicked point is near the curve/graph object you want to move- do the change in similar way that it is shown in example from the first link
EDIT
Regarding your edit:
Let's assume you have a horizontal curve
myCurve
containing two points. UsingFindNearestPoint
you can find nearest clicked point and the curve containing this point.So you have:
Next handle the
MouseMove
andMouseUp
events to find out how much you need to move your curve. You need to know only the change in Y (or Y2) direction as the curve is horizontal and you probably do not want to move it along X axis.When you'll find out how much you need to move your curve (
dy
), just do:Regarding your second question, in the documentation for
LineObj.Location.Y2
you have:And
Width
/Height
properties can be set easily, so you can do it this way.首先回答bretddog:
我不使用 JapaneseCandleStick,而是使用 Line,但我认为这是同一类问题。 ZedGraph 使用坐标,因此使用点,而不是函数,因此要确定最近的“曲线”,它应该进行插值,但这似乎很难做到。
尽管如此,对于线条图形,我开发了一个函数来获取最近的曲线。因此,我在每条曲线的每个连续点之间进行了直线插值,并使用数学距离来确定最近的曲线。代码是:
我已经测试了这个函数,它似乎工作得很好,但我不能保证在所有情况下(事实上,如果曲线的第一个/最后一个点是最近的点,它将不会被检测到)像这样)。关于使用的一些备注:
最后,我不确定这段代码是否针对速度进行了优化,但我并没有冻结。最好的方法应该是将函数集成到 ZedGraph 类中,并在调用 Add 函数时计算每个系数(a 和 b),这样就不会每次都计算它们(因此每次鼠标移动)。
所以我希望代码能够帮助一些人创建一个可移动光标,这是 ZedGraph 中非常缺少的。
Firstly to answer to bretddog:
I don't work with JapaneseCandleStick but with Line, but I think it's the same kind of problem. ZedGraph works with coordinates, so with points, not with functions, so to determine the nearest "Curve" it should interpolate and it seems very hard to do that.
Nevertheless, for Line graphics I've develop a function to obtain the nearest curve. So I've made a straight line interpolation between each consecutive points for each curve, and I've used the mathematical distance to determine the nearest curve. The code is:
I've tested this function, and it seems to work well, but I can't guarantee in all cases (indeed, if the first/last point of a curve is the nearest point, it won't be detected as such). Some remarks about using:
Lastly, I'm not sure that this code is optimized for speed, but I've no freezing on my side. The best way should be to integrate the function to a ZedGraph class, and calculate each coefficient (a and b) when Add function is called, so to not calculate them each time (so each mouse move).
So I hope that code will help some people to create a movable cursor, something which is very missing in ZedGraph.
我需要在绘图上拖动一条线对象。我花了相当长的时间才弄清楚如何去做。以下代码特定于我的应用程序,并不完整,但它确实有效,我认为对于其他需要执行此操作的人来说,这是一个很好的起点。我的代码是VB的。它的本质是利用MouseDownEvent来判断光标是否距离你想要拖动的对象足够近。然后在 MouseMoveEvent 中确定新位置并更新绘图。
I needed to drag a line object on a plot. It took me quite some time to work out how to do it. The following code is specific to my application and not complete but it does work and I think its a good starting point for anyone else who needs to do this. My code is in VB. The essence of it is to use the MouseDownEvent to determine if the cursor is close enough to the object you want to drag. And then in the MouseMoveEvent determine the new location and update the plot.