Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/DataBarSetView.cs

Last change on this file was 17980, checked in by jzenisek, 3 years ago

#2719 merged head of HeuristicLab.Problems.DataAnalysis into branch; added several minor items

File size: 12.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using System.Linq;
25using System.Windows.Forms;
26using System.Windows.Forms.DataVisualization.Charting;
27using HeuristicLab.Core.Views;
28using HeuristicLab.MainForm;
29
30namespace HeuristicLab.DatastreamAnalysis.Views {
31  [View("DataBarSet")]
32  [Content(typeof(DataBarSet), true)]
33  public partial class DataBarSetView : ItemView {
34    private bool updateInProgress;
35    private string seriesName = "Ensembles";
36
37    public virtual Image ViewImage {
38      get { return HeuristicLab.Common.Resources.VSImageLibrary.Graph; }
39    }
40
41    public new DataBarSet Content {
42      get { return (DataBarSet) base.Content; }
43      set { base.Content = value; }
44    }
45
46    public DataBarSetView() : base() {
47      InitializeComponent();
48      updateInProgress = false;
49
50      this.chart.CustomizeAllChartAreas();
51      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
52      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
53      this.chart.ChartAreas[0].AxisX.Title = "Ensembles";
54      //this.chart.ChartAreas[0].AxisX.Maximum = 0.0;
55      //this.chart.ChartAreas[0].AxisX.Maximum = (Content != null && Content.Bars != null) ? Content.Bars.Count : 0.0;
56      //AddCustomLabelsToAxis(this.chart.ChartAreas[0].AxisX);
57
58      this.chart.ChartAreas[0].AxisY.Title = "Estimation Quality";
59      this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
60      this.chart.ChartAreas[0].AxisY.Minimum = 0.0;
61      this.chart.ChartAreas[0].AxisY.Maximum = 1.0;
62      this.chart.ChartAreas[0].AxisY.Interval = 0.1;
63      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
64      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
65    }
66
67    private void AddCustomLabelsToAxis(Axis axis) {
68      axis.CustomLabels.Clear();
69
70      var bars = Content.Bars.ToList();
71      for(int i = 0; i < Content.Bars.Count; i++) {
72        CustomLabel barLabel = new CustomLabel();
73        barLabel.Text = bars[i].Name;
74        barLabel.FromPosition = i;
75        barLabel.ToPosition = i + 1;
76        axis.CustomLabels.Add(barLabel);
77      }
78    }
79
80    protected override void RegisterContentEvents() {
81      base.RegisterContentEvents();
82      Content.BarsPropertyChanged += new EventHandler(Content_BarsChanged);
83      Content.BarValueChanged += new EventHandler(Content_BarValuesChanged);
84      Content.ThresholdsPropertyChanged += new EventHandler(Content_ThresholdsChanged);
85    }
86
87    protected override void DeregisterContentEvents() {
88      base.DeregisterContentEvents();
89      Content.BarsPropertyChanged -= new EventHandler(Content_BarsChanged);
90      Content.BarValueChanged -= new EventHandler(Content_BarValuesChanged);
91      Content.ThresholdsPropertyChanged -= new EventHandler(Content_ThresholdsChanged);
92    }
93
94    private void Content_BarsChanged(object sender, EventArgs e) {
95      UpdateChart();
96    }
97
98    private void Content_BarValuesChanged(object sender, EventArgs e) {
99      UpdateChartValues();
100    }
101
102    private void Content_ThresholdsChanged(object sender, EventArgs e) {
103      UpdateChart();
104    }
105
106    protected override void OnContentChanged() {
107      base.OnContentChanged();
108      UpdateChart();
109    }
110    private void UpdateChart() {
111      if (InvokeRequired) {
112        Invoke((Action) UpdateChart);
113      } else if(!updateInProgress) {
114        if (Content == null) return;
115
116        updateInProgress = true;
117
118        chart.Series.Clear();
119       
120        Series series = chart.Series.Add(seriesName);
121        series.IsVisibleInLegend = false;
122        series.ChartType = SeriesChartType.Column;
123        int i = 0;
124        foreach (var bar in Content.Bars) {
125          var dp = new DataPoint(i, bar.Value) {
126            AxisLabel = bar.Name,
127            ToolTip = bar.Name,
128            Color = bar.BarColor,
129            BorderWidth = 5
130          };
131          series.Points.Add(dp);
132          i++;
133        }
134
135        //chart.ChartAreas[0].RecalculateAxesScale();
136        AddThresholds();
137        CheckThresholds();
138
139        chart.Refresh();
140        updateInProgress = false;
141      }
142    }
143
144    private void UpdateChartValues() {
145      if (InvokeRequired) {
146        Invoke((Action) UpdateChartValues);
147      } else if(!updateInProgress) {
148        if (Content == null) return;
149
150        updateInProgress = true;
151
152        //chart.Series[seriesName].Points.Clear();
153        //foreach (var bar in Content.Bars) {
154        //  chart.Series[seriesName].Points.AddXY(bar.Name, bar.Value);
155        //}
156
157        var bars = Content.Bars.ToList();
158
159        for (int i = 0; i < bars.Count; i++) {
160          chart.Series[seriesName].Points.ElementAt(i).SetValueY(bars[i].Value);
161          chart.Series[seriesName].Points.ElementAt(i).ToolTip = bars[i].Name + " = " + bars[i].Value;
162        }
163
164        CheckThresholds();
165        //chart.ChartAreas[0].RecalculateAxesScale();
166        chart.Refresh();
167        updateInProgress = false;
168      }
169    }
170
171    public static Color DefaultColor = Color.FromArgb(65, 140, 240);
172    public static Color HighlightColor1 = Color.FromArgb(37, 105, 175);
173    public static Color HighlightColor2 = Color.FromArgb(247, 150, 70);
174    public static Color HighlightColor3 = Color.FromArgb(228, 108, 10);
175    //public static Color HighlightColor1 = Color.FromArgb(45, 120, 200);
176    //public static Color HighlightColor2 = Color.FromArgb(15, 90, 160);
177    //public static Color HighlightColor3 = Color.FromArgb(10, 60, 110);
178    private void CheckThresholds() {
179      var bars = Content.Bars.ToList();
180      var winner =
181        !bars.Any() ? -1 :
182        bars
183        .Select((value, index) => new {Value = value, Index = index})
184        .Aggregate((a, b) => ((a.Value.Value - a.Value.ThresholdUpperBound) > (b.Value.Value - b.Value.ThresholdUpperBound)) ? a : b)
185        .Index;
186
187      // color bars depending on the threshold boundaries they exceed
188      for (int i = 0; i < bars.Count; i++) {
189        var bar = bars[i];
190        if (bar.Value > bar.ThresholdUpperBound) {
191          chart.Series[seriesName].Points[i].Color = HighlightColor2;
192          chart.Series[seriesName].Points[i].BorderColor = HighlightColor2;
193        } else if (bar.Value > bar.ThresholdLowerBound) {
194          chart.Series[seriesName].Points[i].Color = HighlightColor1;
195          chart.Series[seriesName].Points[i].BorderColor = HighlightColor1;
196        } else {
197          chart.Series[seriesName].Points[i].Color = bar.BarColor;
198          chart.Series[seriesName].Points[i].BorderColor = bar.BarColor;
199        }
200      }
201
202      // color the winner's border
203      if (winner != -1 && bars[winner].Value > bars[winner].ThresholdUpperBound) {
204        chart.Series[seriesName].Points[winner].BorderColor = HighlightColor3;
205      }
206    }
207
208
209
210    private void AddThresholds() {
211      Series series = chart.Series.Add("Thresholds");
212      series.IsVisibleInLegend = false;
213      series.ChartType = SeriesChartType.ErrorBar;
214
215      int i = 0;
216      foreach (var bar in Content.Bars) {
217        string desc = string.Format("{0} - Threshold [{1},{2}]", bar.Name, bar.ThresholdLowerBound,bar.ThresholdUpperBound);
218        var threshold = new DataPoint(i, new[]
219              {(bar.ThresholdLowerBound + bar.ThresholdUpperBound)/2, bar.ThresholdLowerBound, bar.ThresholdUpperBound}) {
220                AxisLabel = desc,
221                ToolTip = desc,
222                Color = bar.ThresholdColor,
223                BorderWidth = 1
224        };
225        series.Points.Add(threshold);
226        i++;
227      }
228    }
229    private void AddThresholdsOld() {
230      Series series = chart.Series.Add("Thresholds");
231      series.IsVisibleInLegend = false;
232      series.ChartType = SeriesChartType.StackedColumn;
233
234      int i = 0;
235      foreach (var bar in Content.Bars) {
236        //series.Points.Add(new DataPoint(i, new [] { bar.Threshold, bar.Threshold + 0.05 }) { AxisLabel = bar.Name, Color = Color.Transparent, BorderWidth = 2, BorderColor = bar.ThresholdColor});
237        series.Points.Add(new DataPoint(i, new[] { bar.ThresholdLowerBound, bar.ThresholdUpperBound }) { AxisLabel = bar.Name, Color = bar.ThresholdColor });
238        i++;
239      }
240    }
241    private void AddThresholdsOld2() {
242      chart.Annotations.Clear();
243
244      var bars = Content.Bars.ToList();
245      for (int i = 0; i < bars.Count; i++) {
246        HorizontalLineAnnotation annotation = new HorizontalLineAnnotation();
247        annotation.AllowMoving = false;
248        annotation.AllowResizing = false;
249        annotation.LineWidth = 2;
250        annotation.LineColor = bars[i].ThresholdColor;
251        annotation.IsInfinitive = false;
252        annotation.ClipToChartArea = chart.ChartAreas[0].Name;
253        annotation.AxisX = chart.ChartAreas[0].AxisX;
254        annotation.AxisY = chart.ChartAreas[0].AxisY;
255        annotation.Y = bars[i].ThresholdLowerBound;
256
257        annotation.Alignment = ContentAlignment.MiddleCenter;
258        annotation.AnchorX = i;
259
260        annotation.X = i - 0.4;
261        annotation.Width = (46 - bars.Count) / bars.Count;
262        annotation.Name = bars[i].Name;
263        annotation.Tag = bars[i].Name;
264        annotation.BringToFront();
265
266       
267
268        chart.Annotations.Add(annotation);
269      }
270    }
271
272    private TextAnnotation CreateTextAnnotation(string name, int classIndex, Axis axisX, Axis axisY, double x, double y, ContentAlignment alignment) {
273      TextAnnotation annotation = new TextAnnotation();
274      annotation.Text = name;
275      annotation.AllowMoving = true;
276      annotation.AllowResizing = false;
277      annotation.AllowSelecting = false;
278      annotation.IsSizeAlwaysRelative = true;
279      annotation.ClipToChartArea = chart.ChartAreas[0].Name;
280      annotation.Tag = classIndex;
281      annotation.AxisX = axisX;
282      annotation.AxisY = axisY;
283      annotation.Alignment = alignment;
284      annotation.X = x;
285      annotation.Y = y;
286      return annotation;
287    }
288
289
290    #region user interaction events
291    private void chart_MouseMove(object sender, MouseEventArgs e) {
292      HitTestResult result = chart.HitTest(e.X, e.Y);
293      if (result.ChartElementType == ChartElementType.LegendItem)
294        this.Cursor = Cursors.Hand;
295      else
296        this.Cursor = Cursors.Default;
297    }
298
299    private void chart_MouseDown(object sender, MouseEventArgs e) {
300      HitTestResult result = chart.HitTest(e.X, e.Y);
301      if (result.ChartElementType == ChartElementType.LegendItem) {
302        if (result.Series != null) ToggleSeries(result.Series);
303      }
304    }
305
306    private void ToggleSeries(Series series) {
307      if (series.Points.Count == 0) {
308        // TODO
309      } else {
310        series.Points.Clear();
311      }
312    }
313
314    private void chart_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e) {
315      int classIndex = (int)e.Annotation.Tag;
316      //double[] thresholds = Content.Model.Thresholds.ToArray();
317      //thresholds[classIndex] = e.NewLocationY;
318      //Array.Sort(thresholds);
319      //Content.Model.SetThresholdsAndClassValues(thresholds, Content.Model.ClassValues);
320    }
321
322    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
323      foreach (LegendItem legendItem in e.LegendItems) {
324        var series = chart.Series[legendItem.SeriesName];
325        if (series != null) {
326          bool seriesIsInvisible = series.Points.Count == 0;
327          foreach (LegendCell cell in legendItem.Cells)
328            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
329        }
330      }
331    }
332    #endregion
333  }
334}
Note: See TracBrowser for help on using the repository browser.