using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Analysis.FitnessLandscape.BoxChart; namespace HeuristicLab.Analysis.FitnessLandscape.BoxCharts { [StorableClass] public class DiscreteValueBoxChartElementGenerator : EmptyBoxChartElementGenerator { public ValueParameter ValueNameParameter { get { return (ValueParameter)Parameters["ValueName"]; } } public ValueParameter> LevelsParameter { get { return (ValueParameter>)Parameters["Levels"]; } } public ValueParameter> ColorsParameter { get { return (ValueParameter>)Parameters["Colors"]; } } public ValueParameter InvertParameter { get { return (ValueParameter)Parameters["Invert"]; } } protected string ValueName { get { return ValueNameParameter.Value.Value; } } protected List Levels { get { return LevelsParameter.Value.Select(v => v.Value).ToList(); } } protected List Colors { get { return ColorsParameter.Value.Select(v => v.Color).ToList(); } } protected bool Invert { get { return InvertParameter.Value.Value; } } #region Construction & Cloning [StorableConstructor] protected DiscreteValueBoxChartElementGenerator(bool deserializing) : base(deserializing) { } protected DiscreteValueBoxChartElementGenerator(DiscreteValueBoxChartElementGenerator original, Cloner cloner) : base(original, cloner) { RegisterEvents(); } public DiscreteValueBoxChartElementGenerator() { Parameters.Add(new ValueParameter("ValueName", "The name of the result of parameter ot be visualized.", new StringValue("Value"))); Parameters.Add(new ValueParameter>("Levels", "The names and order of the different possible values.", new ItemList { new StringValue("Very Low"), new StringValue("Low"), new StringValue("Average"), new StringValue("High"), new StringValue("Very High") })); Parameters.Add(new ValueParameter>("Colors", "The list of colors to assigned to the different levels", new ItemList { new ColorValue(Color.Blue), new ColorValue(Color.Green), new ColorValue(Color.White), new ColorValue(Color.Orange), new ColorValue(Color.Red) })); Parameters.Add(new ValueParameter("Invert", "Whether the color assignment should be inverted and highlighted.", new BoolValue(false))); RegisterEvents(); if (GetType() == typeof(DiscreteValueBoxChartElementGenerator)) UpdateName(); } public override IDeepCloneable Clone(Cloner cloner) { return new DiscreteValueBoxChartElementGenerator(this, cloner); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { if (!Parameters.ContainsKey("Levels")) Parameters.Add(new ValueParameter>("Levels", "The names and order of the different possible values.", new ItemList { new StringValue("Very Low"), new StringValue("Low"), new StringValue("Average"), new StringValue("High"), new StringValue("Very High") })); if (!Parameters.ContainsKey("Colors")) Parameters.Add(new ValueParameter>("Colors", "The list of colors to assigned to the different levels", new ItemList { new ColorValue(Color.Blue), new ColorValue(Color.Green), new ColorValue(Color.White), new ColorValue(Color.Orange), new ColorValue(Color.Red) })); if (!Parameters.ContainsKey("Invert")) Parameters.Add(new ValueParameter("Invert", "Whether the color assignment should be inverted and highlighted.", new BoolValue(false))); RegisterEvents(); } #endregion private void RegisterEvents() { ValueNameParameter.ToStringChanged += new EventHandler(Parameters_Changed); } private void Parameters_Changed(object sender, EventArgs eventArgs) { UpdateName(); } protected override string CalculateName() { return string.Format("{0} d {1}", base.CalculateName(), ValueName); } private string GetValue(IRun run) { IItem value; run.Results.TryGetValue(ValueName, out value); if (value != null) return value.ToString(); run.Parameters.TryGetValue(ValueName, out value); if (value != null) return value.ToString(); return ""; } private Color GetColor(string value) { var idx = Levels.IndexOf(value); if (Invert) idx = Colors.Count - 1 - idx; if (idx < 0 || idx >= Colors.Count) return Color.Black; return Colors[idx]; } public override void Draw(IRun run, Graphics g) { using (var b = new SolidBrush(GetColor(GetValue(run)))) g.FillRectangle(b, g.ClipBounds.Left, g.ClipBounds.Top, g.ClipBounds.Width, g.ClipBounds.Height); if (Invert) { using (var p = new Pen(SystemBrushes.ControlDarkDark, 3)) { g.DrawLines(p, new[] { new PointF(g.ClipBounds.Left+1, g.ClipBounds.Bottom-1), new PointF(g.ClipBounds.Left+1, g.ClipBounds.Top+1), new PointF(g.ClipBounds.Right-1, g.ClipBounds.Top+1)}); p.Color = SystemColors.ControlLightLight; g.DrawLines(p, new[] { new PointF(g.ClipBounds.Right-1, g.ClipBounds.Top+1), new PointF(g.ClipBounds.Right-1, g.ClipBounds.Bottom-1), new PointF(g.ClipBounds.Left+1, g.ClipBounds.Bottom-1) }); } } } } }