public Chart GetChart(Chart chart) { if (String.IsNullOrEmpty(chart.Expression)) { return chart; } if (!chart.Expression.ToLower().Contains('x')) { return chart; } if (chart.MaxX - chart.MinX <= 0) { return chart; } if (chart.MaxY - chart.MinY <= 0) { return chart; } if (chart.Width <= 0 || chart.Height <= 0) { return chart; } Func<Double, Double> expressionEvaluator = this.CreateExpressionEvaluator(chart.Expression.Replace(",", ".")); if (expressionEvaluator == null) { return chart; } OperationContext operationContext = OperationContext.Current; Thread thread = new Thread(new ThreadStart(delegate { using (new OperationContextScope(operationContext)) { ChartPlotter chartProtter = new ChartPlotter(); chartProtter.Width = chart.Width; chartProtter.Height = chart.Height; List<EnumerableDataSource<Double>> pointDataSources = this.CreatePointDataSources(chart, expressionEvaluator); foreach (EnumerableDataSource<Double> pointDataSource in pointDataSources) { LineGraph lineGraph = new LineGraph(pointDataSource); lineGraph.LinePen = new System.Windows.Media.Pen(lineGraph.LinePen.Brush, 2.0); chartProtter.Children.Add(lineGraph); } chartProtter.LegendVisible = false; using (MemoryStream memoryStream = new MemoryStream()) { chartProtter.SaveScreenshotToStream(memoryStream, "png"); chart.ImageBytes = memoryStream.ToArray(); } } })); thread.SetApartmentState(System.Threading.ApartmentState.STA); thread.Start(); thread.Join(); return chart; }
private List<EnumerableDataSource<Double>> CreatePointDataSources(Chart chart, Func<Double, Double> expressionEvaluator) { Double coefficient = (chart.MaxX - chart.MinX) / POINTS_COUNT; IEnumerable<Double> data = Enumerable.Range(0, POINTS_COUNT).Select(i => chart.MinX + (Double)i * coefficient); List<List<Double>> dataRanges = this.SplitData(data, expressionEvaluator, chart.MinY, chart.MaxY); List<EnumerableDataSource<Double>> pointDataSources = new List<EnumerableDataSource<Double>>(); foreach (List<Double> dataRange in dataRanges) { EnumerableDataSource<Double> pointDataSource = new EnumerableDataSource<Double>(dataRange); pointDataSource.SetXMapping(i => i); pointDataSource.SetYMapping(expressionEvaluator); pointDataSources.Add(pointDataSource); } return pointDataSources; }