![]() ![]() Private void chart1_MouseUp(object sender, MouseEventArgs e) On revisiting the code I wonder why I didn't choose a simpler way: DataPoint curPoint = null ![]() If (!ippRect.Contains(e.Location) ) return įor the InnerPlotPositionClientRectangle function see here! Only the Tooltip formatting will have to be adapted.įinal note: To prevent the users from moving a DataPoint off the ChartArea you can add this check into the if-clause of the MouseMove event: RectangleF ippRect = InnerPlotPositionClientRectangle(chart1, ca_) This stops the Chart from running wild with its automatic display of Labels, GridLines, TickMarks etc.Īlso note that this will work with any DataType for X- and YValues. Note that I have set both the Minima and Maxima as well as the Intervals for both Axes. S1.ToolTip = "(#VALX)" ĬA.AxisX.Minimum = S1.Points.Select(x => x.XValue).Min() ĬA.AxisX.Maximum = S1.Points.Select(x => x.XValue).Max() + 1 ĬA.AxisY.Minimum = S1.Points.Select(x => x.YValues).Min() ĬA.AxisY.Maximum = S1.Points.Select(x => x.YValues).Max() + 1 Here is how I have set up my chart: Series S1 = chart1.Series If (e.Button.HasFlag(MouseButtons.Left) & dp_ != null)ĭouble vx = ca_.AxisX.PixelPositionToValue(e.Location.X) ĭouble vy = ca_.AxisY.PixelPositionToValue(e.Location.Y) įinally we clean up in the MouseUp event: private void chart1_MouseUp(object sender, MouseEventArgs e) In the MouseMove we do the reverse calculation and set the values of our point note that we also synch its new position and trigger the Chart to refresh the display: private void chart1_MouseMove(object sender, MouseEventArgs e) If (((RectangleF)dp.Tag).Contains(e.Location)) Then we store it and change its Color.: private void chart1_MouseDown(object sender, MouseEventArgs e) In the MouseDown we loop over the Points collection until we find one with a Tag that contains the mouse position. Now for the actual moving of a point: As usual we need to code the three mouse events: The flag will help keeping things efficient. We are calling it from the PrePaint event, which is fine. Note that calling the ValueToPixelPosition is not always valid! If you call it at the wrong time it will return null. The actual refreshing of the rectangles is being triggered from the PrePaint event: private void chart1_PrePaint(object sender, ChartPaintEventArgs e) Here is the Resize event: private void chart1_Resize(object sender, EventArgs e) have happend, so we need to re-synch them each time! And, of course you need to initially set them whenever you add a DataPoint! These rectangles will change whenever the chart is resized or other changes in the Layout, like sizing of a Legend etc. Note that I chose to use the Tag of each DataPoints to hold a RectangleF that has the clientRectangle of the DataPoint's Marker. Void SyncAPoint(ChartArea ca, Series s, DataPoint dp)įloat px = (float)ca.AxisX.ValueToPixelPosition(dp.XValue) įloat py = (float)ca.AxisY.ValueToPixelPosition(dp.YValues) ĭp.Tag = (new RectangleF(px - mh, py - mh, dp.MarkerSize, dp.MarkerSize)) Void SyncAllPoints(ChartArea ca, Series s)įoreach (DataPoint dp in s.Points) SyncAPoint(ca, s, dp) They do the 1st conversion between pixels and data values: // two helper functions: When we set up the chart we fill some of them: ca_ = chart1.ChartAreas There are several ways to do this, but I think this is the cleanest:įirst we create a few class level variables that hold references to the targets: // variables holding moveable parts: Those are doubles and they can go from and to anywhere you set them to.įor our task we need to convert between mouse pixels and data values. The DataPoints have an x-value and one (or more) y-values(s). The Mouse coordinates and all graphics drawn in one of the three Paint events, all work in pixels they go from /Height. Those data make up an ElementPosition and usually go from 0-100%. The chart elements, like a Legend or an Annotation are measured in percentages of the respective containers. The problem with interacting with a Chart by mouse is that there are not one but three coordinate systems at work in a Chart: Moving a DataPoint is not a built-in feature of the Chart control.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |