public static List<Point> OptimizeAsIndexedChart(this IEnumerable<Point> points, Chart chart) { var isFirst = true; var result = new List<Point>(); var ppp = chart.PerformanceConfiguration.PixelsPerPoint; double? x = null; var g = new List<Point>(); foreach (var point in points) { var chartValue = chart.ToPlotArea(point.X,AxisTags.X); if (x == null) x = chartValue; if (chartValue - x < ppp) { g.Add(point); continue; } //ToDo: Think about this: //average seems the best "general" method, but maybe a developer //should be able to choose the method. var xx = g.Average(p => p.X); if (isFirst) { xx = g.First().X; isFirst = false; } result.Add(new Point(xx, g.Average(p => p.Y))); g = new List<Point> {point}; x = chart.ToPlotArea(point.X, AxisTags.X); } result.Add(new Point(g.Last().X, g.Average(p => p.Y))); return result; }
/// <summary> /// Scales a graph value to screen according to an axis. /// </summary> /// <param name="value"></param> /// <param name="axis"></param> /// <param name="chart"></param> /// <returns></returns> public static double ToPlotArea(double value, AxisTags axis, Chart chart) { //y = m (x - x1) + y1 var p1 = axis == AxisTags.X ? new Point(chart.Max.X, chart.PlotArea.Width + chart.PlotArea.X) : new Point(chart.Max.Y, chart.PlotArea.Y); var p2 = axis == AxisTags.X ? new Point(chart.Min.X, chart.PlotArea.X) : new Point(chart.Min.Y, chart.PlotArea.Y + chart.PlotArea.Height); var m = (p2.Y - p1.Y) / (p2.X - p1.X); return m * (value - p1.X) + p1.Y; }
private void Chart_OnPlot(Chart chart) { var sunPoint = chart.ToPlotArea(new Point(4, 35)); var snowPoint = chart.ToPlotArea(new Point(8, -3)); var notePoint = chart.ToPlotArea(new Point(1, 35)); Canvas.SetLeft(_sun, sunPoint.X - 20); Canvas.SetLeft(_snow, snowPoint.X - 20); Canvas.SetLeft(_note, notePoint.X); Canvas.SetTop(_sun, sunPoint.Y - 20); Canvas.SetTop(_snow, snowPoint.Y - 20); Canvas.SetTop(_note, notePoint.Y); }
private void InitializeSeries(Chart chart) { #if DEBUG Trace.WriteLine("Chart was initialized (" + DateTime.Now.ToLongTimeString() + ")"); #endif chart.SeriesInitialized = true; foreach (var series in chart.Series) { var index = _colorIndexer++; series.Chart = chart; series.Collection = Series; series.Stroke = series.Stroke ?? new SolidColorBrush( Colors[(int) (index - Colors.Count*Math.Truncate(index/(decimal) Colors.Count))]); series.Fill = series.Fill ?? new SolidColorBrush( Colors[(int) (index - Colors.Count*Math.Truncate(index/(decimal) Colors.Count))]) { Opacity = DefaultFillOpacity }; series.RequiresPlot = true; series.RequiresAnimation = true; var observable = series.Values as INotifyCollectionChanged; if (observable != null) observable.CollectionChanged += chart.OnDataSeriesChanged; } chart.ClearAndPlot(); var anim = new DoubleAnimation { From = 0, To = 1, Duration = TimeSpan.FromMilliseconds(1000) }; if (!chart.DisableAnimation) chart.Canvas.BeginAnimation(OpacityProperty, anim); chart.Series.CollectionChanged += (sender, args) => { chart._seriesChanged.Stop(); chart._seriesChanged.Start(); if (args.OldItems != null) foreach (var serie in args.OldItems.Cast<Series>()) { chart.EraseSerieBuffer.Add(serie); } var newElements = args.NewItems != null ? args.NewItems.Cast<Series>() : new List<Series>(); chart.RequiresScale = true; foreach (var serie in chart.Series.Where(x => !newElements.Contains(x))) { chart.EraseSerieBuffer.Add(serie); serie.RequiresPlot = true; } if (args.NewItems != null) foreach (var series in newElements) { var index = _colorIndexer++; series.Chart = chart; series.Collection = Series; series.Stroke = series.Stroke ?? new SolidColorBrush( Colors[(int)(index - Colors.Count * Math.Truncate(index / (decimal)Colors.Count))]); series.Fill = series.Fill ?? new SolidColorBrush( Colors[(int)(index - Colors.Count * Math.Truncate(index / (decimal)Colors.Count))]) { Opacity = DefaultFillOpacity }; series.RequiresPlot = true; series.RequiresAnimation = true; var observable = series.Values as INotifyCollectionChanged; if (observable != null) observable.CollectionChanged += chart.OnDataSeriesChanged; #if DEBUG if (observable == null) Trace.WriteLine("series do not implements INotifyCollectionChanged"); #endif } }; }
private void Chart_OnDataMouseDown(Chart chart, Shape sender, Point dataPoint) { MessageBox.Show("you clicked over (" + dataPoint.X + "," + dataPoint.Y + ")"); }
/// <summary> /// Scales a graph point to screen. /// </summary> /// <param name="value"></param> /// <param name="chart"></param> /// <returns></returns> public static Point ToPlotArea(Point value, Chart chart) { return new Point(ToPlotArea(value.X, AxisTags.X, chart), ToPlotArea(value.Y, AxisTags.Y, chart)); }