Drag&Drop Tracker for OxyPlot
Showing how to add Drag&Drop to oxyplot library
Introduction
I am having a WPF application with OxyPlot
and trying to solve the drag and drop problem in my Interval Bar chart.

Background
OxyPlot
is cross-platform plotting library for .NET. More information can be found here.
Using the Code
First of all, we need to develop MouseManipulator
class that does all the drag and drop magic.
Class has three methods Started
, Delta
and Completed
.
Mostly important is Delta where we are moving Interval bar when we are holding mause btn.
class DragDropTrackerManipulator : MouseManipulator
{
private IntervalBarSeries currentSeries; // Currently selected series
private IntervalBarItem currentItem; // currently selected Items.
private double StartX;
public DragDropTrackerManipulator(IPlotView plotView)
: base(plotView)
{
}
/// <summary>
/// Occurs when a manipulation is complete.
/// </summary>
/// <param name="e">
/// The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.
/// </param>
public override void Completed(OxyMouseEventArgs e)
{
base.Completed(e);
e.Handled = true;
currentItem = null;
PlotView.InvalidatePlot(true);
PlotView.HideTracker();
}
/// <summary>
/// Occurs when the input device changes position during a manipulation.
/// </summary>
/// <param name="e">
/// The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.
/// </param>
public override void Delta(OxyMouseEventArgs e)
{
base.Delta(e);
e.Handled = true;
if (currentSeries == null)
{
PlotView.HideTracker();
return;
}
var actualModel = PlotView.ActualModel;
if (actualModel == null)
{
return;
}
if (!actualModel.PlotArea.Contains(e.Position.X, e.Position.Y))
{
return;
}
var click_XAxis = currentSeries.InverseTransform(e.Position).X;
var click_YAxis = currentSeries.InverseTransform(e.Position).Y;
double diffX = StartX - click_XAxis;
StartX = click_XAxis;
int id_Category = Convert.ToInt32(click_YAxis);
if (currentItem == null)
{
IntervalBarItem dp = currentSeries.Items.FirstOrDefault
(d => ((d.Start <= click_XAxis && d.End >= click_XAxis) &&
d.CategoryIndex == id_Category)); // select points clicked
currentItem = dp;
}
else
{
currentItem.CategoryIndex = id_Category;
currentItem.Start = currentItem.Start - diffX;
currentItem.End = currentItem.End - diffX;
PlotView.InvalidatePlot(true);
}
}
/// <summary>
/// Occurs when an input device begins a manipulation on the plot.
/// </summary>
/// <param name="e">
/// The <see cref="OxyPlot.OxyMouseEventArgs" /> instance containing the event data.
/// </param>
public override void Started(OxyMouseEventArgs e)
{
base.Started(e);
currentSeries = PlotView.ActualModel.Series.FirstOrDefault(s => s.IsVisible)
as IntervalBarSeries;
StartX = currentSeries.InverseTransform(e.Position).X;
Delta(e);
}
}
Last thing to make it work we need to set up our class to PlotView
. Credits about this go to this guy.
PlotV.ActualController.UnbindMouseDown(OxyMouseButton.Left);
PlotV.ActualController.UnbindMouseDown(OxyMouseButton.Left);
PlotV.ActualController.UnbindMouseDown(OxyMouseButton.Left, OxyModifierKeys.Control);
PlotV.ActualController.UnbindMouseDown(OxyMouseButton.Left, OxyModifierKeys.Shift);
PlotV.ActualController.BindMouseDown(OxyMouseButton.Left,
new DelegatePlotCommand<OxyMouseDownEventArgs>(
(view, controller, args) =>
controller.AddMouseManipulator(view, new DragDropTrackerManipulator(view),
args)));
Points of Interest
This was created only for Inverted Bar chart but it is simply to convert to other types that OxyPlot
provides.
This tip was inspired by Phil J Pearson and his article.
History
- 6th February, 2016: First release