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.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);
}
}
}