diff --git a/GraphDrawer/Program.cs b/GraphDrawer/Program.cs index 31d4120c3dac63b66ce60cbf9fe7228d6b832814..9cde53c0c72c3d218dc9ac49047fb55b564140b4 100644 --- a/GraphDrawer/Program.cs +++ b/GraphDrawer/Program.cs @@ -9,11 +9,36 @@ 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")) { + Console.WriteLine("plotting graphs splitted by distance"); + var idx = Array.FindIndex(args, x => x == "--split"); + var lenght = int.Parse(args[idx + 1]); + var success = true; + var start = 0; + do { + Console.WriteLine("plotting {0} - {1}", start / 1000, (start + lenght) / 1000); + success = GraphWriter.WriteDistanceSlice(args[0], args[1], start, start + lenght); + start += lenght; + } while (success); + Console.WriteLine("plotting full cycle"); + GraphWriter.Write(args[0], args[1]); + Console.WriteLine("done"); + return; + } + Console.WriteLine("plotting graphs..."); + GraphWriter.Write(args[0], args[1]); + Console.WriteLine("done"); + } + } } \ No newline at end of file diff --git a/VectoConsole/Program.cs b/VectoConsole/Program.cs index 64ddb2f4503283ee3338aa7ef2135420bee889d3..6172449a69ea5186b5b1fb14962949a5e7991e47 100644 --- a/VectoConsole/Program.cs +++ b/VectoConsole/Program.cs @@ -14,14 +14,14 @@ using TUGraz.VectoCore.Models.Simulation.Impl; namespace VectoConsole { - internal static class Program - { - private static int NumLines; - private static int ProgessCounter { get; set; } + internal static class Program + { + private static int NumLines; + private static int ProgessCounter { get; set; } - private const string USAGE = @"Usage: vecto.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]"; + private const string USAGE = @"Usage: vecto.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]"; - private const string HELP = @" + private const string HELP = @" Commandline Interface for Vecto. Synopsis: @@ -50,173 +50,180 @@ Examples: vecto.exe -h "; - private static int Main(string[] args) - { - try { - // on -h display help and terminate. - if (args.Contains("-h")) { - ShowVersionInformation(); - Console.Write(HELP); - return 0; - } - - // on -v: activate verbose console logger - var logLevel = LogLevel.Fatal; - - // Fatal > Error > Warn > Info > Debug > Trace - var debugEnabled = false; - - if (args.Contains("-v")) { - // display errors, warnings - logLevel = LogLevel.Warn; - debugEnabled = true; - } else if (args.Contains("-vv")) { - // also display info - logLevel = LogLevel.Info; - debugEnabled = true; - } else if (args.Contains("-vvv")) { - // display debug messages - logLevel = LogLevel.Debug; - debugEnabled = true; - } else if (args.Contains("-vvvv")) { - // display everything! - logLevel = LogLevel.Trace; - debugEnabled = true; - } - - var config = LogManager.Configuration; - //config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("ConsoleLogger"))); - config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile"))); - LogManager.Configuration = config; - Trace.Listeners.Add(new ConsoleTraceListener(true)); - - if (args.Contains("-V") || debugEnabled) { - ShowVersionInformation(); - } - - args = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t" }).ToArray(); - - // if no other arguments given: display usage and terminate - if (!args.Any()) { - Console.Write(USAGE); - return 1; - } - - var stopWatch = new Stopwatch(); - var timings = new Dictionary<string, double>(); - - // process the file list and start simulation - var fileList = args; - - var sumFileName = Path.Combine(Path.GetDirectoryName(fileList.First()) ?? "", - Path.GetFileNameWithoutExtension(fileList.First()) + Constants.FileExtensions.SumFile); - var sumWriter = new SummaryFileWriter(sumFileName); - var jobContainer = new JobContainer(sumWriter); - - var mode = SimulatorFactory.FactoryMode.DeclarationMode; - if (args.Contains("-eng")) { - mode = SimulatorFactory.FactoryMode.EngineeringMode; - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine("Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!"); - Console.ResetColor(); - } - - Console.WriteLine("Reading Job Files"); - stopWatch.Start(); - foreach (var file in fileList.Where(f => Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile)) { - var runsFactory = new SimulatorFactory(mode, file); - if (args.Contains("-mod")) { - runsFactory.WriteModalResults = true; - } - jobContainer.AddRuns(runsFactory); - } - stopWatch.Stop(); - timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds); - stopWatch.Reset(); - - Console.WriteLine("Starting simulation runs"); - if (debugEnabled) { - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine("Debug-Output is enabled, executing simulation runs sequentially"); - Console.ResetColor(); - } - Console.WriteLine(); - stopWatch.Start(); - jobContainer.Execute(!debugEnabled); - - Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { - var isCtrlC = e.SpecialKey == ConsoleSpecialKey.ControlC; - var isCtrlBreak = e.SpecialKey == ConsoleSpecialKey.ControlBreak; - - if (isCtrlC) { - Console.WriteLine("Canceling simulation!"); - } - }; - - //var x = Console.CursorLeft; - while (!jobContainer.AllCompleted) { - PrintProgress(jobContainer.GetProgress()); - Thread.Sleep(250); - } - stopWatch.Stop(); - timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds); - - PrintProgress(jobContainer.GetProgress(), args.Contains("-t")); - if (args.Contains("-t")) { - PrintTimings(timings); - } - } catch (Exception e) { - Console.Error.WriteLine(e.Message); - //Trace.TraceError(e.ToString()); - Console.ForegroundColor = ConsoleColor.Red; - Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); - Console.ResetColor(); - Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; - } - return Environment.ExitCode; - } - - private static void ShowVersionInformation() - { - var vectodll = AssemblyName.GetAssemblyName("VectoCore.dll"); - Console.WriteLine("VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version); - Console.WriteLine("VectoCore: {0}", vectodll.Version); - } - - private static void PrintProgress(Dictionary<string, JobContainer.ProgressEntry> progessData, bool showTiming = true) - { - Console.SetCursorPosition(0, Console.CursorTop - NumLines); - NumLines = 0; - var sumProgress = 0.0; - foreach (var progressEntry in progessData) { - if (progressEntry.Value.Success) { - Console.ForegroundColor = ConsoleColor.Green; - } else if (progressEntry.Value.Error != null) { - Console.ForegroundColor = ConsoleColor.Red; - } - var timingString = ""; - if (showTiming && progressEntry.Value.ExecTime > 0) { - timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0); - } - Console.WriteLine("{0,-60} {1,8:P}{2}", progressEntry.Key, progressEntry.Value.Progress, timingString); - Console.ResetColor(); - sumProgress += progressEntry.Value.Progress; - NumLines++; - } - sumProgress /= NumLines; - var spinner = "/-\\|"[ProgessCounter++ % 4]; - var bar = new string('#', (int)(sumProgress * 100.0 / 2)); - Console.WriteLine(string.Format(" {2} [{1,-50}] [{0,7:P}]", sumProgress, bar, spinner)); - NumLines++; - } - - private static void PrintTimings(Dictionary<string, double> timings) - { - Console.WriteLine(); - Console.WriteLine("---- timing information ----"); - foreach (var timing in timings) { - Console.WriteLine("{0,-20}: {1:F2}s", timing.Key, timing.Value / 1000); - } - } - } + private static JobContainer jobContainer; + + private static int Main(string[] args) + { + try { + // on -h display help and terminate. + if (args.Contains("-h")) { + ShowVersionInformation(); + Console.Write(HELP); + return 0; + } + + // on -v: activate verbose console logger + var logLevel = LogLevel.Fatal; + + // Fatal > Error > Warn > Info > Debug > Trace + var debugEnabled = false; + + if (args.Contains("-v")) { + // display errors, warnings + logLevel = LogLevel.Warn; + debugEnabled = true; + } else if (args.Contains("-vv")) { + // also display info + logLevel = LogLevel.Info; + debugEnabled = true; + } else if (args.Contains("-vvv")) { + // display debug messages + logLevel = LogLevel.Debug; + debugEnabled = true; + } else if (args.Contains("-vvvv")) { + // display everything! + logLevel = LogLevel.Trace; + debugEnabled = true; + } + + var config = LogManager.Configuration; + //config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("ConsoleLogger"))); + config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile"))); + LogManager.Configuration = config; + Trace.Listeners.Add(new ConsoleTraceListener(true)); + + if (args.Contains("-V") || debugEnabled) { + ShowVersionInformation(); + } + + args = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t" }).ToArray(); + + // if no other arguments given: display usage and terminate + if (!args.Any()) { + Console.Write(USAGE); + return 1; + } + + var stopWatch = new Stopwatch(); + var timings = new Dictionary<string, double>(); + + // process the file list and start simulation + var fileList = args; + + var sumFileName = Path.Combine(Path.GetDirectoryName(fileList.First()) ?? "", + Path.GetFileNameWithoutExtension(fileList.First()) + Constants.FileExtensions.SumFile); + var sumWriter = new SummaryFileWriter(sumFileName); + jobContainer = new JobContainer(sumWriter); + + var mode = SimulatorFactory.FactoryMode.DeclarationMode; + if (args.Contains("-eng")) { + mode = SimulatorFactory.FactoryMode.EngineeringMode; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine( + "Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!"); + Console.ResetColor(); + } + + Console.WriteLine("Reading Job Files"); + stopWatch.Start(); + foreach (var file in fileList.Where(f => Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile)) { + var runsFactory = new SimulatorFactory(mode, file); + if (args.Contains("-mod")) { + runsFactory.WriteModalResults = true; + } + jobContainer.AddRuns(runsFactory); + } + stopWatch.Stop(); + timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds); + stopWatch.Reset(); + + Console.WriteLine("Starting simulation runs"); + if (debugEnabled) { + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine("Debug-Output is enabled, executing simulation runs sequentially"); + Console.ResetColor(); + } + Console.WriteLine(); + stopWatch.Start(); + jobContainer.Execute(!debugEnabled); + + Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { + var isCtrlC = e.SpecialKey == ConsoleSpecialKey.ControlC; + var isCtrlBreak = e.SpecialKey == ConsoleSpecialKey.ControlBreak; + + if (!isCtrlC) { + return; + } + //Console.WriteLine("Canceling simulation!"); + e.Cancel = true; + Program.jobContainer.CancelCurrent(); + }; + + //var x = Console.CursorLeft; + while (!jobContainer.AllCompleted) { + PrintProgress(jobContainer.GetProgress()); + Thread.Sleep(250); + } + stopWatch.Stop(); + timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds); + + PrintProgress(jobContainer.GetProgress(), args.Contains("-t")); + if (args.Contains("-t")) { + PrintTimings(timings); + } + } catch (Exception e) { + Console.Error.WriteLine(e.Message); + //Trace.TraceError(e.ToString()); + Console.ForegroundColor = ConsoleColor.Red; + Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); + Console.ResetColor(); + Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; + } + return Environment.ExitCode; + } + + private static void ShowVersionInformation() + { + var vectodll = AssemblyName.GetAssemblyName("VectoCore.dll"); + Console.WriteLine("VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version); + Console.WriteLine("VectoCore: {0}", vectodll.Version); + } + + private static void PrintProgress(Dictionary<string, JobContainer.ProgressEntry> progessData, + bool showTiming = true) + { + Console.SetCursorPosition(0, Console.CursorTop - NumLines); + NumLines = 0; + var sumProgress = 0.0; + foreach (var progressEntry in progessData) { + if (progressEntry.Value.Success) { + Console.ForegroundColor = ConsoleColor.Green; + } else if (progressEntry.Value.Error != null) { + Console.ForegroundColor = ConsoleColor.Red; + } + var timingString = ""; + if (showTiming && progressEntry.Value.ExecTime > 0) { + timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0); + } + Console.WriteLine("{0,-60} {1,8:P}{2}", progressEntry.Key, progressEntry.Value.Progress, timingString); + Console.ResetColor(); + sumProgress += progressEntry.Value.Progress; + NumLines++; + } + sumProgress /= NumLines; + var spinner = "/-\\|"[ProgessCounter++ % 4]; + var bar = new string('#', (int)(sumProgress * 100.0 / 2)); + Console.WriteLine(string.Format(" {2} [{1,-50}] [{0,7:P}]", sumProgress, bar, spinner)); + NumLines++; + } + + private static void PrintTimings(Dictionary<string, double> timings) + { + Console.WriteLine(); + Console.WriteLine("---- timing information ----"); + foreach (var timing in timings) { + Console.WriteLine("{0,-20}: {1:F2}s", timing.Key, timing.Value / 1000); + } + } + } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/JobContainer.cs b/VectoCore/Models/Simulation/Impl/JobContainer.cs index e6e7c135834f5c656e46aa04d5264e5ab001da43..8d7c748dbe18a2e1e4b6aeb5ecb651b009a37c0e 100644 --- a/VectoCore/Models/Simulation/Impl/JobContainer.cs +++ b/VectoCore/Models/Simulation/Impl/JobContainer.cs @@ -8,182 +8,191 @@ using TUGraz.VectoCore.Models.Simulation.Data; namespace TUGraz.VectoCore.Models.Simulation.Impl { - /// <summary> - /// Container for simulation jobs. - /// </summary> - public class JobContainer : LoggingObject - { - internal readonly List<JobEntry> Runs = new List<JobEntry>(); - private readonly SummaryFileWriter _sumWriter; - - private static int _jobNumber; - - /// <summary> - /// Initializes a new empty instance of the <see cref="JobContainer"/> class. - /// </summary> - /// <param name="sumWriter">The sum writer.</param> - public JobContainer(SummaryFileWriter sumWriter) - { - _sumWriter = sumWriter; - } - - public void AddRun(IVectoRun run) - { - _jobNumber++; - Runs.Add(new JobEntry() { - Run = run, - Container = this, - }); - } - - public void AddRuns(IEnumerable<IVectoRun> runs) - { - _jobNumber++; - //Runs.AddRange(runs); - foreach (var run in runs) { - Runs.Add(new JobEntry() { - Run = run, - Container = this, - }); - } - } - - public void AddRuns(SimulatorFactory factory) - { - factory.SumWriter = _sumWriter; - factory.JobNumber = _jobNumber++; - AddRuns(factory.SimulationRuns()); - } - - /// <summary> - /// Execute all runs, waits until finished. - /// </summary> - public void Execute(bool multithreaded = true) - { - Log.Info("VectoRun started running. Executing Runs."); - - foreach (var job in Runs) { - job.Worker = new BackgroundWorker() { - WorkerSupportsCancellation = true, - WorkerReportsProgress = true, - }; - job.Worker.DoWork += job.DoWork; - job.Worker.ProgressChanged += job.ProgressChanged; - job.Worker.RunWorkerCompleted += job.RunWorkerCompleted; - if (multithreaded) { - job.Started = true; - job.Worker.RunWorkerAsync(); - } - } - if (!multithreaded) { - var entry = Runs.First(); - entry.Started = true; - entry.Worker.RunWorkerAsync(); - } - //Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray()); + /// <summary> + /// Container for simulation jobs. + /// </summary> + public class JobContainer : LoggingObject + { + internal readonly List<JobEntry> Runs = new List<JobEntry>(); + private readonly SummaryFileWriter _sumWriter; + + private static int _jobNumber; + + /// <summary> + /// Initializes a new empty instance of the <see cref="JobContainer"/> class. + /// </summary> + /// <param name="sumWriter">The sum writer.</param> + public JobContainer(SummaryFileWriter sumWriter) + { + _sumWriter = sumWriter; + } + + public void AddRun(IVectoRun run) + { + _jobNumber++; + Runs.Add(new JobEntry() { + Run = run, + Container = this, + }); + } + + public void AddRuns(IEnumerable<IVectoRun> runs) + { + _jobNumber++; + //Runs.AddRange(runs); + foreach (var run in runs) { + Runs.Add(new JobEntry() { + Run = run, + Container = this, + }); + } + } + + public void AddRuns(SimulatorFactory factory) + { + factory.SumWriter = _sumWriter; + factory.JobNumber = _jobNumber++; + AddRuns(factory.SimulationRuns()); + } + + /// <summary> + /// Execute all runs, waits until finished. + /// </summary> + public void Execute(bool multithreaded = true) + { + Log.Info("VectoRun started running. Executing Runs."); + + foreach (var job in Runs) { + job.Worker = new BackgroundWorker() { + WorkerSupportsCancellation = true, + WorkerReportsProgress = true, + }; + job.Worker.DoWork += job.DoWork; + job.Worker.ProgressChanged += job.ProgressChanged; + job.Worker.RunWorkerCompleted += job.RunWorkerCompleted; + if (multithreaded) { + job.Started = true; + job.Worker.RunWorkerAsync(); + } + } + if (!multithreaded) { + var entry = Runs.First(); + entry.Started = true; + entry.Worker.RunWorkerAsync(); + } + //Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray()); //_sumWriter.Finish(); - } - - public void Cancel() - { - foreach (var job in Runs) { - if (job.Worker != null && job.Worker.WorkerSupportsCancellation) { - job.Worker.CancelAsync(); - } - } - } - - private static AutoResetEvent resetEvent = new AutoResetEvent(false); - - public void WaitFinished() - { - resetEvent.WaitOne(); - } - - - private void JobCompleted(JobEntry jobEntry) - { - var next = Runs.FirstOrDefault(x => x.Started == false); - if (next != null) { - next.Started = true; - next.Worker.RunWorkerAsync(); - } - if (Runs.Count(x => x.Done == true) == Runs.Count()) { - _sumWriter.Finish(); - resetEvent.Set(); - } - } - - public Dictionary<string, ProgressEntry> GetProgress() - { - return Runs.ToDictionary(jobEntry => jobEntry.Run.Name, entry => new ProgressEntry() { - Progress = entry.Progress, - Done = entry.Done, - ExecTime = entry.ExecTime, - Success = entry.Success, - Canceled = entry.Canceled, - Error = entry.ExecException - }); - } - - public bool AllCompleted - { - get { return (Runs.Count(x => x.Done == true) == Runs.Count()); } - } - - public class ProgressEntry - { - public double Progress; - public double ExecTime; - public Exception Error; - public bool Canceled; - public bool Success; - public bool Done; - } - - internal class JobEntry : LoggingObject - { - public IVectoRun Run; - public JobContainer Container; - public double Progress; - public bool Done; - public bool Started; - public bool Success; - public bool Canceled; - public double ExecTime; - public Exception ExecException; - - public BackgroundWorker Worker; - - public void DoWork(object sender, DoWorkEventArgs e) - { - var stopWatch = new Stopwatch(); - stopWatch.Start(); - var worker = sender as BackgroundWorker; - try { - Run.Run(worker); - } catch (Exception ex) { - Log.Error(ex, "Error during simulation run!"); - ExecException = ex; - } - if (worker != null && worker.CancellationPending) { - e.Cancel = true; - Canceled = true; - } - stopWatch.Stop(); - Success = Run.FinishedWithoutErrors; - Done = true; - ExecTime = stopWatch.Elapsed.TotalMilliseconds; - Container.JobCompleted(this); - } - - public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {} - - public void ProgressChanged(object sender, ProgressChangedEventArgs e) - { - Progress = e.ProgressPercentage / 10000.0; - } - } - } + } + + public void Cancel() + { + foreach (var job in Runs) { + if (job.Worker != null && job.Worker.WorkerSupportsCancellation) { + job.Worker.CancelAsync(); + } + } + } + + public void CancelCurrent() + { + foreach (var job in Runs) { + if (job.Worker != null && job.Worker.IsBusy && job.Worker.WorkerSupportsCancellation) { + job.Worker.CancelAsync(); + } + } + } + + private static AutoResetEvent resetEvent = new AutoResetEvent(false); + + public void WaitFinished() + { + resetEvent.WaitOne(); + } + + + private void JobCompleted(JobEntry jobEntry) + { + var next = Runs.FirstOrDefault(x => x.Started == false); + if (next != null) { + next.Started = true; + next.Worker.RunWorkerAsync(); + } + if (Runs.Count(x => x.Done == true) == Runs.Count()) { + _sumWriter.Finish(); + resetEvent.Set(); + } + } + + public Dictionary<string, ProgressEntry> GetProgress() + { + return Runs.ToDictionary(jobEntry => jobEntry.Run.Name, entry => new ProgressEntry() { + Progress = entry.Progress, + Done = entry.Done, + ExecTime = entry.ExecTime, + Success = entry.Success, + Canceled = entry.Canceled, + Error = entry.ExecException + }); + } + + public bool AllCompleted + { + get { return (Runs.Count(x => x.Done == true) == Runs.Count()); } + } + + public class ProgressEntry + { + public double Progress; + public double ExecTime; + public Exception Error; + public bool Canceled; + public bool Success; + public bool Done; + } + + internal class JobEntry : LoggingObject + { + public IVectoRun Run; + public JobContainer Container; + public double Progress; + public bool Done; + public bool Started; + public bool Success; + public bool Canceled; + public double ExecTime; + public Exception ExecException; + + public BackgroundWorker Worker; + + public void DoWork(object sender, DoWorkEventArgs e) + { + var stopWatch = new Stopwatch(); + stopWatch.Start(); + var worker = sender as BackgroundWorker; + try { + Run.Run(worker); + } catch (Exception ex) { + Log.Error(ex, "Error during simulation run!"); + ExecException = ex; + } + if (worker != null && worker.CancellationPending) { + e.Cancel = true; + Canceled = true; + } + stopWatch.Stop(); + Success = Run.FinishedWithoutErrors; + Done = true; + ExecTime = stopWatch.Elapsed.TotalMilliseconds; + Container.JobCompleted(this); + } + + public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {} + + public void ProgressChanged(object sender, ProgressChangedEventArgs e) + { + Progress = e.ProgressPercentage / 10000.0; + } + } + } } \ No newline at end of file diff --git a/VectoCoreTest/Utils/GraphWriter.cs b/VectoCoreTest/Utils/GraphWriter.cs index 4522ac47f39fdbeda5073b5ca75cb3d6b1ac79cb..4c62b9881a821257d457bbd8fe5f7b4050de78b4 100644 --- a/VectoCoreTest/Utils/GraphWriter.cs +++ b/VectoCoreTest/Utils/GraphWriter.cs @@ -18,248 +18,403 @@ 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); - - 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); - } + var grad = LoadData(modDataV3, ModalResultField.grad.GetName()); + + chartArea.AxisY2.Enabled = AxisEnabled.True; + chartArea.AxisY2.Title = "gradient [%]"; + chartArea.AxisY2.TitleFont = AxisTitleFont; + chartArea.AxisY2.LabelStyle.Font = AxisLabelFont; + chartArea.AxisY2.LabelAutoFitStyle = LabelAutoFitStyles.None; + chartArea.AxisY2.MinorGrid.Enabled = false; + chartArea.AxisY2.MajorGrid.Enabled = false; + var max = Math.Max(-Math.Round(grad.Min() * 2), Math.Round(grad.Max() * 2)); + //chartArea.AxisY2.si + //chartArea.AxisY2.Minimum = -max; + //chartArea.AxisY2.Maximum = max; + chartArea.AxisY2.RoundAxisValues(); + chartArea.AxisY2.Interval = Math.Round(max / 5); + + var seriesGrad = CreateSeries("Gradient", legend, chartArea, chart, Color.Coral, x, grad); + seriesGrad.YAxisType = AxisType.Secondary; + } + + 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()); + } + } - PositionChartArea(chartArea, titleHeight, i, yfields.Count()); + AddTitle(chart, Path.GetFileNameWithoutExtension(fileName), yfields[0].ToString()); - if (i > 0) { - AlignChart(chart, yfield.ToString(), yfields[0].ToString()); - } - } + 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 grad = LoadData(modDataV3, ModalResultField.grad.GetName()); + + chartArea.AxisY2.Enabled = AxisEnabled.True; + chartArea.AxisY2.Title = "gradient [%]"; + chartArea.AxisY2.TitleFont = AxisTitleFont; + chartArea.AxisY2.LabelStyle.Font = AxisLabelFont; + chartArea.AxisY2.LabelAutoFitStyle = LabelAutoFitStyles.None; + chartArea.AxisY2.MinorGrid.Enabled = false; + chartArea.AxisY2.MajorGrid.Enabled = false; + var max = Math.Max(-Math.Round(grad.Min() * 2), Math.Round(grad.Max() * 2)); + //chartArea.AxisY2.si + chartArea.AxisY2.Minimum = -max; + chartArea.AxisY2.Maximum = max; + chartArea.AxisY2.RoundAxisValues(); + + var seriesGrad = CreateSeries("Gradient", legend, chartArea, chart, Color.Coral, x, grad); + seriesGrad.YAxisType = AxisType.Secondary; + } + + + 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); - } - } - - 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); + } + 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 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