using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using HeuristicLab.Services.Optimization.Web.Models; using HeuristicLab.Services.Optimization.ControllerService.Model; using System.Web.UI.DataVisualization.Charting; using System.Drawing; using System.IO; using System.Text; using System.Diagnostics; namespace HeuristicLab.Services.Optimization.Web.Controllers { public class ChartController : Controller { // // GET: /Chart/GenerateChart/ public ActionResult GenerateChart(int index, string parameterName, string chartType) { var model = Session["jobDetails"] as JobDetailsModel; var parameter = (from result in model.Runs[index].Results where result.Value.Name == parameterName select result.Value).FirstOrDefault(); var chartTypeObj = (SeriesChartType) Enum.Parse(typeof(SeriesChartType), chartType); var matrix = parameter as DecimalMatrix; var chart = new Chart(); chart.Width = 1024; chart.Height = 768; chart.BackColor = Color.FromArgb(211, 223, 240); chart.BorderlineDashStyle = ChartDashStyle.Solid; chart.BackSecondaryColor = Color.White; chart.BackGradientStyle = GradientStyle.TopBottom; chart.BorderlineWidth = 1; chart.Palette = ChartColorPalette.BrightPastel; chart.BorderlineColor = Color.FromArgb(26, 59, 105); chart.RenderType = RenderType.BinaryStreaming; chart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss; chart.AntiAliasing = AntiAliasingStyles.All; chart.TextAntiAliasingQuality = TextAntiAliasingQuality.Normal; chart.Titles.Add(CreateTitle(parameterName)); chart.Legends.Add(CreateLegend()); CreateSeries(chart, matrix, chartTypeObj); using (var stream = new MemoryStream()) { string img = "Chart"; chart.SaveImage(stream, ChartImageFormat.Png); string encoded = Convert.ToBase64String(stream.ToArray()); var resultString = new StringBuilder(); string result = string.Format(img, encoded); string imageMap = chart.GetHtmlImageMap("ImageMap" + parameterName); resultString.Append(result); resultString.Append(imageMap); return Content(resultString.ToString()); } } private Title CreateTitle(string titleString) { Title title = new Title(); title.Text = titleString; title.ShadowColor = Color.FromArgb(32, 0, 0, 0); title.Font = new Font("Trebuchet MS", 14F, FontStyle.Bold); title.ShadowOffset = 3; title.ForeColor = Color.FromArgb(26, 59, 105); return title; } private Legend CreateLegend() { Legend legend = new Legend("Legend"); legend.ShadowColor = Color.FromArgb(32, 0, 0, 0); legend.Font = new Font("Trebuchet MS", 14F, FontStyle.Bold); legend.ShadowOffset = 3; legend.ForeColor = Color.FromArgb(26, 59, 105); return legend; } private KnownColor GetRandomColor(List ignore) { Random randomGen = new Random(); //KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor)); KnownColor[] names = { KnownColor.Blue, KnownColor.Red, KnownColor.Green, KnownColor.Yellow, KnownColor.Violet, KnownColor.Purple, KnownColor.Orange }; KnownColor randomColorName = KnownColor.Blue; do { randomColorName = names[randomGen.Next(names.Length)]; if (ignore.Count == names.Count()) // prevent deadlock break; } while (ignore.Contains(randomColorName)); return randomColorName; } public void CreateSeries(Chart chart, DecimalMatrix matrix, SeriesChartType chartType) { DataPoint point; var usedColors = new List(); for (int i = 0; i < matrix.Value.Length; i++ ) { Series seriesDetail = new Series(); seriesDetail.Name = matrix.RowNames[i]; seriesDetail.IsValueShownAsLabel = false; var kc = GetRandomColor(usedColors); usedColors.Add(kc); seriesDetail.Url = "#"; seriesDetail.Color = Color.FromKnownColor(kc); seriesDetail.ChartType = chartType; seriesDetail.BorderWidth = 2; seriesDetail.ChartArea = "Area"; for (int j = 0; j < matrix.Value[i].Length; j++) { point = new DataPoint(); point.XValue = j; point.YValues = new double[] { matrix.Value[i][j] }; //point.AxisLabel = j + ""; seriesDetail.Points.Add(point); } chart.Series.Add(seriesDetail); } chart.ChartAreas.Add(CreateChartArea("Area")); } private ChartArea CreateChartArea(string name) { ChartArea chartArea = new ChartArea(); chartArea.Name = name; chartArea.BackColor = Color.Transparent; chartArea.AxisX.IsLabelAutoFit = false; chartArea.AxisY.IsLabelAutoFit = false; chartArea.AxisX.LabelStyle.Font = new Font("Verdana,Arial,Helvetica,sans-serif", 8F, FontStyle.Regular); chartArea.AxisY.LabelStyle.Font = new Font("Verdana,Arial,Helvetica,sans-serif", 8F, FontStyle.Regular); chartArea.AxisY.LineColor = Color.FromArgb(64, 64, 64, 64); chartArea.AxisX.LineColor = Color.FromArgb(64, 64, 64, 64); chartArea.AxisY.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64); chartArea.AxisX.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64); //chartArea.AxisX.Interval = 1; return chartArea; } [HttpGet] public JsonResult GetMatrixContentForGraph(int run, int parameterOffset, bool showMarker) { try { var model = Session["jobDetails"] as JobDetailsModel; if (model != null) { var parameter = model.Runs[run].Results[parameterOffset].Value as DecimalMatrix; var plotableData = new PlotableData() { ShowMarker = showMarker }; for (var i = 0; i < parameter.Value.Length; i++) { plotableData.Series.Add(new SeriesEntry() { Label = parameter.RowNames[i], Values = parameter.Value[i] }); } return Json(plotableData, JsonRequestBehavior.AllowGet); } } catch (Exception e) { Trace.TraceError(e.Message); } Response.StatusCode = 400; Response.Status = "Session timed out or "; return Json("error", JsonRequestBehavior.AllowGet); } [HttpGet] public JsonResult GetDatatableContent(string datatable, string datarow) { try { var model = Session["jobDetails"] as JobDetailsModel; var plotableData = new PlotableData(); for (var i=0; i < model.Runs.Count; i++) { foreach (var result in model.Runs[i].Results) { if (result.Value.Name == datatable) { var matrix = result.Value as DecimalMatrix; var index = Array.IndexOf(matrix.RowNames, datarow); plotableData.Series.Add( new SeriesEntry() { Label = "" + (i + 1) + ". Run - " + datatable + " - " + datarow, Values = matrix.Value[index] } ); break; } } } return Json(plotableData, JsonRequestBehavior.AllowGet); } catch (Exception e) { Trace.TraceError(e.Message); } Response.StatusCode = 400; Response.Status = "Session timed out"; return Json("error", JsonRequestBehavior.AllowGet); } [HttpGet] public JsonResult GetDatatables() { try { var model = Session["jobDetails"] as JobDetailsModel; var dts = new DatatableContainer(); var datatables = new List(); foreach (var param in model.Runs[0].Results) { if (param.Value is DecimalMatrix) { datatables.Add(param.Value.Name); } } dts.Datatables = datatables.ToArray(); return Json(dts, JsonRequestBehavior.AllowGet); } catch (Exception e) { Trace.TraceError(e.Message); } Response.StatusCode = 400; Response.Status = "Session timed out or "; return Json("error", JsonRequestBehavior.AllowGet); } [HttpGet] public JsonResult GetRowNames(string datatable) { var model = Session["jobDetails"] as JobDetailsModel; try { foreach (var param in model.Runs[0].Results) { if (param.Value.Name == datatable) { var matrix = param.Value as DecimalMatrix; var rowNames = new RowNameContainer() { RowNames = new List(matrix.RowNames) }; return Json(rowNames, JsonRequestBehavior.AllowGet); } } } catch(Exception ex) { Trace.WriteLine(ex.Message); } Response.StatusCode = 400; Response.Status = "Session timed out"; return Json("error", JsonRequestBehavior.AllowGet); } } }