patterncsharpMinor
Drawing a point on a chart
Viewed 0 times
chartdrawingpoint
Problem
Is there any way to make this work faster?
Here is my sample code in vb.net. This adds a point on a chart at mouse position but it is quite slow.
Function returns the coordinates of x and y axis at mouse position.
Result:
Here is my sample code in vb.net. This adds a point on a chart at mouse position but it is quite slow.
Private Sub Chart2_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart2.MouseMove
Dim coord() As Double = GetAxisValuesFromMouse(e.X, e.Y)
Dim test As Series
Try
Chart2.Series.RemoveAt(1)
Catch ex As Exception
End Try
Dim pt As New DataPoint
pt.XValue = coord(0)
pt.YValues(0) = coord(1)
test = New Series
Chart2.Series.Add(test)
Chart2.Series(test.Name).ChartType = SeriesChartType.Point
Chart2.Series(test.Name).Points.Add(pt)
End SubFunction returns the coordinates of x and y axis at mouse position.
Private Function GetAxisValuesFromMouse(x As Integer, y As Integer) As Double()
Dim coord(1) As Double
Dim chartArea = Chart2.ChartAreas(0)
coord(0) = chartArea.AxisX.PixelPositionToValue(x)
coord(1) = chartArea.AxisY.PixelPositionToValue(y)
Return coord
End FunctionResult:
Solution
Unless I'm mistaken, the
-
An empty
-
-
The chart object is abstracting a lot of plumbing, and I suspect this plumbing is where your bottleneck is. Your code removes a series, creates a new data point, adds a new series and adds the data point to the new series; the chart probably gets redrawn when you remove the series, and again when you add it, and once more when you add the point. It would be much more efficient to move the datapoint instead of recreating the series everytime the mouse moves by a pixel.
I suggest you only create the data point when you don't already have it (i.e. only once!); keep a reference to your data point, and simply change its coordinates per the mouse. If that alone doesn't do it, you'll need code that finds the data point and moves it. Since you're drawing the point on its own series, that shouldn't be too hard to achieve. The chart will only redraw itself when the coordinates of the point have changed, and when the mouse moves you'll only be fetching the mouse coordinates and assigning new values to the point's XY values. I'm sure this would be much faster.
And yeah, exceptions incur some performance hit, so if your code is swallowing exceptions that is another possible bottleneck, but if you're only moving a data point around, you shouldn't have to worry about that.
MouseMove event fires everytime the mouse coordinates change - and when you're moving the mouse across the chart, that's a couple dozens (if not hundreds) of times in a very limited amount of time (Tab button the lovin' it deserves!-
An empty
Catch block is bad. You're swallowing exceptions without ever knowing if anything has gone wrong. Don't do that!-
GetAxisValuesFromMouse should be returning a Point, not an array of doubles. Returning a simple struct instead of an array can help you gain a couple cycles - my background is c# so the syntax might be a little off here:Public Structure PointD ' named after System.Drawing.PointF which is using Float/Single.
Public X As Double
Public Y As Double
Public Sub New(ByVal XValue As Double, ByVal YValue As Double)
X = XValue
Y = YValue
End Sub
End Structure
Private Function GetAxisValuesFromMouse(x As Integer, y As Integer) As Double()
return New PointD(chartArea.AxisX.PixelPositionToValue(x), _
chartArea.AxisY.PixelPositionToValue(y))
End Function-
The chart object is abstracting a lot of plumbing, and I suspect this plumbing is where your bottleneck is. Your code removes a series, creates a new data point, adds a new series and adds the data point to the new series; the chart probably gets redrawn when you remove the series, and again when you add it, and once more when you add the point. It would be much more efficient to move the datapoint instead of recreating the series everytime the mouse moves by a pixel.
I suggest you only create the data point when you don't already have it (i.e. only once!); keep a reference to your data point, and simply change its coordinates per the mouse. If that alone doesn't do it, you'll need code that finds the data point and moves it. Since you're drawing the point on its own series, that shouldn't be too hard to achieve. The chart will only redraw itself when the coordinates of the point have changed, and when the mouse moves you'll only be fetching the mouse coordinates and assigning new values to the point's XY values. I'm sure this would be much faster.
And yeah, exceptions incur some performance hit, so if your code is swallowing exceptions that is another possible bottleneck, but if you're only moving a data point around, you shouldn't have to worry about that.
Code Snippets
Public Structure PointD ' named after System.Drawing.PointF which is using Float/Single.
Public X As Double
Public Y As Double
Public Sub New(ByVal XValue As Double, ByVal YValue As Double)
X = XValue
Y = YValue
End Sub
End Structure
Private Function GetAxisValuesFromMouse(x As Integer, y As Integer) As Double()
return New PointD(chartArea.AxisX.PixelPositionToValue(x), _
chartArea.AxisY.PixelPositionToValue(y))
End FunctionContext
StackExchange Code Review Q#30188, answer score: 7
Revisions (0)
No revisions yet.