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; private IntervalBarItem currentItem; private double StartX;
public DragDropTrackerManipulator(IPlotView plotView)
: base(plotView)
{
}
public override void Completed(OxyMouseEventArgs e)
{
base.Completed(e);
e.Handled = true;
currentItem = null;
PlotView.InvalidatePlot(true);
PlotView.HideTracker();
}
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)); currentItem = dp;
}
else
{
currentItem.CategoryIndex = id_Category;
currentItem.Start = currentItem.Start - diffX;
currentItem.End = currentItem.End - diffX;
PlotView.InvalidatePlot(true);
}
}
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