Free cookie consent management tool by TermsFeed Policy Generator

source: branches/FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape/BoxChart/BoxChartCreator.cs @ 13820

Last change on this file since 13820 was 11661, checked in by ascheibe, 10 years ago

#1696 adapted FLA to changes of #2247

File size: 7.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Drawing.Imaging;
5using System.IO;
6using System.IO.Compression;
7using System.Linq;
8using HeuristicLab.Collections;
9using HeuristicLab.Common;
10using HeuristicLab.Core;
11using HeuristicLab.Data;
12using HeuristicLab.Optimization;
13using HeuristicLab.Parameters;
14using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
15
16namespace HeuristicLab.Analysis.FitnessLandscape.BoxCharts {
17
18  [Item("Box Chart Creator", "Visualizes essential run information by creating an overview chart.")]
19  [StorableClass]
20  public class BoxChartCreator : ParameterizedNamedItem, IRunCollectionModifier {
21
22    public enum AppendModes { None, Horizontal, Vertical };
23
24    #region Parameters
25    public ValueParameter<StringValue> ChartNameParameter {
26      get { return (ValueParameter<StringValue>)Parameters["ChartName"]; }
27    }
28    public ValueParameter<CheckedItemList<IBoxChartElementGenerator>> ElementsParameter {
29      get { return (ValueParameter<CheckedItemList<IBoxChartElementGenerator>>)Parameters["Elements"]; }
30    }
31    public ValueParameter<IntValue> SizeParameter {
32      get { return (ValueParameter<IntValue>)Parameters["Size"]; }
33    }
34    public ValueParameter<IntValue> PaddingParameter {
35      get { return (ValueParameter<IntValue>)Parameters["Padding"]; }
36    }
37    public ValueParameter<StringValue> ZipFileNameParameter {
38      get { return (ValueParameter<StringValue>)Parameters["ZipFileName"]; }
39    }
40    public IConstrainedValueParameter<StringValue> AppendModeParameter {
41      get { return (IConstrainedValueParameter<StringValue>)Parameters["AppendMode"]; }
42    }
43    #endregion
44
45    #region Parameter Values
46    protected string ChartName { get { return ChartNameParameter.Value.Value; } }
47    protected string ZipFileName { get { return ZipFileNameParameter.Value.Value; } }
48    protected int Size { get { return SizeParameter.Value.Value; } }
49    protected int Padding { get { return PaddingParameter.Value.Value; } }
50    protected AppendModes AppendMode { get { return (AppendModes)Enum.Parse(typeof(AppendModes), AppendModeParameter.Value.Value); } }
51    protected List<IBoxChartElementGenerator> Generators {
52      get {
53        return ElementsParameter.Value.CheckedItems.Select(i => i.Value).ToList();
54      }
55    }
56    #endregion
57
58    #region Construction & Cloning
59    [StorableConstructor]
60    protected BoxChartCreator(bool deserializing) : base(deserializing) { }
61    protected BoxChartCreator(BoxChartCreator original, Cloner cloner)
62      : base(original, cloner) {
63      RegisterEvents();
64    }
65    public BoxChartCreator() {
66      Parameters.Add(new ValueParameter<StringValue>("ChartName", "The result name of the chart.", new StringValue("Chart")));
67      Parameters.Add(new ValueParameter<CheckedItemList<IBoxChartElementGenerator>>("Elements", "List of patient chart element generators.", new CheckedItemList<IBoxChartElementGenerator>()));
68      Parameters.Add(new ValueParameter<IntValue>("Size", "The size of one box in pixels.", new IntValue(50)));
69      Parameters.Add(new ValueParameter<IntValue>("Padding", "The padding inside the boxes", new IntValue(1)));
70      Parameters.Add(new ValueParameter<StringValue>("ZipFileName", "The name of the zip file that will contain all generated charts.", new StringValue("")));
71      Parameters.Add(new ConstrainedValueParameter<StringValue>("AppendMode", "Determines how coordinates of new elements are calculated.",
72        new ItemSet<StringValue>(Enum.GetNames(typeof(AppendModes)).Select(v => new StringValue(v)))));
73      AppendModeParameter.Value = AppendModeParameter.ValidValues.SingleOrDefault(v => v.Value == AppendModes.Horizontal.ToString());
74      RegisterEvents();
75    }
76    public override IDeepCloneable Clone(Cloner cloner) {
77      return new BoxChartCreator(this, cloner);
78    }
79    [StorableHook(HookType.AfterDeserialization)]
80    private void AfterDeserialization() {
81      if (!Parameters.ContainsKey("ZipFileName"))
82        Parameters.Add(new ValueParameter<StringValue>("ZipFileName", "The name of the zip file that will contain all generated charts.", new StringValue("")));
83      if (!Parameters.ContainsKey("AppendMode")) {
84        Parameters.Add(new ConstrainedValueParameter<StringValue>("AppendMode", "Determines how coordinates of new elements are calculated.",
85          new ItemSet<StringValue>(Enum.GetNames(typeof(AppendModes)).Select(v => new StringValue(v)))));
86        AppendModeParameter.Value = AppendModeParameter.ValidValues.SingleOrDefault(v => v.Value == AppendModes.Horizontal.ToString());
87      }
88      RegisterEvents();
89    }
90    #endregion
91
92    private void RegisterEvents() {
93      ElementsParameter.ValueChanged += ElementsParameter_ValueChanged;
94      ElementsParameter.Value.ItemsAdded += ElementsParameter_Value_ItemsAdded;
95    }
96
97    private void ElementsParameter_ValueChanged(object sender, EventArgs e) {
98      ElementsParameter.Value.ItemsAdded += ElementsParameter_Value_ItemsAdded;
99    }
100
101    private void ElementsParameter_Value_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IBoxChartElementGenerator>> e) {
102      if (sender != ElementsParameter.Value) {
103        var oldParameter = sender as ICheckedItemList<IBoxChartElementGenerator>;
104        if (oldParameter != null)
105          oldParameter.ItemsAdded -= ElementsParameter_Value_ItemsAdded;
106      } else {
107        var generators = Generators;
108        var newItems = e.Items.Select(kvp => kvp.Value).ToList();
109        switch (AppendMode) {
110          case AppendModes.Horizontal:
111            foreach (var generator in newItems) {
112              generator.Y = generators.Max(g => g.Y + g.RowSpan - 1);
113              generator.X = generators.Where(g => g.Y + g.RowSpan - 1 == generator.Y).Max(g => g.X + g.ColSpan);
114            }
115            break;
116          case AppendModes.Vertical:
117            foreach (var generator in newItems) {
118              generator.X = generators.Max(g => g.X + g.ColSpan - 1);
119              generator.Y = generators.Where(g => g.X + g.ColSpan - 1 == generator.X).Max(g => g.Y + g.RowSpan);
120            }
121            break;
122        }
123      }
124    }
125
126    #region IRunCollectionModifier Members
127
128    public void Modify(List<IRun> runs) {
129      var bitmaps = new Dictionary<string, Bitmap>();
130      var generators = Generators;
131      var maxX = generators.Max(g => g.X + g.ColSpan);
132      var maxY = generators.Max(g => g.Y + g.RowSpan);
133      for (int i = 0; i < runs.Count; i++) {
134        var run = runs[i];
135        var b = new Bitmap(maxX * Size, maxY * Size);
136        using (var g = Graphics.FromImage(b)) {
137          g.FillRectangle(SystemBrushes.Control, 0, 0, b.Width, b.Height);
138          foreach (var gen in generators) {
139            g.SetClip(new Rectangle(gen.X * Size + Padding, gen.Y * Size + Padding, gen.ColSpan * Size - 2 * Padding, gen.RowSpan * Size - 2 * Padding));
140            gen.Draw(run, g);
141            g.ResetClip();
142          }
143        }
144        run.Results[ChartName] = new BitmapItem(b);
145        bitmaps.Add(string.Format("{0}.png", run.Name), (Bitmap)b.Clone());
146      }
147      SaveAllBitmaps(bitmaps);
148    }
149
150    private void SaveAllBitmaps(Dictionary<string, Bitmap> bitmaps) {
151      if (ZipFileNameParameter.Value == null && string.IsNullOrEmpty(ZipFileName))
152        return;
153      var filename = ZipFileName;
154      if (!filename.ToLowerInvariant().EndsWith("zip"))
155        filename = string.Format("{0}.zip", filename);
156      using (var stream = File.Create(filename)) {
157        using (var zipArchive = new ZipArchive(stream, ZipArchiveMode.Create)) {
158          foreach (var bitmap in bitmaps) {
159            var entry = zipArchive.CreateEntry(bitmap.Key);
160            using (var s = entry.Open()) {
161              bitmap.Value.Save(s, ImageFormat.Png);
162            }
163          }
164        }
165      }
166    }
167    #endregion
168  }
169}
Note: See TracBrowser for help on using the repository browser.