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