Changeset 14101


Ignore:
Timestamp:
07/18/16 16:54:16 (9 months ago)
Author:
abeham
Message:

#2634: Fixed some remaining bugs in runcollection rld view regarding runs with unequal length

Location:
branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs

    r12888 r14101  
    4545    private void InitializeComponent() {
    4646      this.components = new System.ComponentModel.Container();
     47      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
     48      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
    4749      this.dataTableComboBox = new System.Windows.Forms.ComboBox();
    4850      this.dataTableLabel = new System.Windows.Forms.Label();
     
    5961      this.budgetsTextBox = new System.Windows.Forms.TextBox();
    6062      this.addBudgetsAsResultButton = new System.Windows.Forms.Button();
    61       this.eachOrAllTargetCheckBox = new System.Windows.Forms.CheckBox();
     63      this.aggregateTargetsCheckBox = new System.Windows.Forms.CheckBox();
    6264      this.tabControl = new System.Windows.Forms.TabControl();
    6365      this.byTargetTabPage = new System.Windows.Forms.TabPage();
    64       this.byTargetViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
     66      this.targetChart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
     67      this.boundShadingCheckBox = new System.Windows.Forms.CheckBox();
    6568      this.byCostTabPage = new System.Windows.Forms.TabPage();
     69      this.byCostViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
    6670      this.budgetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
    6771      this.eachOrAllBudgetsCheckBox = new System.Windows.Forms.CheckBox();
    6872      this.generateBudgetsButton = new System.Windows.Forms.Button();
    69       this.byCostViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
    7073      this.byTableTabPage = new System.Windows.Forms.TabPage();
     74      this.ertTableView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
    7175      this.problemComboBox = new System.Windows.Forms.ComboBox();
    7276      this.problemLabel = new System.Windows.Forms.Label();
    73       this.ertTableView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
    7477      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
    7578      this.tabControl.SuspendLayout();
    7679      this.byTargetTabPage.SuspendLayout();
     80      ((System.ComponentModel.ISupportInitialize)(this.targetChart)).BeginInit();
    7781      this.byCostTabPage.SuspendLayout();
    7882      this.byTableTabPage.SuspendLayout();
     
    139143      this.targetsTextBox.Location = new System.Drawing.Point(59, 8);
    140144      this.targetsTextBox.Name = "targetsTextBox";
    141       this.targetsTextBox.Size = new System.Drawing.Size(326, 20);
     145      this.targetsTextBox.Size = new System.Drawing.Size(287, 20);
    142146      this.targetsTextBox.TabIndex = 1;
    143147      this.toolTip.SetToolTip(this.targetsTextBox, "The order of the targets is important, first to-hit targets\r\nshould be given firs" +
     
    211215      this.addBudgetsAsResultButton.Click += new System.EventHandler(this.addBudgetsAsResultButton_Click);
    212216      //
    213       // eachOrAllTargetCheckBox
    214       //
    215       this.eachOrAllTargetCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
    216       this.eachOrAllTargetCheckBox.AutoSize = true;
    217       this.eachOrAllTargetCheckBox.Location = new System.Drawing.Point(414, 10);
    218       this.eachOrAllTargetCheckBox.Name = "eachOrAllTargetCheckBox";
    219       this.eachOrAllTargetCheckBox.Size = new System.Drawing.Size(36, 17);
    220       this.eachOrAllTargetCheckBox.TabIndex = 2;
    221       this.eachOrAllTargetCheckBox.Text = "all";
    222       this.eachOrAllTargetCheckBox.UseVisualStyleBackColor = true;
    223       this.eachOrAllTargetCheckBox.CheckedChanged += new System.EventHandler(this.eachOrAllTargetCheckBox_CheckedChanged);
     217      // aggregateTargetsCheckBox
     218      //
     219      this.aggregateTargetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
     220      this.aggregateTargetsCheckBox.AutoSize = true;
     221      this.aggregateTargetsCheckBox.Checked = true;
     222      this.aggregateTargetsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
     223      this.aggregateTargetsCheckBox.Location = new System.Drawing.Point(352, 10);
     224      this.aggregateTargetsCheckBox.Name = "aggregateTargetsCheckBox";
     225      this.aggregateTargetsCheckBox.Size = new System.Drawing.Size(74, 17);
     226      this.aggregateTargetsCheckBox.TabIndex = 2;
     227      this.aggregateTargetsCheckBox.Text = "aggregate";
     228      this.aggregateTargetsCheckBox.UseVisualStyleBackColor = true;
     229      this.aggregateTargetsCheckBox.CheckedChanged += new System.EventHandler(this.aggregateTargetsCheckBox_CheckedChanged);
    224230      //
    225231      // tabControl
     
    239245      // byTargetTabPage
    240246      //
    241       this.byTargetTabPage.Controls.Add(this.byTargetViewHost);
     247      this.byTargetTabPage.Controls.Add(this.targetChart);
     248      this.byTargetTabPage.Controls.Add(this.boundShadingCheckBox);
    242249      this.byTargetTabPage.Controls.Add(this.targetLogScalingCheckBox);
    243250      this.byTargetTabPage.Controls.Add(this.targetsLabel);
    244       this.byTargetTabPage.Controls.Add(this.eachOrAllTargetCheckBox);
     251      this.byTargetTabPage.Controls.Add(this.aggregateTargetsCheckBox);
    245252      this.byTargetTabPage.Controls.Add(this.targetsTextBox);
    246253      this.byTargetTabPage.Controls.Add(this.generateTargetsButton);
     
    254261      this.byTargetTabPage.UseVisualStyleBackColor = true;
    255262      //
    256       // byTargetViewHost
    257       //
    258       this.byTargetViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
     263      // targetChart
     264      //
     265      this.targetChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    259266            | System.Windows.Forms.AnchorStyles.Left)
    260267            | System.Windows.Forms.AnchorStyles.Right)));
    261       this.byTargetViewHost.Caption = "View";
    262       this.byTargetViewHost.Content = null;
    263       this.byTargetViewHost.Enabled = false;
    264       this.byTargetViewHost.Location = new System.Drawing.Point(3, 34);
    265       this.byTargetViewHost.Name = "byTargetViewHost";
    266       this.byTargetViewHost.ReadOnly = false;
    267       this.byTargetViewHost.Size = new System.Drawing.Size(640, 324);
    268       this.byTargetViewHost.TabIndex = 5;
    269       this.byTargetViewHost.ViewsLabelVisible = true;
    270       this.byTargetViewHost.ViewType = null;
     268      chartArea1.AxisX.IsStartedFromZero = false;
     269      chartArea1.AxisX.MinorGrid.Enabled = true;
     270      chartArea1.AxisX.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
     271      chartArea1.AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
     272      chartArea1.AxisY.Maximum = 1D;
     273      chartArea1.AxisY.Minimum = 0D;
     274      chartArea1.AxisY.MinorGrid.Enabled = true;
     275      chartArea1.AxisY.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
     276      chartArea1.AxisY.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
     277      chartArea1.Name = "ChartArea1";
     278      this.targetChart.ChartAreas.Add(chartArea1);
     279      legend1.Alignment = System.Drawing.StringAlignment.Center;
     280      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
     281      legend1.Name = "Legend1";
     282      this.targetChart.Legends.Add(legend1);
     283      this.targetChart.Location = new System.Drawing.Point(6, 34);
     284      this.targetChart.Name = "targetChart";
     285      this.targetChart.Size = new System.Drawing.Size(634, 324);
     286      this.targetChart.SuppressExceptions = true;
     287      this.targetChart.TabIndex = 7;
     288      this.targetChart.Text = "enhancedChart1";
     289      this.targetChart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
     290      this.targetChart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
     291      this.targetChart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
     292      //
     293      // boundShadingCheckBox
     294      //
     295      this.boundShadingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     296      this.boundShadingCheckBox.AutoSize = true;
     297      this.boundShadingCheckBox.Checked = true;
     298      this.boundShadingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
     299      this.boundShadingCheckBox.Location = new System.Drawing.Point(127, 364);
     300      this.boundShadingCheckBox.Name = "boundShadingCheckBox";
     301      this.boundShadingCheckBox.Size = new System.Drawing.Size(96, 17);
     302      this.boundShadingCheckBox.TabIndex = 6;
     303      this.boundShadingCheckBox.Text = "bound shading";
     304      this.boundShadingCheckBox.UseVisualStyleBackColor = true;
     305      this.boundShadingCheckBox.CheckedChanged += new System.EventHandler(this.boundShadingCheckBox_CheckedChanged);
    271306      //
    272307      // byCostTabPage
    273308      //
     309      this.byCostTabPage.Controls.Add(this.byCostViewHost);
    274310      this.byCostTabPage.Controls.Add(this.budgetLogScalingCheckBox);
    275311      this.byCostTabPage.Controls.Add(this.eachOrAllBudgetsCheckBox);
    276312      this.byCostTabPage.Controls.Add(this.generateBudgetsButton);
    277       this.byCostTabPage.Controls.Add(this.byCostViewHost);
    278313      this.byCostTabPage.Controls.Add(this.budgetsLabel);
    279314      this.byCostTabPage.Controls.Add(this.addBudgetsAsResultButton);
     
    287322      this.byCostTabPage.UseVisualStyleBackColor = true;
    288323      //
     324      // byCostViewHost
     325      //
     326      this.byCostViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
     327            | System.Windows.Forms.AnchorStyles.Left)
     328            | System.Windows.Forms.AnchorStyles.Right)));
     329      this.byCostViewHost.Caption = "View";
     330      this.byCostViewHost.Content = null;
     331      this.byCostViewHost.Enabled = false;
     332      this.byCostViewHost.Location = new System.Drawing.Point(6, 34);
     333      this.byCostViewHost.Name = "byCostViewHost";
     334      this.byCostViewHost.ReadOnly = false;
     335      this.byCostViewHost.Size = new System.Drawing.Size(634, 324);
     336      this.byCostViewHost.TabIndex = 12;
     337      this.byCostViewHost.ViewsLabelVisible = true;
     338      this.byCostViewHost.ViewType = null;
     339      //
    289340      // budgetLogScalingCheckBox
    290341      //
     
    322373      this.generateBudgetsButton.Click += new System.EventHandler(this.generateBudgetsButton_Click);
    323374      //
    324       // byCostViewHost
    325       //
    326       this.byCostViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    327             | System.Windows.Forms.AnchorStyles.Left)
    328             | System.Windows.Forms.AnchorStyles.Right)));
    329       this.byCostViewHost.Caption = "View";
    330       this.byCostViewHost.Content = null;
    331       this.byCostViewHost.Enabled = false;
    332       this.byCostViewHost.Location = new System.Drawing.Point(3, 34);
    333       this.byCostViewHost.Name = "byCostViewHost";
    334       this.byCostViewHost.ReadOnly = false;
    335       this.byCostViewHost.Size = new System.Drawing.Size(640, 324);
    336       this.byCostViewHost.TabIndex = 8;
    337       this.byCostViewHost.ViewsLabelVisible = true;
    338       this.byCostViewHost.ViewType = null;
    339       //
    340375      // byTableTabPage
    341376      //
     
    348383      this.byTableTabPage.Text = "Expected Runtime Tables";
    349384      this.byTableTabPage.UseVisualStyleBackColor = true;
    350       //
    351       // problemComboBox
    352       //
    353       this.problemComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
    354             | System.Windows.Forms.AnchorStyles.Right)));
    355       this.problemComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
    356       this.problemComboBox.FormattingEnabled = true;
    357       this.problemComboBox.Location = new System.Drawing.Point(69, 30);
    358       this.problemComboBox.Name = "problemComboBox";
    359       this.problemComboBox.Size = new System.Drawing.Size(582, 21);
    360       this.problemComboBox.TabIndex = 3;
    361       this.problemComboBox.SelectedIndexChanged += new System.EventHandler(this.problemComboBox_SelectedIndexChanged);
    362       //
    363       // problemLabel
    364       //
    365       this.problemLabel.AutoSize = true;
    366       this.problemLabel.Location = new System.Drawing.Point(3, 33);
    367       this.problemLabel.Name = "problemLabel";
    368       this.problemLabel.Size = new System.Drawing.Size(48, 13);
    369       this.problemLabel.TabIndex = 2;
    370       this.problemLabel.Text = "Problem:";
    371385      //
    372386      // ertTableView
     
    382396      this.ertTableView.Size = new System.Drawing.Size(640, 381);
    383397      this.ertTableView.TabIndex = 0;
     398      //
     399      // problemComboBox
     400      //
     401      this.problemComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
     402            | System.Windows.Forms.AnchorStyles.Right)));
     403      this.problemComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
     404      this.problemComboBox.FormattingEnabled = true;
     405      this.problemComboBox.Location = new System.Drawing.Point(69, 30);
     406      this.problemComboBox.Name = "problemComboBox";
     407      this.problemComboBox.Size = new System.Drawing.Size(582, 21);
     408      this.problemComboBox.TabIndex = 3;
     409      this.problemComboBox.SelectedIndexChanged += new System.EventHandler(this.problemComboBox_SelectedIndexChanged);
     410      //
     411      // problemLabel
     412      //
     413      this.problemLabel.AutoSize = true;
     414      this.problemLabel.Location = new System.Drawing.Point(3, 33);
     415      this.problemLabel.Name = "problemLabel";
     416      this.problemLabel.Size = new System.Drawing.Size(48, 13);
     417      this.problemLabel.TabIndex = 2;
     418      this.problemLabel.Text = "Problem:";
    384419      //
    385420      // RunCollectionRLDView
     
    399434      this.byTargetTabPage.ResumeLayout(false);
    400435      this.byTargetTabPage.PerformLayout();
     436      ((System.ComponentModel.ISupportInitialize)(this.targetChart)).EndInit();
    401437      this.byCostTabPage.ResumeLayout(false);
    402438      this.byCostTabPage.PerformLayout();
     
    423459    private System.Windows.Forms.TextBox budgetsTextBox;
    424460    private System.Windows.Forms.Label budgetsLabel;
    425     private System.Windows.Forms.CheckBox eachOrAllTargetCheckBox;
     461    private System.Windows.Forms.CheckBox aggregateTargetsCheckBox;
    426462    private System.Windows.Forms.TabControl tabControl;
    427463    private System.Windows.Forms.TabPage byTargetTabPage;
    428     private MainForm.WindowsForms.ViewHost byTargetViewHost;
    429464    private System.Windows.Forms.TabPage byCostTabPage;
    430465    private System.Windows.Forms.TabPage byTableTabPage;
    431     private MainForm.WindowsForms.ViewHost byCostViewHost;
    432466    private System.Windows.Forms.CheckBox eachOrAllBudgetsCheckBox;
    433467    private System.Windows.Forms.Button generateBudgetsButton;
     
    436470    private System.Windows.Forms.ComboBox problemComboBox;
    437471    private Data.Views.StringConvertibleMatrixView ertTableView;
     472    private Visualization.ChartControlsExtensions.EnhancedChart targetChart;
     473    private MainForm.WindowsForms.ViewHost byCostViewHost;
     474    private System.Windows.Forms.CheckBox boundShadingCheckBox;
    438475  }
    439476}
  • branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs

    r14035 r14101  
    2020#endregion
    2121
    22 using HeuristicLab.Analysis;
    23 using HeuristicLab.Collections;
    24 using HeuristicLab.Core.Views;
    25 using HeuristicLab.Data;
    26 using HeuristicLab.MainForm;
    27 using HeuristicLab.MainForm.WindowsForms;
    2822using System;
    2923using System.Collections.Generic;
     
    3327using System.Linq;
    3428using System.Windows.Forms;
     29using System.Windows.Forms.DataVisualization.Charting;
     30using HeuristicLab.Analysis;
     31using HeuristicLab.Collections;
     32using HeuristicLab.Core.Views;
     33using HeuristicLab.Data;
     34using HeuristicLab.MainForm;
     35using HeuristicLab.MainForm.WindowsForms;
    3536
    3637namespace HeuristicLab.Optimization.Views {
     
    3839  [Content(typeof(RunCollection), false)]
    3940  public partial class RunCollectionRLDView : ItemView {
     41    private List<Series> invisibleTargetSeries;
     42
    4043    private const string AllRuns = "All Runs";
    4144
     
    5659      Color.FromArgb(0x63, 0xC2, 0x16),
    5760    };
    58     private static readonly DataRowVisualProperties.DataRowLineStyle[] lineStyles = new[] {
     61    private static readonly ChartDashStyle[] lineStyles = new[] {
     62      ChartDashStyle.Solid,
     63      ChartDashStyle.Dash,
     64      ChartDashStyle.DashDot,
     65      ChartDashStyle.Dot
     66    };
     67    private static readonly DataRowVisualProperties.DataRowLineStyle[] hlLineStyles = new[] {
    5968      DataRowVisualProperties.DataRowLineStyle.Solid,
    6069      DataRowVisualProperties.DataRowLineStyle.Dash,
     
    7281
    7382    private bool suppressUpdates;
    74     private readonly IndexedDataTable<double> byTargetDataTable;
    75     public IndexedDataTable<double> ByTargetDataTable {
    76       get { return byTargetDataTable; }
    77     }
    7883    private readonly IndexedDataTable<double> byCostDataTable;
    7984    public IndexedDataTable<double> ByCostDataTable {
     
    8388    public RunCollectionRLDView() {
    8489      InitializeComponent();
    85       byTargetDataTable = new IndexedDataTable<double>("ECDF by Target", "A data table containing the ECDF of each of a number of groups.") {
    86         VisualProperties = {
    87           YAxisTitle = "Proportion of reached targets",
    88           YAxisMinimumFixedValue = 0,
    89           YAxisMinimumAuto = false,
    90           YAxisMaximumFixedValue = 1,
    91           YAxisMaximumAuto = false
    92         }
    93       };
    94       byTargetViewHost.Content = byTargetDataTable;
     90      invisibleTargetSeries = new List<Series>();
     91
     92      targetChart.CustomizeAllChartAreas();
     93      targetChart.ChartAreas[0].CursorX.Interval = 1;
     94      targetChart.SuppressExceptions = true;
    9595      byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of each of a number of groups.") {
    9696        VisualProperties = {
     
    196196      dataTableComboBox.Items.Clear();
    197197      groupComboBox.Items.Clear();
    198       byTargetDataTable.Rows.Clear();
     198      targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
     199      targetChart.Series.Clear();
     200      invisibleTargetSeries.Clear();
     201      byCostDataTable.VisualProperties.XAxisLogScale = false;
     202      byCostDataTable.Rows.Clear();
    199203
    200204      UpdateCaption();
     
    309313    private void UpdateResultsByTarget() {
    310314      // necessary to reset log scale -> empty chart cannot use log scaling
    311       byTargetDataTable.VisualProperties.XAxisLogScale = false;
    312       byTargetDataTable.Rows.Clear();
     315      targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
     316      targetChart.Series.Clear();
     317      invisibleTargetSeries.Clear();
    313318
    314319      var table = (string)dataTableComboBox.SelectedItem;
     
    324329      var lineStyleCount = 0;
    325330
     331      // if the group contains multiple different problem instances we want to use the
     332      // minimal maximal observed effort otherwise we run into situations where we don't
     333      // have data for a certain problem instance anymore this is a special case when
     334      // aggregating over multiple problem instances     
    326335      var maxEfforts = new Dictionary<ProblemDescription, double>();
     336      double minEff = double.MaxValue, maxEff = double.MinValue;
    327337      foreach (var group in groupedRuns) {
    328338        foreach (var problem in group.Value) {
    329           double eff;
    330           if (!maxEfforts.TryGetValue(problem.Key, out eff)) {
    331             eff = 0.0;
    332           }
     339          double problemSpecificMaxEff;
     340          if (!maxEfforts.TryGetValue(problem.Key, out problemSpecificMaxEff)) {
     341            problemSpecificMaxEff = 0;
     342          }
     343          var bestKnownTarget = problem.Value.Item1;
     344          var max = problem.Key.IsMaximization();
     345          var worstTarget = (max ? (1 - targets.Max()) : (1 + targets.Max())) * bestKnownTarget;
     346          var bestTarget = (max ? (1 - targets.Min()) : (1 + targets.Min())) * bestKnownTarget;
    333347          foreach (var run in problem.Value.Item2) {
    334             var maxEff = ((IndexedDataTable<double>)run.Results[table]).Rows.First().Values.Last().Item1;
    335             if (maxEff > eff) eff = maxEff;
    336           }
    337           maxEfforts[problem.Key] = eff;
    338         }
    339       }
    340       // if the group contains multiple different problems we want to use the minimal maximal observed effort
    341       // otherwise we run into situations where we don't have data for a certain problem instance anymore
    342       // this is a special case when aggregating over multiple problem instances
    343       var maxEffort = maxEfforts.Values.Min();
     348            var row = ((IndexedDataTable<double>)run.Results[table]).Rows.First().Values;
     349            var a = row.FirstOrDefault(x => max ? x.Item2 >= worstTarget : x.Item2 <= worstTarget);
     350            var b = row.FirstOrDefault(x => max ? x.Item2 >= bestTarget : x.Item2 <= bestTarget);
     351            var firstEff = (a == default(Tuple<double, double>)) ? row.Last().Item1 : a.Item1;
     352            var lastEff = (b == default(Tuple<double, double>)) ? row.Last().Item1 : b.Item1;
     353            if (minEff > firstEff) minEff = firstEff;
     354            if (maxEff < lastEff) maxEff = lastEff;
     355            if (problemSpecificMaxEff < lastEff) problemSpecificMaxEff = lastEff;
     356          }
     357          maxEfforts[problem.Key] = problemSpecificMaxEff;
     358        }
     359      }
     360      maxEff = Math.Min(maxEff, maxEfforts.Values.Min());
     361
     362      var minZeros = (int)Math.Floor(Math.Log10(minEff));
     363      var maxZeros = (int)Math.Floor(Math.Log10(maxEff));
     364      var axisMin = (decimal)Math.Pow(10, minZeros);
     365      var axisMax = (decimal)Math.Pow(10, maxZeros);
     366      if (!targetLogScalingCheckBox.Checked) {
     367        var minAdd = (decimal)Math.Pow(10, minZeros - 1) * 2;
     368        var maxAdd = (decimal)Math.Pow(10, maxZeros - 1) * 2;
     369        while (axisMin + minAdd < (decimal)minEff) axisMin += minAdd;
     370        while (axisMax <= (decimal)maxEff) axisMax += maxAdd;
     371      } else axisMax = (decimal)Math.Pow(10, (int)Math.Ceiling(Math.Log10(maxEff)));
     372      targetChart.ChartAreas[0].AxisX.Minimum = (double)axisMin;
     373      targetChart.ChartAreas[0].AxisX.Maximum = (double)axisMax;
    344374
    345375      foreach (var group in groupedRuns) {
     
    358388            xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
    359389
    360             if (eachOrAllTargetCheckBox.Checked) {
    361               CalculateHitsForEachTarget(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1, maxEffort);
    362               // achiving each target can be seen as a separate run for that target only
    363               noRuns += targets.Length;
     390            if (aggregateTargetsCheckBox.Checked) {
     391              var length = CalculateHitsForAllTargets(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1, maxEff);
     392              maxLength = Math.Max(length, maxLength);
    364393            } else {
    365               var length = CalculateHitsForAllTargets(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1, maxEffort);
    366               maxLength = Math.Max(length, maxLength);
    367               noRuns++;
     394              CalculateHitsForEachTarget(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1, maxEff);
    368395            }
    369           }
    370         }
    371 
     396            noRuns++;
     397          }
     398        }
    372399        foreach (var list in hits) {
    373           var row = new IndexedDataRow<double>(list.Key) {
    374             VisualProperties = {
    375               ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
    376               LineWidth = 2,
    377               Color = colors[colorCount],
    378               LineStyle = lineStyles[lineStyleCount],
    379               StartIndexZero = false
     400          var row = new Series(list.Key) {
     401            ChartType = SeriesChartType.StepLine,
     402            BorderWidth = 2,
     403            Color = colors[colorCount],
     404            BorderDashStyle = lineStyles[lineStyleCount],
     405          };
     406          var rowShade = new Series(list.Key + "-range") {
     407            IsVisibleInLegend = false,
     408            ChartType = SeriesChartType.Range,
     409            Color = Color.FromArgb(32, colors[colorCount])
     410          };
     411
     412          var ecdf = 0.0;
     413          var missedecdf = 0.0;
     414          var iter = misses[list.Key].GetEnumerator();
     415          var moreMisses = iter.MoveNext();
     416          var totalTargets = noRuns;
     417          if (aggregateTargetsCheckBox.Checked) totalTargets *= targets.Length;
     418          var movingTargets = totalTargets;
     419          foreach (var h in list.Value) {
     420            while (moreMisses && iter.Current.Key <= h.Key) {
     421              missedecdf += iter.Current.Value;
     422              movingTargets -= iter.Current.Value;
     423              if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key)
     424                row.Points.Last().SetValueY(ecdf / movingTargets);
     425              else row.Points.AddXY(iter.Current.Key, ecdf / movingTargets);
     426              if (boundShadingCheckBox.Checked) {
     427                if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key)
     428                  rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets);
     429                else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets }));
     430              }
     431              moreMisses = iter.MoveNext();
    380432            }
    381           };
    382 
    383           var ecdf = 0.0;
    384           var iter = misses[list.Key].GetEnumerator();
    385           iter.MoveNext();
    386           var sumTargets = noRuns * targets.Length;
    387           foreach (var h in list.Value) {
    388433            ecdf += h.Value;
    389             while (iter.Current.Key < h.Key) {
    390               sumTargets -= iter.Current.Value;
    391               if (!iter.MoveNext()) break;
     434            if (row.Points.Count > 0 && row.Points.Last().XValue == h.Key)
     435              row.Points.Last().SetValueY(ecdf / movingTargets);
     436            else row.Points.AddXY(h.Key, ecdf / movingTargets);
     437            if (missedecdf > 0 && boundShadingCheckBox.Checked) {
     438              if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == h.Key)
     439                rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets);
     440              else rowShade.Points.Add(new DataPoint(h.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets }));
    392441            }
    393             row.Values.Add(Tuple.Create(h.Key, ecdf / sumTargets));
    394           }
    395 
    396           if (maxLength > 0 && (row.Values.Count == 0 || row.Values.Last().Item1 < maxLength))
    397             row.Values.Add(Tuple.Create(maxLength, ecdf / sumTargets));
    398 
    399           byTargetDataTable.Rows.Add(row);
     442          }
     443
     444          while (moreMisses) {
     445            // if there are misses beyond the last hit we extend the shaded area
     446            missedecdf += iter.Current.Value;
     447            //movingTargets -= iter.Current.Value;
     448            if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key)
     449              row.Points.Last().SetValueY(ecdf / movingTargets);
     450            else row.Points.AddXY(iter.Current.Key, ecdf / movingTargets);
     451            if (boundShadingCheckBox.Checked) {
     452              if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key)
     453                rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets);
     454              else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets }));
     455            }
     456            moreMisses = iter.MoveNext();
     457          }
     458
     459          if (maxLength > 0 && (row.Points.Count == 0 || row.Points.Last().XValue < maxLength))
     460            row.Points.AddXY(maxLength, ecdf / movingTargets);
     461
     462          if (row.Points.Count > 0) {
     463            var point = row.Points.Last();
     464            point.Label = row.Name;
     465            point.MarkerStyle = MarkerStyle.Cross;
     466            point.MarkerBorderWidth = 1;
     467          }
     468
     469          ConfigureSeries(row);
     470          targetChart.Series.Add(rowShade);
     471          targetChart.Series.Add(row);
    400472        }
    401473        colorCount = (colorCount + 1) % colors.Length;
     
    404476
    405477      if (targets.Length == 1)
    406         ByTargetDataTable.VisualProperties.YAxisTitle = "Probability to be " + (targets[0] * 100) + "% worse than best";
    407       else ByTargetDataTable.VisualProperties.YAxisTitle = "Proportion of reached targets";
    408       byTargetDataTable.VisualProperties.XAxisTitle = string.Join(" / ", xAxisTitles);
    409       byTargetDataTable.VisualProperties.XAxisLogScale = byTargetDataTable.Rows.Count > 0 && targetLogScalingCheckBox.Checked;
    410 
     478        targetChart.ChartAreas[0].AxisY.Title = "Probability to be " + (targets[0] * 100) + "% worse than best";
     479      else targetChart.ChartAreas[0].AxisY.Title = "Proportion of reached targets";
     480      targetChart.ChartAreas[0].AxisX.Title = string.Join(" / ", xAxisTitles);
     481      targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic();
     482      targetChart.ChartAreas[0].CursorY.Interval = 0.05;
    411483      UpdateErtTables(groupedRuns);
    412484    }
     
    423495                                            IndexedDataRow<double> row, ProblemDescription problem,
    424496                                            string group, double bestTarget, double maxEffort) {
    425       foreach (var l in targets.Select(x => (problem.IsMaximization() ? (1 - x) : (1 + x)) * bestTarget)) {
    426         var key = group + "-" + l;
     497      foreach (var t in targets.Select(x => Tuple.Create((problem.IsMaximization() ? (1 - x) : (1 + x)) * bestTarget, x))) {
     498        var l = t.Item1;
     499        var key = group + "_" + (t.Item2 * 100) + "%_" + l;
    427500        if (!hits.ContainsKey(key)) {
    428501          hits.Add(key, new SortedList<double, int>());
     
    572645              LineWidth = 2,
    573646              Color = colors[colorCount],
    574               LineStyle = lineStyles[lineStyleCount],
     647              LineStyle = hlLineStyles[lineStyleCount],
    575648              StartIndexZero = false
    576649            }
     
    688761
    689762    private void logScalingCheckBox_CheckedChanged(object sender, EventArgs e) {
    690       byTargetDataTable.VisualProperties.XAxisLogScale = byTargetDataTable.Rows.Count > 0 && targetLogScalingCheckBox.Checked;
     763      UpdateResultsByTarget();
    691764      byCostDataTable.VisualProperties.XAxisLogScale = byCostDataTable.Rows.Count > 0 && budgetLogScalingCheckBox.Checked;
     765    }
     766
     767    private void boundShadingCheckBox_CheckedChanged(object sender, EventArgs e) {
     768      UpdateResultsByTarget();
    692769    }
    693770
     
    722799    }
    723800
    724     private void eachOrAllTargetCheckBox_CheckedChanged(object sender, EventArgs e) {
    725       var each = eachOrAllTargetCheckBox.Checked;
    726       eachOrAllTargetCheckBox.Text = each ? "each" : "all";
     801    private void aggregateTargetsCheckBox_CheckedChanged(object sender, EventArgs e) {
    727802      SuspendRepaint();
    728803      try {
     
    918993    #endregion
    919994
     995    private void ConfigureSeries(Series series) {
     996      series.SmartLabelStyle.Enabled = true;
     997      series.SmartLabelStyle.AllowOutsidePlotArea = LabelOutsidePlotAreaStyle.No;
     998      series.SmartLabelStyle.CalloutLineAnchorCapStyle = LineAnchorCapStyle.None;
     999      series.SmartLabelStyle.CalloutLineColor = series.Color;
     1000      series.SmartLabelStyle.CalloutLineWidth = 2;
     1001      series.SmartLabelStyle.CalloutStyle = LabelCalloutStyle.Underlined;
     1002      series.SmartLabelStyle.IsOverlappedHidden = false;
     1003      series.SmartLabelStyle.MaxMovingDistance = 200;
     1004      series.ToolTip = series.LegendText + " X = #VALX, Y = #VALY";
     1005    }
     1006
     1007    private void chart_MouseDown(object sender, MouseEventArgs e) {
     1008      HitTestResult result = targetChart.HitTest(e.X, e.Y);
     1009      if (result.ChartElementType == ChartElementType.LegendItem) {
     1010        ToggleTargetChartSeriesVisible(result.Series);
     1011      }
     1012    }
     1013    private void chart_MouseMove(object sender, MouseEventArgs e) {
     1014      HitTestResult result = targetChart.HitTest(e.X, e.Y);
     1015      if (result.ChartElementType == ChartElementType.LegendItem)
     1016        this.Cursor = Cursors.Hand;
     1017      else
     1018        this.Cursor = Cursors.Default;
     1019    }
     1020    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
     1021      foreach (LegendItem legendItem in e.LegendItems) {
     1022        var series = targetChart.Series[legendItem.SeriesName];
     1023        if (series != null) {
     1024          bool seriesIsInvisible = invisibleTargetSeries.Any(x => x.Name == series.Name);
     1025          foreach (LegendCell cell in legendItem.Cells) {
     1026            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
     1027          }
     1028        }
     1029      }
     1030    }
     1031
     1032    private void ToggleTargetChartSeriesVisible(Series series) {
     1033      var indexList = invisibleTargetSeries.FindIndex(x => x.Name == series.Name);
     1034      var indexChart = targetChart.Series.IndexOf(series);
     1035      if (targetChart.Series.Count == 1) targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
     1036      targetChart.Series.RemoveAt(indexChart);
     1037      var s = indexList >= 0 ? invisibleTargetSeries[indexList] : new Series(series.Name) {
     1038        Color = series.Color,
     1039        ChartType = series.ChartType,
     1040        BorderWidth = series.BorderWidth,
     1041        BorderDashStyle = series.BorderDashStyle
     1042      };
     1043      if (indexList < 0) {
     1044        // hide
     1045        invisibleTargetSeries.Add(series);
     1046        var shadeSeries = targetChart.Series.FirstOrDefault(x => x.Name == series.Name + "-range");
     1047        if (shadeSeries != null) {
     1048          if (targetChart.Series.Count == 1) targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
     1049          targetChart.Series.Remove(shadeSeries);
     1050          invisibleTargetSeries.Add(shadeSeries);
     1051          indexChart--;
     1052        }
     1053      } else {
     1054        // show
     1055        invisibleTargetSeries.RemoveAt(indexList);
     1056        var shadeSeries = invisibleTargetSeries.FirstOrDefault(x => x.Name == series.Name + "-range");
     1057        if (shadeSeries != null) {
     1058          invisibleTargetSeries.Remove(shadeSeries);
     1059          InsertOrAddSeries(indexChart, shadeSeries);
     1060          indexChart++;
     1061        }
     1062      }
     1063      InsertOrAddSeries(indexChart, s);
     1064      targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic();
     1065    }
     1066
     1067    private bool CanDisplayLogarithmic() {
     1068      return targetLogScalingCheckBox.Checked
     1069        && targetChart.Series.Count > 0 // must have a series
     1070        && targetChart.Series.Any(x => x.Points.Count > 0) // at least one series must have points
     1071        && targetChart.Series.All(s => s.Points.All(p => p.XValue > 0)); // all points must be positive
     1072    }
     1073
     1074    private void InsertOrAddSeries(int index, Series s) {
     1075      if (targetChart.Series.Count <= index)
     1076        targetChart.Series.Add(s);
     1077      else targetChart.Series.Insert(index, s);
     1078    }
    9201079
    9211080    private class ProblemDescription {
Note: See TracChangeset for help on using the changeset viewer.