Skip to content

Instantly share code, notes, and snippets.

@TABETA
Created April 25, 2017 22:55
Show Gist options
  • Save TABETA/9acd78fd87cb328c5648a6cfc2b6f98f to your computer and use it in GitHub Desktop.
Save TABETA/9acd78fd87cb328c5648a6cfc2b6f98f to your computer and use it in GitHub Desktop.
<Window x:Class="OxyPlotWpfTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.org/wpf"
xmlns:oxyPlotWpfTests="clr-namespace:OxyPlotWpfTests"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<oxyPlotWpfTests:MainWindowViewModel x:Key="MainWindowViewModel" />
<oxyPlotWpfTests:CustomDataPointConverter x:Key="CustomDataPointConverter"/>
</Window.Resources>
<Grid x:Name="ThisGrid" DataContext="{Binding Source={StaticResource MainWindowViewModel}}">
<oxy:PlotView
Controller="{Binding Controller}"
Model="{Binding PlotModel}">
<oxy:PlotView.DefaultTrackerTemplate>
<ControlTemplate>
<oxy:TrackerControl Position="{Binding Position}" LineExtents="{Binding PlotModel.PlotArea}">
<oxy:TrackerControl.Content>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource CustomDataPointConverter}">
<MultiBinding.Bindings>
<Binding />
<Binding ElementName="ThisGrid"
Path="DataContext.CustomTooltipProvider" />
</MultiBinding.Bindings>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</oxy:TrackerControl.Content>
</oxy:TrackerControl>
</ControlTemplate>
</oxy:PlotView.DefaultTrackerTemplate>
</oxy:PlotView>
</Grid>
</Window>
using System;
using System.Diagnostics;
using System.Windows.Media;
using System.Windows.Threading;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
namespace OxyPlotWpfTests
{
using System;
using System.Globalization;
using System.Windows.Data;
using OxyPlot;
public class CustomDataPointConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var hitResult = values[0] as TrackerHitResult;
if (hitResult == null)
return string.Empty;
var tooltipProvider = values[1] as CustomTooltipProvider;
if (tooltipProvider == null)
return string.Empty;
if (tooltipProvider.GetCustomTooltip == null)
return hitResult.Text;
var customTooltip = tooltipProvider.GetCustomTooltip(hitResult);
if (string.IsNullOrWhiteSpace(customTooltip))
return hitResult.Text;
return hitResult.Text + Environment.NewLine + customTooltip;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class CustomTooltipProvider
{
public Func<TrackerHitResult, string> GetCustomTooltip { set; get; }
}
public class MainWindowViewModel
{
public CustomTooltipProvider CustomTooltipProvider { set; get; }
public PlotModel PlotModel { get; set; }
private readonly LineSeries _lineSeries1 = new LineSeries
{
MarkerType = MarkerType.Circle,
StrokeThickness = 2,
MarkerSize = 3,
Title = "Start",
};
private readonly LineSeries _lineSeries2 = new LineSeries {
MarkerType = MarkerType.Circle,
Title = "End",
StrokeThickness = 2,
MarkerSize = 3,
};
private readonly LinearAxis _xAxis = new LinearAxis {
Minimum = 0,
MaximumPadding = 1,
MinimumPadding = 1,
Position = AxisPosition.Bottom,
Title = "X axis",
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.Dot
};
private readonly LinearAxis _yAxis = new LinearAxis {
Minimum = 0,
MaximumPadding = 1,
MinimumPadding = 1,
Title = "Y axis",
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.Dot,
};
private IPlotController _controller;
private bool _haveNewPoints;
private int _xMax;
private int _yMax;
public MainWindowViewModel()
{
initPlot();
addPoints();
updatePlot();
}
private void initPlot()
{
CustomTooltipProvider = new CustomTooltipProvider { GetCustomTooltip = (hitResult)=>{
var lineSeries = hitResult.Series as LineSeries;
var nearestPointIndex = hitResult.Index;
return "nearestPointIndex: " + nearestPointIndex;
}
};
PlotModel = new PlotModel
{
Title = "FFT",
Subtitle = "Pan (right click and drag)/Zoom (Middle click and drag)/Reset (double-click)",
Series = { _lineSeries1, _lineSeries2, },
Axes = { _xAxis, _yAxis },
};
PlotModel.MouseDown += (sender, args) =>
{
if (args.ChangedButton == OxyMouseButton.Left && args.ClickCount == 2)
{
foreach (var axis in PlotModel.Axes)
axis.Reset();
PlotModel.InvalidatePlot(false);
}
};
foreach (var series in PlotModel.Series)
{
series.MouseDown += (s, e) =>
{
if (e.ChangedButton == OxyMouseButton.Left)
{
PlotModel.Subtitle = "Index of nearest point in LineSeries: " + Math.Round(e.HitTestResult.Index);
PlotModel.InvalidatePlot(false);
}
};
}
}
private void addPoints()
{
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
var rnd = new Random();
var x = 1;
_xMax = Math.Max(_xMax, x);
timer.Tick += (sender, args) =>
{
foreach (LineSeries series in PlotModel.Series)
{
var y = rnd.Next(100);
_yMax = Math.Max(_yMax, y);
series.Points.Add(new DataPoint(x, y));
}
_xMax = Math.Max(_xMax, ++x);
_haveNewPoints = true;
};
timer.Start();
}
private void updatePlot()
{
CompositionTarget.Rendering += (sender, args) =>
{
if (_haveNewPoints)
{
if (_yMax > 0 && _xMax > 0)
{
_yAxis.Maximum = _yMax + 3;
_xAxis.Maximum = _xMax + 1;
}
PlotModel.InvalidatePlot(false);
_haveNewPoints = false;
}
};
}
public IPlotController Controller
{
get
{
if (_controller == null)
{
// show tracker with mouse move
_controller = new PlotController();
_controller.BindMouseEnter(PlotCommands.HoverPointsOnlyTrack);
}
return _controller;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment