Skip to content

Instantly share code, notes, and snippets.

@eocron
Created February 28, 2024 07:43
Show Gist options
  • Save eocron/94b5f3f66bbc0a16f64ffb6ce8f2c8ef to your computer and use it in GitHub Desktop.
Save eocron/94b5f3f66bbc0a16f64ffb6ce8f2c8ef to your computer and use it in GitHub Desktop.
OxyPlot drag&drop + create on double click
public class SelectedDataPointViewModel
{
private readonly LineSeries _series;
public DataPoint StartDataPoint { get; private set; }
public DataPoint CurrentDataPoint => _series.Points[SelectedDataPointIndex];
public int SelectedDataPointIndex { get; set; }
public bool IsDragging { get; set; }
public float InitiationDistance { get; set; }
public SelectedDataPointViewModel(LineSeries series)
{
_series = series;
_series.PlotModel.MouseDown += OnMouseDown;
_series.PlotModel.MouseMove += OnMouseMove;
_series.PlotModel.MouseUp += OnMouseUp;
_series.PlotModel.MouseLeave += OnMouseLeave;
InitiationDistance = 0.02f;
}
private void OnMouseLeave(object? sender, OxyMouseEventArgs e)
{
if (IsDragging)
{
EndDrag();
e.Handled = true;
}
}
private void OnMouseUp(object? sender, OxyMouseEventArgs e)
{
if (IsDragging)
{
EndDrag();
e.Handled = true;
}
}
private void OnMouseMove(object? sender, OxyMouseEventArgs e)
{
if (IsDragging)
{
var tmp = _series.Points[SelectedDataPointIndex];
_series.Points.RemoveAt(SelectedDataPointIndex);
_series.Points.Insert(SelectedDataPointIndex,
Axis.InverseTransform(e.Position, _series.XAxis, _series.YAxis)); ;
_series.PlotModel.InvalidatePlot(true);
e.Handled = true;
}
}
private void OnMouseDown(object? sender, OxyMouseDownEventArgs e)
{
if (e.HitTestResult?.Item != null && e.HitTestResult.Item is DataPoint)
{
var dataPointOffset = e.HitTestResult.Index;
var dragAndDropIndex = (int)Math.Round(dataPointOffset);
var isWithinInitiationDistance = Math.Abs(dataPointOffset - dragAndDropIndex) <= InitiationDistance;
var isDragAndDropInitiated = isWithinInitiationDistance && e.ClickCount == 1;
var isCreateInitiated = e.ClickCount > 1;
if (isDragAndDropInitiated)
{
StartDrag(dragAndDropIndex);
e.Handled = true;
}
else if (isCreateInitiated)
{
var insertIndex = (int)Math.Ceiling(dataPointOffset);
CreatePoint(insertIndex, Axis.InverseTransform(e.Position, _series.XAxis, _series.YAxis));
e.Handled = true;
}
}
}
private void CreatePoint(int insertIndex, DataPoint point)
{
IsDragging = false;
StartDataPoint = point;
SelectedDataPointIndex = insertIndex;
_series.Points.Insert(insertIndex, point);
_series.PlotModel.InvalidatePlot(true);
}
private void EndDrag()
{
IsDragging = false;
}
private void StartDrag(int dataPointIndex)
{
StartDataPoint = _series.Points[dataPointIndex];
SelectedDataPointIndex = dataPointIndex;
IsDragging = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment