From 10ead514d9690147b8e120566509de10b908830b Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Sun, 8 Nov 2015 00:52:53 +0100 Subject: [PATCH] graphwriter: split long cycles into smaller parts --- GraphDrawer/Program.cs | 32 +- VectoCoreTest/Utils/GraphWriter.cs | 576 ++++++++++++++++++----------- 2 files changed, 376 insertions(+), 232 deletions(-) diff --git a/GraphDrawer/Program.cs b/GraphDrawer/Program.cs index 31d4120c3d..b2fc0a6458 100644 --- a/GraphDrawer/Program.cs +++ b/GraphDrawer/Program.cs @@ -9,11 +9,29 @@ using System.Windows.Forms.DataVisualization.Charting; namespace GraphDrawer { - internal class Program - { - private static void Main(string[] args) - { - GraphWriter.Write(args[0], args[1]); - } - } + internal class Program + { + private const string HELP = @" +Tool for plotting graphs comparing Vecto 2.2 and Vecto 3 + +--split <leng> ... split input into parts of length <len> (in m), only distance output + +"; + + private static void Main(string[] args) + { + if (args.Contains("--split")) { + var idx = Array.FindIndex(args, x => x == "--split"); + var lenght = int.Parse(args[idx + 1]); + var success = true; + var start = 0; + do { + success = GraphWriter.WriteDistanceSlice(args[0], args[1], start, start + lenght); + start += lenght; + } while (success); + GraphWriter.Write(args[0], args[1]); + } + GraphWriter.Write(args[0], args[1]); + } + } } \ No newline at end of file diff --git a/VectoCoreTest/Utils/GraphWriter.cs b/VectoCoreTest/Utils/GraphWriter.cs index 4522ac47f3..cda940f97b 100644 --- a/VectoCoreTest/Utils/GraphWriter.cs +++ b/VectoCoreTest/Utils/GraphWriter.cs @@ -18,248 +18,374 @@ using Point = System.Drawing.Point; namespace TUGraz.VectoCore.Tests.Utils { - public static class GraphWriter - { - private static bool _enabled = true; + public static class GraphWriter + { + private static bool _enabled = true; - private static Size _diagramSize = new Size(2000, 440); + private static Size _diagramSize = new Size(2000, 440); private static readonly Font AxisLabelFont = new Font("Consolas", 10); - private static readonly Font AxisTitleFont = new Font("Verdana", 12); + private static readonly Font AxisTitleFont = new Font("Verdana", 12); private static readonly Font LegendFont = new Font("Verdana", 14); - public static void Enabled() - { - _enabled = true; - } - - public static void Disable() - { - _enabled = false; - } - - public static void Write(string fileNameV3, string fileNameV22 = null) - { - if (!_enabled) { - return; - } - - var modDataV3 = VectoCSVFile.Read(fileNameV3); - if (!File.Exists(fileNameV22)) { - LogManager.GetCurrentClassLogger().Error("Modfile V2.2 not found: " + fileNameV22); - //Write(fileNameV3); - //return; - } - DataTable modDataV22 = null; - if (fileNameV22 != null) { - modDataV22 = VectoCSVFile.Read(fileNameV22); - } - var xfields = new[] { ModalResultField.time, ModalResultField.dist }; - - var yfields = new[] { ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, ModalResultField.Pe_eng, ModalResultField.Tq_eng, ModalResultField.FCMap }; - - var titleHeight = (50 * 100.0f) / (_diagramSize.Height * yfields.Count()); - - foreach (var xfield in xfields) { - var fileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileNameV3), xfield.GetName()); - - var x = LoadData(modDataV3, xfield.GetName()); - var x2 = new double[]{ double.NegativeInfinity}; - if (fileNameV22 != null && modDataV22 != null) { - x2 = LoadData(modDataV22, xfield.GetName()); - } - var plotSize = new Size(_diagramSize.Width, _diagramSize.Height * yfields.Count()); - var maxX = (int)(Math.Ceiling(Math.Max(x.Max(), x2.Max()) * 1.01 / 10.0) * 10.0); - var minX = (int)(Math.Floor(Math.Max(x.Min(), x2.Min()) / 10.0) * 10.0); - var chart = new Chart { Size = plotSize }; - - - for (var i = 0; i < yfields.Length; i++) { - var yfield = yfields[i]; + public static void Enabled() + { + _enabled = true; + } + + public static void Disable() + { + _enabled = false; + } + + public static void Write(string fileNameV3, string fileNameV22 = null) + { + if (!_enabled) { + return; + } + + var modDataV3 = VectoCSVFile.Read(fileNameV3); + if (!File.Exists(fileNameV22)) { + LogManager.GetCurrentClassLogger().Error("Modfile V2.2 not found: " + fileNameV22); + //Write(fileNameV3); + //return; + } + DataTable modDataV22 = null; + if (fileNameV22 != null) { + modDataV22 = VectoCSVFile.Read(fileNameV22); + } + var xfields = new[] { ModalResultField.time, ModalResultField.dist }; + + var yfields = new[] { + ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, + ModalResultField.Pe_eng, ModalResultField.Tq_eng, ModalResultField.FCMap + }; + + var titleHeight = (50 * 100.0f) / (_diagramSize.Height * yfields.Count()); + + foreach (var xfield in xfields) { + var fileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileNameV3), + xfield.GetName()); + + var x = LoadData(modDataV3, xfield.GetName()); + var x2 = new double[] { double.NegativeInfinity }; + if (fileNameV22 != null && modDataV22 != null) { + x2 = LoadData(modDataV22, xfield.GetName()); + } + var plotSize = new Size(_diagramSize.Width, _diagramSize.Height * yfields.Count()); + var maxX = (int)(Math.Ceiling(Math.Max(x.Max(), x2.Max()) * 1.01 / 10.0) * 10.0); + var minX = (int)(Math.Floor(Math.Max(x.Min(), x2.Min()) / 10.0) * 10.0); + var chart = new Chart { Size = plotSize }; + + + for (var i = 0; i < yfields.Length; i++) { + var yfield = yfields[i]; var y = LoadData(modDataV3, yfield.GetName()); - var chartArea = AddChartArea(chart, yfield.ToString(), xfield.GetCaption(), maxX, minX, yfield.GetCaption(), yfield == ModalResultField.Gear); + var chartArea = AddChartArea(chart, yfield.ToString(), xfield.GetCaption(), maxX, minX, + yfield.GetCaption(), yfield == ModalResultField.Gear); - var legend = CreateLegend(chart, yfield.ToString()); + var legend = CreateLegend(chart, yfield.ToString()); - if (yfield == ModalResultField.v_act) { - var y3 = LoadData(modDataV3, ModalResultField.v_targ.GetName()); + if (yfield == ModalResultField.v_act) { + var y3 = LoadData(modDataV3, ModalResultField.v_targ.GetName()); var series3 = CreateSeries("v_target", legend, chartArea, chart, Color.Green, x, y3); - } + } - var series1 = CreateSeries( string.Format("Vecto 3 - {0}", yfield), legend, chartArea, chart,Color.Blue, x, y); + var series1 = CreateSeries(string.Format("Vecto 3 - {0}", yfield), legend, chartArea, chart, + Color.Blue, x, y); - if (fileNameV22 != null) { - var y2 = LoadData(modDataV22, yfield.GetName()); - var series2 = CreateSeries(string.Format("Vecto 2.2 - {0}", yfield), legend, chartArea, chart, Color.Red, x2, - y2); - } + if (fileNameV22 != null) { + var y2 = LoadData(modDataV22, yfield.GetName()); + var series2 = CreateSeries(string.Format("Vecto 2.2 - {0}", yfield), legend, chartArea, chart, + Color.Red, x2, + y2); + } - PositionChartArea(chartArea, titleHeight, i, yfields.Count()); + PositionChartArea(chartArea, titleHeight, i, yfields.Count()); - if (i > 0) { + if (i > 0) { AlignChart(chart, yfield.ToString(), yfields[0].ToString()); - } - } + } + } AddTitle(chart, Path.GetFileNameWithoutExtension(fileName), yfields[0].ToString()); - chart.Invalidate(); - chart.SaveImage(fileName, ChartImageFormat.Png); - } - } - - private static void AddTitle(Chart chart, string titleText, string dockToChartArea) - { - var title = new Title(); - title.Text = titleText; - title.DockedToChartArea = dockToChartArea; - title.IsDockedInsideChartArea = false; - title.Font = new Font("Verdana", 18, FontStyle.Bold); - chart.Titles.Add(title); - } - - private static double[] LoadData(DataTable modDataV3, string field) - { - return modDataV3.Rows.Cast<DataRow>() - .Select(v => v.Field<string>(field).Length == 0 - ? Double.NaN - : v.Field<string>(field).ToDouble()) - .ToArray(); - } - - private static void AlignChart(Chart chart, string chartToAlign, string chartToAlignWith) - { - chart.ChartAreas[chartToAlign].AlignWithChartArea = chartToAlignWith; - chart.ChartAreas[chartToAlign].AlignmentOrientation = AreaAlignmentOrientations.Vertical; - chart.ChartAreas[chartToAlign].AlignmentStyle = AreaAlignmentStyles.All; - } - - private static void PositionChartArea(ChartArea chartArea, float titleHeight, int i, int numCharts) - { - chartArea.Position.Auto = false; - chartArea.Position.Width = 85; - chartArea.Position.Height = (100.0f - titleHeight) / numCharts; - chartArea.Position.X = 0; - chartArea.Position.Y = (i * (100.0f - titleHeight)) / numCharts + titleHeight; - } - - private static ChartArea AddChartArea(Chart chart, string name, string axisXTitle, int xMax, int xMin, string axisYTitle, bool discreteValues) - { - var chartArea = new ChartArea { Name = name }; - chartArea.AxisX.MajorGrid.LineColor = Color.DarkGray; - chartArea.AxisY.MajorGrid.LineColor = Color.DarkGray; - chartArea.AxisX.LabelStyle.Font = AxisLabelFont; - chartArea.AxisY.LabelStyle.Font = AxisLabelFont; - - chartArea.AxisX.Interval = xMax / 20.0; - chartArea.AxisX.Maximum = xMax; - chartArea.AxisX.Minimum = xMin; - chartArea.AxisX.MinorGrid.Enabled = true; - chartArea.AxisX.MinorGrid.Interval = xMax / 100.0; - chartArea.AxisX.MinorGrid.LineColor = Color.LightGray; - chartArea.AxisX.Title = axisXTitle; - chartArea.AxisX.TitleFont = AxisTitleFont; - chartArea.AxisX.RoundAxisValues(); - chartArea.AxisX.MajorTickMark.Size = 2 * 100.0f / _diagramSize.Height; - - chartArea.AxisY.Title = axisYTitle; - chartArea.AxisY.TitleFont = AxisTitleFont; - chartArea.AxisY.RoundAxisValues(); - if (discreteValues) { - chartArea.AxisY.MajorGrid.Interval = 1; - chartArea.AxisY.MinorGrid.Enabled = false; - } else { - chartArea.AxisY.MinorGrid.Enabled = true; - } - chartArea.AxisY.MinorGrid.LineColor = Color.LightGray; - chartArea.AxisY.MajorTickMark.Size = 5 * 100.0f / _diagramSize.Width; - - chart.ChartAreas.Add(chartArea); - return chartArea; - } - - private static Legend CreateLegend(Chart chart, string dockToChartArea) - { - var legend = new Legend(dockToChartArea.ToString()) { - Docking = Docking.Right, - IsDockedInsideChartArea = false, - DockedToChartArea = dockToChartArea, - Font = LegendFont, - }; - chart.Legends.Add(legend); - return legend; - } - - private static Series CreateSeries(String name, Legend legend, ChartArea chartArea, Chart chart, Color color, double[] x, double[] y) - { - ModalResultField yfield; - var series1 = new Series { - Name = name, - ChartType = SeriesChartType.Line, - Color = color, - BorderWidth = 2, - Legend = legend.Name, - IsVisibleInLegend = true, - ChartArea = chartArea.Name, - }; - - chart.Series.Add(series1); - chart.Series[series1.Name].Points.DataBindXY(x, y); - return series1; - } - - //public static void Write(string fileName) - //{ - // if (!_enabled) { - // return; - // } - - // var modDataV3 = VectoCSVFile.Read(fileName); - - // var xfields = new[] { ModalResultField.time, ModalResultField.dist }; - - // var yfields = new[] { - // ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, ModalResultField.Pe_eng, - // ModalResultField.Tq_eng, ModalResultField.FCMap - // }; - - // var images = new List<Stream>(); - // try { - // foreach (var xfield in xfields) { - // var x = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(xfield.GetName())).ToArray(); - - // for (var i = 1; i <= yfields.Length; i++) { - // var yfield = yfields[i - 1]; - // var y = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(yfield.GetName())).ToArray(); - - // var values = string.Format("{0}|{1}", string.Join(",", x), string.Join(",", y)); - - // if (yfield == ModalResultField.v_act) { - // var y3 = - // modDataV3.Rows.Cast<DataRow>() - // .Select(v => v.Field<string>(ModalResultField.v_targ.GetName())) - // .Select(v => string.IsNullOrWhiteSpace(v) ? "0" : v); - - // values += string.Format("|{0}|{1}|0|0", string.Join(",", x), string.Join(",", y3)); - // } - - // values = values.Replace("NaN", "0"); - // if (values.Length > 14000) { - // // remove all decimal places to reduce request size - // values = Regex.Replace(values, @"\..*?,", ","); - // } - // var maxX = (int)Math.Ceiling(x.ToDouble().Max()); - // images.Add(CreateGraphStream(xfield.GetCaption(), yfield.GetCaption(), maxX, values)); - // } - // var outfileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileName), xfield.GetName()); - // SaveImages(outfileName, images.ToArray()); - // images.Clear(); - // } - // } finally { - // images.ForEach(x => x.Close()); - // } - //} - } + chart.Invalidate(); + chart.SaveImage(fileName, ChartImageFormat.Png); + } + } + + public static bool WriteDistanceSlice(string fileNameV3, string fileNameV22, double start, double end) + { + if (!_enabled) { + return true; + } + + var modDataV3Iput = VectoCSVFile.Read(fileNameV3); + //var modDataV3View = new DataView(modDataV3Iput) { + // RowFilter = string.Format(@"dist > {0} AND dist < {1}", start, end) + //}; + //var modDataV3 = modDataV3View.ToTable(); + var modDataV3tmp = modDataV3Iput.AsEnumerable().Where(row => { + var s = row.ParseDouble("dist"); + return s >= start && s <= end; + }); + + + if (!File.Exists(fileNameV22)) { + //LogManager.GetCurrentClassLogger().Error("Modfile V2.2 not found: " + fileNameV22); + //Write(fileNameV3); + //return; + } + DataTable modDataV22 = null; + if (fileNameV22 != null) { + var modDataV22Input = VectoCSVFile.Read(fileNameV22); + //var modDataV22View = new DataView(modDataV22Input) { + // RowFilter = string.Format(@"dist > {0} AND dist < {1}", start, end) + //}; + var modDataV22tmp = modDataV22Input.AsEnumerable().Where(row => { + var s = row.ParseDouble("dist"); + return s >= start && s <= end; + }); + if (!(modDataV3tmp.Any() || modDataV22tmp.Any())) { + return false; + } + modDataV22 = modDataV22tmp.CopyToDataTable(); + } else { + if (!modDataV3tmp.Any()) { + return false; + } + } + var modDataV3 = modDataV3tmp.CopyToDataTable(); + + //var xfields = new[] { ModalResultField.dist }; + var xfield = ModalResultField.dist; + var yfields = new[] { + ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, + ModalResultField.Pe_eng, ModalResultField.Tq_eng, ModalResultField.FCMap + }; + + var titleHeight = (50 * 100.0f) / (_diagramSize.Height * yfields.Count()); + + //foreach (var xfield in xfields) { + var fileName = string.Format("{0}_{1}-{2:D3}_{3:D3}.png", Path.GetFileNameWithoutExtension(fileNameV3), + xfield.GetName(), (int)(start / 1000), (int)(end / 1000)); + + var x = LoadData(modDataV3, xfield.GetName()); + var x2 = new double[] { double.NegativeInfinity }; + if (fileNameV22 != null && modDataV22 != null) { + x2 = LoadData(modDataV22, xfield.GetName()); + } + var plotSize = new Size(_diagramSize.Width, _diagramSize.Height * yfields.Count()); + var maxX = (int)(Math.Ceiling(Math.Max(x.Max(), x2.Max()) * 1.01 / 10.0) * 10.0); + var minX = (int)(Math.Floor(Math.Max(x.Min(), x2.Min()) / 10.0) * 10.0); + var chart = new Chart { Size = plotSize }; + + + for (var i = 0; i < yfields.Length; i++) { + var yfield = yfields[i]; + var y = LoadData(modDataV3, yfield.GetName()); + + + var chartArea = AddChartArea(chart, yfield.ToString(), xfield.GetCaption(), maxX, minX, + yfield.GetCaption(), yfield == ModalResultField.Gear); + + var legend = CreateLegend(chart, yfield.ToString()); + + if (yfield == ModalResultField.v_act) { + var y3 = LoadData(modDataV3, ModalResultField.v_targ.GetName()); + var series3 = CreateSeries("v_target", legend, chartArea, chart, Color.Green, x, y3); + } + + var series1 = CreateSeries(string.Format("Vecto 3 - {0}", yfield), legend, chartArea, chart, + Color.Blue, x, y); + + if (fileNameV22 != null) { + var y2 = LoadData(modDataV22, yfield.GetName()); + var series2 = CreateSeries(string.Format("Vecto 2.2 - {0}", yfield), legend, chartArea, chart, + Color.Red, x2, + y2); + } + + PositionChartArea(chartArea, titleHeight, i, yfields.Count()); + + if (i > 0) { + AlignChart(chart, yfield.ToString(), yfields[0].ToString()); + } + //} + + AddTitle(chart, Path.GetFileNameWithoutExtension(fileName), yfields[0].ToString()); + + chart.Invalidate(); + chart.SaveImage(fileName, ChartImageFormat.Png); + } + return true; + } + + + private static void AddTitle(Chart chart, string titleText, string dockToChartArea) + { + var title = new Title(); + title.Text = titleText; + title.DockedToChartArea = dockToChartArea; + title.IsDockedInsideChartArea = false; + title.Font = new Font("Verdana", 18, FontStyle.Bold); + chart.Titles.Add(title); + } + + private static double[] LoadData(DataTable modDataV3, string field) + { + return modDataV3.Rows.Cast<DataRow>() + .Select(v => v.Field<string>(field).Length == 0 + ? Double.NaN + : v.Field<string>(field).ToDouble()) + .ToArray(); + } + + //private static double[] LoadData(DataView modDataV3, string field) + //{ + // return modDataV3.Rows.Cast<DataRow>() + // .Select(v => v.Field<string>(field).Length == 0 + // ? Double.NaN + // : v.Field<string>(field).ToDouble()) + // .ToArray(); + //} + + private static void AlignChart(Chart chart, string chartToAlign, string chartToAlignWith) + { + chart.ChartAreas[chartToAlign].AlignWithChartArea = chartToAlignWith; + chart.ChartAreas[chartToAlign].AlignmentOrientation = AreaAlignmentOrientations.Vertical; + chart.ChartAreas[chartToAlign].AlignmentStyle = AreaAlignmentStyles.All; + } + + private static void PositionChartArea(ChartArea chartArea, float titleHeight, int i, int numCharts) + { + chartArea.Position.Auto = false; + chartArea.Position.Width = 85; + chartArea.Position.Height = (100.0f - titleHeight) / numCharts; + chartArea.Position.X = 0; + chartArea.Position.Y = (i * (100.0f - titleHeight)) / numCharts + titleHeight; + } + + private static ChartArea AddChartArea(Chart chart, string name, string axisXTitle, int xMax, int xMin, + string axisYTitle, bool discreteValues) + { + var chartArea = new ChartArea { Name = name }; + chartArea.AxisX.MajorGrid.LineColor = Color.DarkGray; + chartArea.AxisY.MajorGrid.LineColor = Color.DarkGray; + chartArea.AxisX.LabelStyle.Font = AxisLabelFont; + chartArea.AxisY.LabelStyle.Font = AxisLabelFont; + + chartArea.AxisX.Interval = xMax / 20.0; + chartArea.AxisX.Maximum = xMax; + chartArea.AxisX.Minimum = xMin; + chartArea.AxisX.MinorGrid.Enabled = true; + chartArea.AxisX.MinorGrid.Interval = (xMax - xMin) / 100.0; + chartArea.AxisX.MinorGrid.LineColor = Color.LightGray; + chartArea.AxisX.Title = axisXTitle; + chartArea.AxisX.TitleFont = AxisTitleFont; + chartArea.AxisX.RoundAxisValues(); + chartArea.AxisX.MajorTickMark.Size = 2 * 100.0f / _diagramSize.Height; + + chartArea.AxisY.Title = axisYTitle; + chartArea.AxisY.TitleFont = AxisTitleFont; + chartArea.AxisY.RoundAxisValues(); + if (discreteValues) { + chartArea.AxisY.MajorGrid.Interval = 1; + chartArea.AxisY.MinorGrid.Enabled = false; + } else { + chartArea.AxisY.MinorGrid.Enabled = true; + } + chartArea.AxisY.MinorGrid.LineColor = Color.LightGray; + chartArea.AxisY.MajorTickMark.Size = 5 * 100.0f / _diagramSize.Width; + + chart.ChartAreas.Add(chartArea); + return chartArea; + } + + private static Legend CreateLegend(Chart chart, string dockToChartArea) + { + var legend = new Legend(dockToChartArea.ToString()) { + Docking = Docking.Right, + IsDockedInsideChartArea = false, + DockedToChartArea = dockToChartArea, + Font = LegendFont, + }; + chart.Legends.Add(legend); + return legend; + } + + private static Series CreateSeries(String name, Legend legend, ChartArea chartArea, Chart chart, Color color, + double[] x, double[] y) + { + ModalResultField yfield; + var series1 = new Series { + Name = name, + ChartType = SeriesChartType.Line, + Color = color, + BorderWidth = 2, + Legend = legend.Name, + IsVisibleInLegend = true, + ChartArea = chartArea.Name, + }; + + chart.Series.Add(series1); + chart.Series[series1.Name].Points.DataBindXY(x, y); + return series1; + } + + //public static void Write(string fileName) + //{ + // if (!_enabled) { + // return; + // } + + // var modDataV3 = VectoCSVFile.Read(fileName); + + // var xfields = new[] { ModalResultField.time, ModalResultField.dist }; + + // var yfields = new[] { + // ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, ModalResultField.Pe_eng, + // ModalResultField.Tq_eng, ModalResultField.FCMap + // }; + + // var images = new List<Stream>(); + // try { + // foreach (var xfield in xfields) { + // var x = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(xfield.GetName())).ToArray(); + + // for (var i = 1; i <= yfields.Length; i++) { + // var yfield = yfields[i - 1]; + // var y = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(yfield.GetName())).ToArray(); + + // var values = string.Format("{0}|{1}", string.Join(",", x), string.Join(",", y)); + + // if (yfield == ModalResultField.v_act) { + // var y3 = + // modDataV3.Rows.Cast<DataRow>() + // .Select(v => v.Field<string>(ModalResultField.v_targ.GetName())) + // .Select(v => string.IsNullOrWhiteSpace(v) ? "0" : v); + + // values += string.Format("|{0}|{1}|0|0", string.Join(",", x), string.Join(",", y3)); + // } + + // values = values.Replace("NaN", "0"); + // if (values.Length > 14000) { + // // remove all decimal places to reduce request size + // values = Regex.Replace(values, @"\..*?,", ","); + // } + // var maxX = (int)Math.Ceiling(x.ToDouble().Max()); + // images.Add(CreateGraphStream(xfield.GetCaption(), yfield.GetCaption(), maxX, values)); + // } + // var outfileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileName), xfield.GetName()); + // SaveImages(outfileName, images.ToArray()); + // images.Clear(); + // } + // } finally { + // images.ForEach(x => x.Close()); + // } + //} + } } \ No newline at end of file -- GitLab