A few weeks ago, someone asked me if the RadChart supported dragging the series items around. The simple answer to this question is no, there is no out-of-the-box support for this feature in the RadChart. I was curious though, so I decided to try my hand at making this concept into a reality. What follows is the code I came up with to do it.

Draggable Chart
Figure 1. The Final Result

Fields and Constructor

In the constructor I am basically generating a bunch of random values to use in the chart. As you can see, I am actually using two series. The reason for this is that the I wanted something that would be easy for the user to click on. A point chart provides a more visible, clickable point when overlaid on top of the line chart that actually displays the data.

#region Fields
// Series item currently being dragged
ChartSeriesItem dragSeriesItem = null;
// Current mouse position
Point mPos = new Point();
// Delta of mouse movement while dragging
Point mDelta = new Point();
#endregion
#region Constructor(s)
public Form1()
{
    InitializeComponent();
    // Generate a random series
    // Uses a point series and a line series together, (points can be clicked, lines cannot)
    Random rnd = new Random();
    for (int i = 0; i < 10; i++)
    {
        int val = rnd.Next() % 10;
        radChart1.Series[0].AddItem(val);
        radChart1.Series[1].AddItem(val);
    }
    // don't show the labels of the line series
    radChart1.Series[0].Appearance.LabelAppearance.Visible = false;
}
#endregion

MouseDown Event

Here, I am detecting when and what series item the user is clicking on. If an item was clicked, I store it as the current item being dragged in the dragSeriesItem variable.

private void radChart1_MouseDown(object sender, MouseEventArgs e)
{
    foreach (ChartSeriesItem seriesItem in radChart1.Series[1].Items)
    {
        if (seriesItem.ActiveRegion.CheckPoint(e.Location))
        {
            this.dragSeriesItem = seriesItem;
             radChart1.Refresh();
            mPos = Cursor.Position;
            mDelta = new Point(0, 0);
        }
    }
}

 

MouseMove Event

In this event, if the user is currently dragging a node, I detect if there has been a change in the mouse cursor position. If so, I increment the YValue of the series item based on that change. I also update the mouse position to match the position of where the node was dragged.

private void radChart1_MouseMove(object sender, MouseEventArgs e)
{
    if (dragSeriesItem != null)
    {
        // get the delta of the mouse cursor
        mDelta.X = Cursor.Position.X - mPos.X;
        mDelta.Y = Cursor.Position.Y - mPos.Y;
        // update the seriesItem position based on the - or + delta of the mouse
        if (mDelta.Y < 0)
            dragSeriesItem.YValue++;
        else if (mDelta.Y > 0)
            dragSeriesItem.YValue--;
        radChart1.Series[0].Items[dragSeriesItem.Index].YValue = dragSeriesItem.YValue;
        // Get center of point, update the mouse position
        RectangleF regionBounds = dragSeriesItem.ActiveRegion.Region.GetBounds();
        Point position = new Point((int)(regionBounds.Left + regionBounds.Width / 2), (int)(regionBounds.Top + regionBounds.Height / 2));
        Cursor.Position = radChart1.PointToScreen(position);
        // save the new mouse position
        mPos = Cursor.Position;
        // redraw the chart
        radChart1.Refresh();
    }
}

 

MouseUp Event

In this event, I simply set the dragSeriesItem variable to null to represent that no item is currently being dragged.

private void radChart1_MouseUp(object sender, MouseEventArgs e)
{
    dragSeriesItem = null;
}

 

Conclusion

Currently, when you drag a node, the mouse cursor feels a bit jumpy. You could probably add a lot of extra precision to this approach if you decrease the amount of the point step value from an integer to a floating point value. (i.e. dragSeriesItem.YValue += .5)

I am not exactly sure what the business use case for something like this would be, but, if you've found a need for something like this, I would love to hear about it. Please comment below.



Related Posts

Comments

Comments are disabled in preview mode.