Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Drag&Drop Tracker for OxyPlot

0.00/5 (No votes)
6 Feb 2016 1  
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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here