using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Web.Mvc; using System.Web.UI.DataVisualization.Charting; using System.Web.UI.WebControls; using LeafWeb.Core.Charter; using LeafWeb.Core.Entities; using LeafWeb.Core.Parsers; using LeafWeb.Core.Utility; using LeafWeb.Web.Services; using LeafWeb.Web.ViewModels.Chart; using NLog; namespace LeafWeb.Web.Controllers { public class ChartController : ControllerBase { public ActionResult Index(int leafInputId) { var leafOutputFile = DataService.GetLeafOutput_ChartFile(leafInputId); if (leafOutputFile == null) throw new ArgumentOutOfRangeException(); // TODO: break try { var curveIds = GetCurveIds(leafOutputFile.FileContents.Contents); var viewModel = new ChartViewModel { AvailableCurveId = curveIds, LeafInputId = leafInputId, LeafInputIdentifier = leafOutputFile.LeafInput.Identifier }; return View(viewModel); } catch (ParseException parseException) { var logger = LogManager.GetCurrentClassLogger(); logger.Warn(parseException); return View("DataError", model: parseException.Message); } } public ActionResult ChartCurve(int leafInputId, string curveId) { var leafOutputFile = DataService.GetLeafOutput_ChartFile(leafInputId); if (leafOutputFile == null) throw new ArgumentOutOfRangeException(); // TODO: break var curveData = GetCurveData(leafOutputFile.FileContents.Contents, curveId); if (curveData == null) return new HttpStatusCodeResult(HttpStatusCode.NotFound); var charts = GetChartBitmaps(curveData).ToList(); var combinedChart = CombineBitmaps(charts); foreach (var chart in charts) chart.Dispose(); // cleanup using (var ms = new MemoryStream()) { combinedChart.Save(ms, ImageFormat.Png); ms.Seek(0, SeekOrigin.Begin); return File(ms.ToArray(), "image/png", curveId.FilterValidFilename() + ".png"); } } private CurveData GetCurveData(byte[] fileContents, string curveId) { try { LeafGasComparison[] leafGasComparisons; using (var parser = new LeafGasComparisonParser(fileContents)) leafGasComparisons = parser.Parse(curveId); return CurveDataConverter.Convert(leafGasComparisons).First(); } catch (Exception e) { LogManager.GetCurrentClassLogger().Warn(e); } return null; } private string[] GetCurveIds(byte[] fileContents) { using (var parser = new LeafGasComparisonParser(fileContents)) return parser.ExtractCurveIds(); } private IEnumerable GetChartBitmaps(CurveData curveData) { var charts = LeafGasCharter.ProduceCharts(curveData); foreach (var chart in charts) { // http://stackoverflow.com/a/336396/99492 var ms = new MemoryStream(); // this gets attached to the bmp, dispose of it later chart.SaveImage(ms, ChartImageFormat.Bmp); ms.Seek(0, SeekOrigin.Begin); yield return new Bitmap(ms); } } private Bitmap CombineBitmaps(IList bitmaps, int columnCount = 2) { if (!bitmaps.Any()) return null; // bitmaps assumed to have same dimensions, use the first one to define that var cellWidth = bitmaps[0].Width; var cellHeight = bitmaps[0].Height; var width = cellWidth * columnCount; var height = cellHeight * bitmaps.Count / columnCount; var combinedBitmap = new Bitmap(width, height); using (var g = Graphics.FromImage(combinedBitmap)) { var currentCol = 0; var currentRow = 0; foreach (var image in bitmaps) { g.DrawImage(image, currentCol * cellWidth, currentRow * cellHeight); currentCol = (currentCol + 1)%columnCount; currentRow += currentCol == 0 ? 1 : 0; } } return combinedBitmap; } public ActionResult ChartSample() { var chart = new Chart { BackColor = Color.FromArgb(255, 255, 255), Width = Unit.Pixel(250), Height = Unit.Pixel(2500) }; var series = new Series { ChartArea = "ca1", ChartType = SeriesChartType.Line }; //series.Font = new Font("Verdana", 8.25f, FontStyle.Regular); var myRandom = new Random(); for (int i = 0; i < 100; i++) { var dp = new DataPoint(); dp.AxisLabel = String.Format("{0}-{1}", i, Guid.NewGuid().ToString().Substring(0, 4)); dp.YValues = new double[] { myRandom.Next(5, 100) }; series.Points.Add(dp); } chart.Series.Add(series); var area = new ChartArea("ca1"); area.Area3DStyle.Enable3D = false; area.AxisX.Interval = 1; //area.BackColor = Color.Transparent; //var labelStyle = new LabelStyle(); //labelStyle.Enabled = true; //labelStyle.Font = new Font("Arial", 3f); area.AxisX.LabelStyle.Font = new Font("Verdana", 8.25f, FontStyle.Underline);//Why does it recognize the style but not the font!!!??? chart.ChartAreas.Add(area); using (var ms = new MemoryStream()) { chart.SaveImage(ms, ChartImageFormat.Png); ms.Seek(0, SeekOrigin.Begin); return File(ms.ToArray(), "image/png", "mychart.png"); } } } }