Changeset 13831


Ignore:
Timestamp:
05/04/16 15:00:49 (4 years ago)
Author:
pfleck
Message:

#2597:

  • merged recent trunk changes for GetUsedVariablesForPrediction method.
  • Merged chart from RegressionSolutionGradientView and existing GradientChart.
  • Used the GradientChart in the RegressionSolutionGradientView.
Location:
branches/HeuristicLab.RegressionSolutionGradientView
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis

  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.Designer.cs

    r13818 r13831  
    2424    /// </summary>
    2525    private void InitializeComponent() {
     26      this.components = new System.ComponentModel.Container();
    2627      System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation verticalLineAnnotation1 = new System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation();
    2728      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
    28       System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
    29       ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
     29      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine1 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
     30      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine2 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
     31      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
     32      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
     33      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
    3034      this.SuspendLayout();
     35      //
     36      // chart
     37      //
     38      this.chart.AllowDrop = true;
     39      verticalLineAnnotation1.AllowMoving = true;
     40      verticalLineAnnotation1.AxisXName = "ChartArea\\rX";
     41      verticalLineAnnotation1.ClipToChartArea = "ChartArea";
     42      verticalLineAnnotation1.IsInfinitive = true;
     43      verticalLineAnnotation1.LineColor = System.Drawing.Color.Red;
     44      verticalLineAnnotation1.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
     45      verticalLineAnnotation1.Name = "VerticalLineAnnotation";
     46      verticalLineAnnotation1.YAxisName = "ChartArea1\\rY";
     47      this.chart.Annotations.Add(verticalLineAnnotation1);
     48      stripLine1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
     49      stripLine2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
     50      chartArea1.AxisX.StripLines.Add(stripLine1);
     51      chartArea1.AxisX.StripLines.Add(stripLine2);
     52      chartArea1.Name = "ChartArea";
     53      this.chart.ChartAreas.Add(chartArea1);
     54      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
     55      legend1.Alignment = System.Drawing.StringAlignment.Center;
     56      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
     57      legend1.LegendItemOrder = System.Windows.Forms.DataVisualization.Charting.LegendItemOrder.SameAsSeriesOrder;
     58      legend1.Name = "Default";
     59      this.chart.Legends.Add(legend1);
     60      this.chart.Location = new System.Drawing.Point(0, 0);
     61      this.chart.Name = "chart";
     62      this.chart.PaletteCustomColors = new System.Drawing.Color[] {
     63        System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(180)))), ((int)(((byte)(65))))),
     64        System.Drawing.Color.FromArgb(((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))))};
     65      this.chart.Size = new System.Drawing.Size(453, 308);
     66      this.chart.TabIndex = 0;
     67      this.chart.AnnotationPositionChanged += new System.EventHandler(this.chart_AnnotationPositionChanged);
     68      this.chart.AnnotationPositionChanging += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.AnnotationPositionChangingEventArgs>(this.chart_AnnotationPositionChanging);
     69      this.chart.FormatNumber += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.FormatNumberEventArgs>(this.chart_FormatNumber);
     70      this.chart.DragDrop += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragDrop);
     71      this.chart.DragEnter += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragEnter);
     72      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
    3173      //
    3274      // GradientChart
    3375      //
    34       this.AllowDrop = true;
    35       verticalLineAnnotation1.AllowMoving = true;
    36       verticalLineAnnotation1.AxisXName = "ChartArea1\\rX";
    37       verticalLineAnnotation1.ClipToChartArea = "ChartArea1";
    38       verticalLineAnnotation1.IsInfinitive = true;
    39       verticalLineAnnotation1.LineColor = System.Drawing.Color.Red;
    40       verticalLineAnnotation1.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
    41       verticalLineAnnotation1.Name = "VerticalLineAnnotation1";
    42       verticalLineAnnotation1.YAxisName = "ChartArea1\\rY";
    43       this.Annotations.Add(verticalLineAnnotation1);
    44       chartArea1.Name = "ChartArea1";
    45       this.ChartAreas.Add(chartArea1);
    46       series1.ChartArea = "ChartArea1";
    47       series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
    48       series1.Name = "Series1";
    49       this.Series.Add(series1);
    50       this.AnnotationPositionChanged += new System.EventHandler(this.chart_AnnotationPositionChanged);
    51       this.AnnotationPositionChanging += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.AnnotationPositionChangingEventArgs>(this.chart_AnnotationPositionChanging);
    52       this.DragDrop += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragDrop);
    53       this.DragEnter += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragEnter);
    54       ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
     76      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
     77      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
     78      this.Controls.Add(this.chart);
     79      this.Name = "GradientChart";
     80      this.Size = new System.Drawing.Size(453, 308);
     81      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
    5582      this.ResumeLayout(false);
    5683
     
    5885
    5986    #endregion
     87
     88    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
    6089  }
    6190}
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.cs

    r13830 r13831  
    2222using System;
    2323using System.Collections.Generic;
    24 using System.Drawing;
    2524using System.Globalization;
    2625using System.Linq;
     
    3130
    3231namespace HeuristicLab.Problems.DataAnalysis.Views {
    33   public partial class GradientChart : EnhancedChart {
    34     private ModifiableDataset sharedDataset; // used for syncronising variable values between charts
     32  public partial class GradientChart : UserControl {
     33    private ModifiableDataset sharedFixedVariables; // used for syncronising variable values between charts
    3534    private ModifiableDataset internalDataset; // used to cache values and speed up calculations
    3635
    37     public bool ShowLegend { get; set; }
    38     public bool ShowXAxisLabel { get; set; }
    39     public bool ShowYAxisLabel { get; set; }
    40     public bool ShowCursor { get; set; }
    41 
    42     private bool useMedianValues;
    43     public bool UseMedianValues {
    44       get { return useMedianValues; }
     36    public bool ShowLegend {
     37      get { return chart.Legends[0].Enabled; }
     38      set { chart.Legends[0].Enabled = value; }
     39    }
     40    public bool ShowXAxisLabel {
     41      get { return chart.ChartAreas[0].AxisX.Enabled == AxisEnabled.True; }
     42      set { chart.ChartAreas[0].AxisX.Enabled = value ? AxisEnabled.True : AxisEnabled.False; }
     43    }
     44    public bool ShowYAxisLabel {
     45      get { return chart.ChartAreas[0].AxisY.Enabled == AxisEnabled.True; }
     46      set { chart.ChartAreas[0].AxisY.Enabled = value ? AxisEnabled.True : AxisEnabled.False; }
     47    }
     48    public bool ShowCursor {
     49      get { return chart.Annotations[0].Visible; }
     50      set { chart.Annotations[0].Visible = value; }
     51    }
     52
     53    private int xAxisTicks = 5;
     54    public int XAxisTicks {
     55      get { return xAxisTicks; }
     56      set { if (xAxisTicks != value) { xAxisTicks = value; UpdateChart(); } }
     57    }
     58    private int yAxisTicks = 5;
     59    public int YXAxisTicks {
     60      get { return yAxisTicks; }
     61      set { if (yAxisTicks != value) { yAxisTicks = value; UpdateChart(); } }
     62    }
     63
     64    private double trainingMin = double.MinValue;
     65    public double TrainingMin {
     66      get { return trainingMin; }
     67      set { if (!value.IsAlmost(trainingMin)) { trainingMin = value; UpdateChart(); } }
     68    }
     69    private double trainingMax = double.MaxValue;
     70    public double TrainingMax {
     71      get { return trainingMax; }
     72      set { if (!value.IsAlmost(trainingMax)) { trainingMax = value; UpdateChart(); } }
     73    }
     74
     75    private int drawingSteps = 1000;
     76    public int DrawingSteps {
     77      get { return drawingSteps; }
     78      set { if (value != drawingSteps) { drawingSteps = value; UpdateChart(); } }
     79    }
     80
     81    private string freeVariable;
     82    public string FreeVariable {
     83      get { return freeVariable; }
    4584      set {
    46         if (value == useMedianValues) return;
    47         useMedianValues = value;
    48         OnChartPropertyChanged(this, EventArgs.Empty);
     85        if (value == freeVariable) return;
     86        if (solutions.Any(s => !s.ProblemData.Dataset.DoubleVariables.Contains(value))) {
     87          throw new ArgumentException("Variable does not exist in the ProblemData of the Solutions.");
     88        }
     89        freeVariable = value;
     90        RecalculateInternalDataset();
    4991        UpdateChart();
    5092      }
    5193    }
    5294
    53     private int row;
    54     public int Row {
    55       get { return row; }
    56       set {
    57         if (row == value) return;
    58         row = value;
    59         OnChartPropertyChanged(this, EventArgs.Empty);
    60         UpdateChart();
    61       }
    62     }
    63 
    64     private double min;
    65     public double Min {
    66       get { return min; }
    67       set {
    68         if (value.IsAlmost(min)) return;
    69         min = value;
    70         OnChartPropertyChanged(this, EventArgs.Empty);
    71         UpdateChart();
    72       }
    73     }
    74 
    75     private double max;
    76     public double Max {
    77       get { return max; }
    78       set {
    79         if (value.IsAlmost(max)) return;
    80         max = value;
    81         OnChartPropertyChanged(this, EventArgs.Empty);
    82         UpdateChart();
    83       }
    84     }
    85 
    86     private int points;
    87     public int Points {
    88       get { return points; }
    89       set {
    90         if (value == points) return;
    91         points = value;
    92         OnChartPropertyChanged(this, EventArgs.Empty);
    93         UpdateChart();
    94       }
    95     }
    96 
    97     private IRegressionProblemData problemData;
    98     public IRegressionProblemData ProblemData {
    99       get { return problemData; }
    100       set {
    101         if (!SolutionsCompatibleWithProblemData(value, solutionList))
    102           throw new ArgumentException("The problem data provided does not contain all the variables required by the solutions.");
    103         problemData = value;
    104         UpdateDataset();
    105         UpdateChart();
    106       }
    107     }
    108 
    109     public string Target {
    110       get { return Solutions.First().ProblemData.TargetVariable; }
    111     }
    112 
    113     private string variable;
    114     public string Variable {
    115       get { return variable; }
    116       set {
    117         if (variable == value) return;
    118         if (!ProblemData.Dataset.DoubleVariables.Contains(value))
    119           throw new ArgumentException("The variable must be present in the problem dataset.");
    120         OnChartPropertyChanged(this, EventArgs.Empty);
    121         variable = value;
    122         var values = ProblemData.Dataset.GetReadOnlyDoubleValues(variable);
    123         min = values.Min();
    124         max = values.Max();
    125         UpdateChart();
    126       }
    127     }
    128 
    129     private List<IRegressionSolution> solutionList;
     95    private bool updateChartAutomatically = false;
     96    public bool UpdateChartAutomatically {
     97      get { return updateChartAutomatically; }
     98      set { updateChartAutomatically = value; if (updateChartAutomatically) UpdateChart(); }
     99    }
     100
     101    private readonly List<IRegressionSolution> solutions = new List<IRegressionSolution>();
    130102    public IEnumerable<IRegressionSolution> Solutions {
    131       get { return solutionList; }
    132       set {
    133         if (!value.Any())
    134           throw new ArgumentException("At least one solution must be provided.");
    135         if (SolutionsCompatibleWithProblemData(problemData, value))
    136           solutionList = new List<IRegressionSolution>(value);
    137         else
    138           throw new ArgumentException("The provided solution collection is not compatible with the existing problem data.");
    139         UpdateChart();
    140       }
    141     }
    142 
    143     public VerticalLineAnnotation VerticalLineAnnotation {
    144       get { return (VerticalLineAnnotation)Annotations.SingleOrDefault(x => x is VerticalLineAnnotation); }
     103      get { return solutions; }
     104    }
     105
     106    private VerticalLineAnnotation VerticalLineAnnotation {
     107      get { return (VerticalLineAnnotation)chart.Annotations.SingleOrDefault(x => x is VerticalLineAnnotation); }
    145108    }
    146109
    147110    public GradientChart() {
    148111      InitializeComponent();
    149       RegisterEvents();
    150     }
    151 
    152     public void AddSolution(IRegressionSolution solution) {
    153       if (!SolutionsCompatibleWithProblemData(problemData, new[] { solution })) {
    154         throw new ArgumentException("The solution is not compatible with the problem data.");
    155       }
    156       solutionList.Add(solution);
    157       UpdateChart();
    158     }
    159 
    160     public void RemoveSolution(IRegressionSolution solution) {
    161       var removed = solutionList.RemoveAll(x => x == solution);
    162       if (removed > 0)
    163         UpdateChart();
    164     }
    165 
    166     private static bool SolutionsCompatibleWithProblemData(IRegressionProblemData pd, IEnumerable<IRegressionSolution> solutions) {
    167       if (pd == null || !solutions.Any()) return true;
    168       if (solutions.Any(x => x.ProblemData.TargetVariable != pd.TargetVariable)) return false;
    169       var variables = new HashSet<string>(pd.Dataset.DoubleVariables);
    170       return solutions.SelectMany(x => x.ProblemData.Dataset.DoubleVariables).All(variables.Contains);
    171     }
    172 
    173     public void Configure(IEnumerable<IRegressionSolution> solutions, IRegressionProblemData pd, ModifiableDataset dataset, string variable, double min, double max, int points) {
    174       if (!SolutionsCompatibleWithProblemData(pd, solutions))
     112    }
     113
     114    public void Configure(IEnumerable<IRegressionSolution> solutions, ModifiableDataset sharedFixedVariables, string freeVariable, int drawingSteps) {
     115      if (!SolutionsCompatible(solutions))
    175116        throw new ArgumentException("Solutions are not compatible with the problem data.");
    176       this.solutionList = new List<IRegressionSolution>(solutions);
    177       this.problemData = pd;
    178       this.variable = variable;
    179       this.sharedDataset = dataset;
    180       this.min = min;
    181       this.max = max;
    182       this.points = points;
     117      this.solutions.Clear();
     118      this.solutions.AddRange(solutions);
     119      this.freeVariable = freeVariable;
     120      this.drawingSteps = drawingSteps;
    183121
    184122      // add an event such that whenever a value is changed in the shared dataset,
    185123      // this change is reflected in the internal dataset (where the value becomes a whole column)
    186       var variables = sharedDataset.DoubleVariables.ToList();
    187       sharedDataset.ItemChanged += (o, e) => {
    188         var rowIndex = e.Value;
    189         var columnIndex = e.Value2;
    190         var ds = (ModifiableDataset)o;
    191         var variableName = variables[columnIndex];
    192         if (variableName == Variable) return;
    193         var v = ds.GetDoubleValue(variableName, rowIndex);
    194         var values = new List<double>(Enumerable.Repeat(v, Points));
    195         internalDataset.ReplaceVariable(variableName, values);
    196       };
    197 
    198       // configure internal dataset. we also expand the range in order to get nice tick intervals on the x axis
    199       const int tics = 5;
     124      if (this.sharedFixedVariables != null)
     125        this.sharedFixedVariables.ItemChanged -= sharedFixedVariables_ItemChanged;
     126      this.sharedFixedVariables = sharedFixedVariables;
     127      this.sharedFixedVariables.ItemChanged += sharedFixedVariables_ItemChanged;
     128
     129      trainingMin = solutions.Select(s => s.ProblemData.Dataset.GetDoubleValues(freeVariable, s.ProblemData.TrainingIndices).Min()).Max();
     130      trainingMax = solutions.Select(s => s.ProblemData.Dataset.GetDoubleValues(freeVariable, s.ProblemData.TrainingIndices).Max()).Min();
     131
     132      RecalculateInternalDataset();
     133    }
     134
     135    private void sharedFixedVariables_ItemChanged(object o, EventArgs<int, int> e) {
     136      var sender = (ModifiableDataset)o;
     137      var variables = sharedFixedVariables.DoubleVariables.ToList();
     138      var rowIndex = e.Value;
     139      var columnIndex = e.Value2;
     140
     141      var variableName = variables[columnIndex];
     142      if (variableName == FreeVariable) return;
     143      var v = sender.GetDoubleValue(variableName, rowIndex);
     144      var values = new List<double>(Enumerable.Repeat(v, DrawingSteps));
     145      internalDataset.ReplaceVariable(variableName, values);
     146
     147      if (UpdateChartAutomatically)
     148        UpdateChart();
     149    }
     150
     151    private void RecalculateInternalDataset() {
     152      // we expand the range in order to get nice tick intervals on the x axis
    200153      double xmin, xmax, xinterval;
    201       ChartUtil.CalculateAxisInterval(min, max, tics, out xmin, out xmax, out xinterval);
    202       var step = (xmax - xmin) / points;
     154      ChartUtil.CalculateAxisInterval(trainingMin, trainingMax, XAxisTicks, out xmin, out xmax, out xinterval);
     155      double step = (xmax - xmin) / drawingSteps;
     156
    203157      var xvalues = new List<double>();
    204       for (int i = 0; i < points; ++i) { xvalues.Add(xmin + i * step); }
    205       internalDataset = new ModifiableDataset(variables, variables.Select(x => x == Variable ? xvalues : new List<double>(Enumerable.Repeat(sharedDataset.GetDoubleValue(x, 0), xvalues.Count))));
     158      for (int i = 0; i < drawingSteps; i++)
     159        xvalues.Add(xmin + i * step);
     160
     161      var variables = sharedFixedVariables.DoubleVariables.ToList();
     162      internalDataset = new ModifiableDataset(variables,
     163        variables.Select(x => x == FreeVariable
     164          ? xvalues
     165          : Enumerable.Repeat(sharedFixedVariables.GetDoubleValue(x, 0), xvalues.Count).ToList()
     166        )
     167      );
    206168    }
    207169
    208170    public void UpdateChart() {
    209171      // throw exceptions?
    210       if (sharedDataset == null || solutionList == null || !solutionList.Any())
     172      if (sharedFixedVariables == null || solutions == null || !solutions.Any())
    211173        return;
    212       if (min.IsAlmost(max) || min > max || points == 0)
     174      if (trainingMin.IsAlmost(trainingMax) || trainingMin > trainingMax || drawingSteps == 0)
    213175        return;
    214       Series.Clear();
    215       var vla = VerticalLineAnnotation;
    216       Annotations.Clear();
    217       var defaultValue = sharedDataset.GetDoubleValue(variable, 0);
    218       vla.Visible = ShowCursor;
    219       Annotations.Add(vla);
    220       vla.X = defaultValue;
    221 
     176
     177      // Set cursor
     178      var defaultValue = sharedFixedVariables.GetDoubleValue(freeVariable, 0);
     179      VerticalLineAnnotation.X = defaultValue;
     180
     181      // Calculate X-axis interval
    222182      double axisMin, axisMax, axisInterval;
    223       // calculate X-axis interval
    224       ChartUtil.CalculateAxisInterval(min, max, 5, out axisMin, out axisMax, out axisInterval);
    225       var axis = ChartAreas[0].AxisX;
     183      ChartUtil.CalculateAxisInterval(trainingMin, trainingMax, XAxisTicks, out axisMin, out axisMax, out axisInterval);
     184      var axis = chart.ChartAreas[0].AxisX;
    226185      axis.Minimum = axisMin;
    227186      axis.Maximum = axisMax;
    228187      axis.Interval = axisInterval;
    229188
    230       for (int i = 0; i < solutionList.Count; ++i) {
    231         var solution = solutionList[i];
    232         var series = PlotSeries(solution);
    233         series.Name = Target + " " + i;
    234         Series.Add(series);
    235       }
    236       // calculate Y-axis interval
    237       double ymin = 0, ymax = 0;
    238       foreach (var v in Series[0].Points.Select(x => x.YValues[0])) {
    239         if (ymin > v) ymin = v;
    240         if (ymax < v) ymax = v;
    241       }
    242       ChartUtil.CalculateAxisInterval(ymin, ymax, 5, out axisMin, out axisMax, out axisInterval);
    243       axis = ChartAreas[0].AxisY;
    244       axis.Minimum = axisMin;
    245       axis.Maximum = axisMax;
    246       axis.Interval = axisInterval;
    247 
    248       if (ShowXAxisLabel) {
    249         ChartAreas[0].AxisX.Title = Variable + " : " + defaultValue.ToString("N3", CultureInfo.CurrentCulture); // set axis title
    250       }
    251 
    252       AddStripLines(); // add strip lines
    253       if (ShowLegend)
    254         AddLegends();
    255     }
    256 
    257     private void UpdateDataset() {
    258       var variables = ProblemData.Dataset.DoubleVariables.ToList();
    259       var variableValues = new List<double>[variables.Count];
    260 
    261       if (UseMedianValues) {
    262         for (int i = 0; i < variables.Count; ++i) {
    263           var median = ProblemData.Dataset.GetDoubleValues(variables[i], ProblemData.TrainingIndices).Median();
    264           variableValues[i] = new List<double> { median };
     189      // Create series
     190      chart.Series.Clear();
     191      for (int i = 0; i < solutions.Count; ++i) {
     192        var solution = solutions[i];
     193        Series confidenceIntervalPlotSeries;
     194        var series = CreateSeries(solution, out confidenceIntervalPlotSeries);
     195        series.Name = Solutions.First().ProblemData.TargetVariable + " " + i;
     196        if (confidenceIntervalPlotSeries != null)
     197          chart.Series.Add(confidenceIntervalPlotSeries);
     198        chart.Series.Add(series);
     199      }
     200      //// calculate Y-axis interval
     201      //double ymin = 0, ymax = 0;
     202      //foreach (var v in chart.Series[0].Points.Select(x => x.YValues[0])) {
     203      //  if (ymin > v) ymin = v;
     204      //  if (ymax < v) ymax = v;
     205      //}
     206      //ChartUtil.CalculateAxisInterval(ymin, ymax, YXAxisTicks, out axisMin, out axisMax, out axisInterval);
     207      //axis = chart.ChartAreas[0].AxisY;
     208      //axis.Minimum = axisMin;
     209      //axis.Maximum = axisMax;
     210      //axis.Interval = axisInterval;
     211
     212      // set axis title
     213      chart.ChartAreas[0].AxisX.Title = FreeVariable + " : " + defaultValue.ToString("N3", CultureInfo.CurrentCulture);
     214
     215      UpdateStripLines();
     216    }
     217
     218    private Series CreateSeries(IRegressionSolution solution, out Series confidenceIntervalPlotSeries) {
     219      var series = new Series {
     220        ChartType = SeriesChartType.Line
     221      };
     222
     223      var xvalues = internalDataset.GetDoubleValues(FreeVariable).ToList();
     224      var yvalues = solution.Model.GetEstimatedValues(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
     225      series.Points.DataBindXY(xvalues, yvalues);
     226
     227      var confidenceBoundSolution = solution as IConfidenceBoundRegressionSolution;
     228      if (confidenceBoundSolution != null) {
     229        var variances = confidenceBoundSolution.Model.GetEstimatedVariances(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
     230
     231        var lower = yvalues.Zip(variances, (m, s2) => m - 1.96 * Math.Sqrt(s2)).ToList();
     232        var upper = yvalues.Zip(variances, (m, s2) => m + 1.96 * Math.Sqrt(s2)).ToList();
     233
     234        confidenceIntervalPlotSeries = new Series {
     235          ChartType = SeriesChartType.Range,
     236          YValuesPerPoint = 2
     237        };
     238        confidenceIntervalPlotSeries.Points.DataBindXY(xvalues, lower, upper);
     239      } else {
     240        confidenceIntervalPlotSeries = null;
     241      }
     242
     243      return series;
     244    }
     245
     246    public void AddSolution(IRegressionSolution solution) {
     247      if (!SolutionsCompatible(solutions.Concat(new[] { solution })))
     248        throw new ArgumentException("The solution is not compatible with the problem data.");
     249      if (solutions.Contains(solution)) return;
     250      solutions.Add(solution);
     251      UpdateChart();
     252    }
     253    public void RemoveSolution(IRegressionSolution solution) {
     254      bool removed = solutions.Remove(solution);
     255      if (removed)
     256        UpdateChart();
     257    }
     258
     259    private static bool SolutionsCompatible(IEnumerable<IRegressionSolution> solutions) {
     260      foreach (var solution1 in solutions) {
     261        var variables1 = solution1.ProblemData.Dataset.DoubleVariables;
     262        foreach (var solution2 in solutions) {
     263          if (solution1 == solution2)
     264            continue;
     265          var variables2 = solution2.ProblemData.Dataset.DoubleVariables;
     266          if (!variables1.All(variables2.Contains))
     267            return false;
    265268        }
    266       } else {
    267         for (int i = 0; i < variables.Count; ++i) {
    268           var variableValue = ProblemData.Dataset.GetDoubleValue(variables[i], Row);
    269           variableValues[i] = new List<double> { variableValue };
    270         }
    271       }
    272       sharedDataset = new ModifiableDataset(variables, variableValues);
    273     }
    274 
    275     private Series PlotSeries(IRegressionSolution solution) {
    276       var v = sharedDataset.GetDoubleValue(variable, 0);
    277       var series = new Series { ChartType = SeriesChartType.Point };
    278       // get values from series
    279       var xvalues = internalDataset.GetReadOnlyDoubleValues(Variable);
    280       var yvalues = solution.Model.GetEstimatedValues(internalDataset, Enumerable.Range(0, internalDataset.Rows));
    281       int i = 0;
    282       foreach (var y in yvalues) {
    283         var x = xvalues[i++];
    284         series.Points.Add(new DataPoint(x, y) { MarkerSize = 2, MarkerColor = Color.DodgerBlue });
    285       }
    286       if (ShowCursor) {
    287         var y = solution.Model.GetEstimatedValues(sharedDataset, new[] { 0 }).Single();
    288         series.Points.Add(new DataPoint(v, y) { MarkerSize = 5, MarkerColor = Color.Red });
    289       }
    290       if (ShowLegend) {
    291         series.IsVisibleInLegend = true;
    292       }
    293       return series;
    294     }
    295 
    296     private void AddLegends() {
    297       Legends.Clear();
    298       var legend = new Legend();
    299       legend.Alignment = StringAlignment.Center;
    300       legend.LegendStyle = LegendStyle.Row;
    301       legend.Docking = Docking.Top;
    302       Legends.Add(legend);
    303       foreach (var s in Series) {
    304         s.Legend = legend.Name;
    305       }
    306     }
    307 
    308     private void AddStripLines() {
    309       var axisX = ChartAreas[0].AxisX;
    310       axisX.StripLines.Clear();
    311       axisX.StripLines.Add(new StripLine { BackColor = Color.FromArgb(30, Color.Green), IntervalOffset = axisX.Minimum, StripWidth = min - axisX.Minimum });
    312       axisX.StripLines.Add(new StripLine { BackColor = Color.FromArgb(30, Color.Green), IntervalOffset = max, StripWidth = axisX.Maximum - max });
    313     }
    314 
    315     private void RegisterEvents() {
    316       AnnotationPositionChanging += chart_AnnotationPositionChanging;
    317       MouseMove += chart_MouseMove;
    318       FormatNumber += chart_FormatNumber;
     269      }
     270      return true;
     271    }
     272
     273    private void UpdateStripLines() {
     274      var axisX = chart.ChartAreas[0].AxisX;
     275      var lowerStripLine = axisX.StripLines[0];
     276      var upperStripLine = axisX.StripLines[1];
     277
     278      lowerStripLine.IntervalOffset = axisX.Minimum;
     279      lowerStripLine.StripWidth = trainingMin - axisX.Minimum;
     280
     281      upperStripLine.IntervalOffset = trainingMax;
     282      upperStripLine.StripWidth = axisX.Maximum - trainingMax;
    319283    }
    320284
     
    327291    }
    328292
    329     public event EventHandler ChartPropertyChanged;
    330     public void OnChartPropertyChanged(object sender, EventArgs args) {
    331       var changed = ChartPropertyChanged;
    332       if (changed == null) return;
    333       changed(sender, args);
    334     }
    335 
    336293    private void chart_AnnotationPositionChanged(object sender, EventArgs e) {
    337294      var annotation = VerticalLineAnnotation;
    338295      var x = annotation.X;
    339       sharedDataset.SetVariableValue(x, Variable, 0);
    340       for (int i = 0; i < solutionList.Count; ++i) {
    341         var y = solutionList[i].Model.GetEstimatedValues(sharedDataset, new[] { 0 }).Single();
    342         var s = Series[i];
    343         var n = s.Points.Count;
    344         s.Points[n - 1] = new DataPoint(x, y) { MarkerColor = Color.Red, MarkerSize = 5 };
    345       }
    346       if (ShowXAxisLabel) {
    347         ChartAreas[0].AxisX.Title = Variable + " : " + x.ToString("N3", CultureInfo.CurrentCulture);
    348       }
    349       Update();
     296      sharedFixedVariables.SetVariableValue(x, FreeVariable, 0);
     297
     298      chart.ChartAreas[0].AxisX.Title = FreeVariable + " : " + x.ToString("N3", CultureInfo.CurrentCulture);
     299      chart.Update();
     300
    350301      OnVariableValueChanged(this, EventArgs.Empty);
    351302    }
    352303
    353304    private void chart_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e) {
    354       var step = (max - min) / points;
    355       e.NewLocationX = step * (long)Math.Round(e.NewLocationX / step);
    356       var axisX = ChartAreas[0].AxisX;
    357       if (e.NewLocationX > axisX.Maximum)
    358         e.NewLocationX = axisX.Maximum;
    359       if (e.NewLocationX < axisX.Minimum)
    360         e.NewLocationX = axisX.Minimum;
     305      //var step = (trainingMax - trainingMin) / drawingSteps;
     306      //e.NewLocationX = step * (long)Math.Round(e.NewLocationX / step);
     307      //var axisX = chart.ChartAreas[0].AxisX;
     308      //if (e.NewLocationX > axisX.Maximum)
     309      //  e.NewLocationX = axisX.Maximum;
     310      //if (e.NewLocationX < axisX.Minimum)
     311      //  e.NewLocationX = axisX.Minimum;
     312
     313      var annotation = VerticalLineAnnotation;
     314      var x = annotation.X;
     315      sharedFixedVariables.SetVariableValue(x, FreeVariable, 0);
     316
     317      chart.ChartAreas[0].AxisX.Title = FreeVariable + " : " + x.ToString("N3", CultureInfo.CurrentCulture);
     318      chart.Update();
     319
     320      OnVariableValueChanged(this, EventArgs.Empty);
    361321    }
    362322
    363323    private void chart_MouseMove(object sender, MouseEventArgs e) {
    364       this.Cursor = HitTest(e.X, e.Y).ChartElementType == ChartElementType.Annotation ? Cursors.VSplit : Cursors.Default;
     324      chart.Cursor = chart.HitTest(e.X, e.Y).ChartElementType == ChartElementType.Annotation ? Cursors.VSplit : Cursors.Default;
    365325    }
    366326
     
    388348      }
    389349    }
    390 
    391350    private void GradientChart_DragEnter(object sender, DragEventArgs e) {
    392351      if (!e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat)) return;
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj

    r13824 r13831  
    271271      <DependentUpon>FeatureCorrelationView.cs</DependentUpon>
    272272    </Compile>
     273    <Compile Include="GradientChart.cs">
     274      <SubType>UserControl</SubType>
     275    </Compile>
     276    <Compile Include="GradientChart.Designer.cs">
     277      <DependentUpon>GradientChart.cs</DependentUpon>
     278    </Compile>
    273279    <Compile Include="RegressionSolutionGradientView.cs">
    274280      <SubType>UserControl</SubType>
     
    467473    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
    468474      <DependentUpon>TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
    469     </Compile>
    470     <Compile Include="GradientChart.cs">
    471       <SubType>Component</SubType>
    472     </Compile>
    473     <Compile Include="GradientChart.Designer.cs">
    474       <DependentUpon>GradientChart.cs</DependentUpon>
    475475    </Compile>
    476476    <None Include="HeuristicLab.snk" />
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.Designer.cs

    r13824 r13831  
    2323  partial class RegressionSolutionGradientView {
    2424    /// <summary>
    25     /// Required designer variable.
     25    /// Required designer variableNames.
    2626    /// </summary>
    2727    private System.ComponentModel.IContainer components = null;
     
    4545    /// </summary>
    4646    private void InitializeComponent() {
    47       this.components = new System.ComponentModel.Container();
    48       System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
    49       System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
    50       this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
    5147      this.splitContainer = new System.Windows.Forms.SplitContainer();
     48      this.gradientChart = new HeuristicLab.Problems.DataAnalysis.Views.GradientChart();
    5249      this.configurationGroupBox = new System.Windows.Forms.GroupBox();
    5350      this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
    54       ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
    5551      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
    5652      this.splitContainer.Panel1.SuspendLayout();
     
    5955      this.configurationGroupBox.SuspendLayout();
    6056      this.SuspendLayout();
    61       //
    62       // chart
    63       //
    64       chartArea1.Name = "ChartArea";
    65       this.chart.ChartAreas.Add(chartArea1);
    66       this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
    67       legend1.Alignment = System.Drawing.StringAlignment.Center;
    68       legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
    69       legend1.Name = "Default";
    70       this.chart.Legends.Add(legend1);
    71       this.chart.Location = new System.Drawing.Point(0, 0);
    72       this.chart.Name = "chart";
    73       this.chart.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.None;
    74       this.chart.PaletteCustomColors = new System.Drawing.Color[] {
    75         System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(180)))), ((int)(((byte)(65))))),
    76         System.Drawing.Color.FromArgb(((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240))))),
    77         System.Drawing.Color.FromArgb(((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))))};
    78       this.chart.Size = new System.Drawing.Size(715, 376);
    79       this.chart.TabIndex = 0;
    80       this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
    81       this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
    82       this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
    83       this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
    8457      //
    8558      // splitContainer
     
    9265      // splitContainer.Panel1
    9366      //
    94       this.splitContainer.Panel1.Controls.Add(this.chart);
     67      this.splitContainer.Panel1.Controls.Add(this.gradientChart);
    9568      //
    9669      // splitContainer.Panel2
     
    10073      this.splitContainer.SplitterDistance = 376;
    10174      this.splitContainer.TabIndex = 1;
     75      //
     76      // gradientChart
     77      //
     78      this.gradientChart.Dock = System.Windows.Forms.DockStyle.Fill;
     79      this.gradientChart.DrawingSteps = 1000;
     80      this.gradientChart.UpdateChartAutomatically = true;
     81      this.gradientChart.Location = new System.Drawing.Point(0, 0);
     82      this.gradientChart.Name = "gradientChart";
     83      this.gradientChart.ShowCursor = false;
     84      this.gradientChart.ShowLegend = true;
     85      this.gradientChart.ShowXAxisLabel = true;
     86      this.gradientChart.ShowYAxisLabel = true;
     87      this.gradientChart.Size = new System.Drawing.Size(715, 376);
     88      this.gradientChart.TabIndex = 0;
     89      this.gradientChart.TrainingMax = 1.7976931348623157E+308D;
     90      this.gradientChart.TrainingMin = -1.7976931348623157E+308D;
     91      this.gradientChart.XAxisTicks = 10;
     92      this.gradientChart.YXAxisTicks = 5;
    10293      //
    10394      // configurationGroupBox
     
    132123      this.Name = "RegressionSolutionGradientView";
    133124      this.Size = new System.Drawing.Size(715, 591);
    134       ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
    135125      this.splitContainer.Panel1.ResumeLayout(false);
    136126      this.splitContainer.Panel2.ResumeLayout(false);
     
    143133
    144134    #endregion
    145 
    146     private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
    147135    private System.Windows.Forms.SplitContainer splitContainer;
    148136    private System.Windows.Forms.GroupBox configurationGroupBox;
    149137    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
     138    private Problems.DataAnalysis.Views.GradientChart gradientChart;
    150139  }
    151140}
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.cs

    r13824 r13831  
    2222using System;
    2323using System.Collections.Generic;
    24 using System.Drawing;
    2524using System.Linq;
    2625using System.Windows.Forms;
    27 using System.Windows.Forms.DataVisualization.Charting;
    2826using HeuristicLab.Collections;
    29 using HeuristicLab.Data;
    3027using HeuristicLab.MainForm;
    31 using HeuristicLab.MainForm.WindowsForms;
    3228using HeuristicLab.Problems.DataAnalysis;
    3329using HeuristicLab.Problems.DataAnalysis.Views;
     
    4541    private const string EstimatedVarianceSeriesName = "95% Conficence Interval";
    4642
    47     private readonly List<string> dimensionNames;
    48     private readonly ObservableList<DensityTrackbar> dimensionTrackbars;
     43    private readonly List<string> variableNames;
     44    private readonly ObservableList<DensityTrackbar> trackbars;
     45    private ModifiableDataset sharedFixedVariables;
    4946
    5047    private int ActiveDimension {
    51       get { return dimensionTrackbars.FindIndex(tb => tb.Checked); }
     48      get { return trackbars.FindIndex(tb => tb.Checked); }
    5249    }
    5350
     
    5956    public RegressionSolutionGradientView()
    6057      : base() {
    61       dimensionNames = new List<string>();
     58      variableNames = new List<string>();
    6259
    63       dimensionTrackbars = new ObservableList<DensityTrackbar>();
    64       dimensionTrackbars.ItemsAdded += (sender, args) => {
     60      trackbars = new ObservableList<DensityTrackbar>();
     61      trackbars.ItemsAdded += (sender, args) => {
    6562        ForEach(args.Items.Select(i => i.Value), RegisterEvents);
    6663      };
    67       dimensionTrackbars.ItemsRemoved += (sender, args) => {
     64      trackbars.ItemsRemoved += (sender, args) => {
    6865        ForEach(args.Items.Select(i => i.Value), DeregisterEvents);
    6966      };
    70       dimensionTrackbars.CollectionReset += (sender, args) => {
     67      trackbars.CollectionReset += (sender, args) => {
    7168        ForEach(args.OldItems.Select(i => i.Value), DeregisterEvents);
    7269        ForEach(args.Items.Select(i => i.Value), RegisterEvents);
    7370      };
    74 
    7571
    7672      InitializeComponent();
     
    7975      var vertScrollWidth = SystemInformation.VerticalScrollBarWidth;
    8076      tableLayoutPanel.Padding = new Padding(0, 0, vertScrollWidth, 0);
    81 
    82       // Configure axis
    83       chart.CustomizeAllChartAreas();
    84       chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
    85       chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
    86       chart.ChartAreas[0].CursorX.Interval = 1;
    87 
    88       chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
    89       chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
    90       chart.ChartAreas[0].CursorY.Interval = 0;
    91     }
    92 
    93     private void RedrawChart() {
    94       chart.Series.Clear();
    95       chart.ChartAreas[0].AxisX.StripLines.Clear();
    96       if (Content == null || ActiveDimension < 0) return;
    97 
    98       double minX = dimensionTrackbars[ActiveDimension].Limits.Lower;
    99       double maxX = dimensionTrackbars[ActiveDimension].Limits.Upper;
    100       decimal stepSize = (decimal)((maxX - minX) / DrawingSteps);
    101 
    102       // Build dataset
    103       var activeXs = Enumerable.Range(0, DrawingSteps).Select(i => (decimal)minX + i * stepSize).ToList();
    104       var fixedXs = dimensionTrackbars.Select(tb => tb.Value).ToList();
    105       var values = new double[DrawingSteps, dimensionNames.Count];
    106       for (int r = 0; r < DrawingSteps; r++) {
    107         for (int c = 0; c < dimensionNames.Count; c++) {
    108           values[r, c] = (double)(c == ActiveDimension ? activeXs[r] : fixedXs[c]);
    109         }
    110       }
    111       var dataset = new Dataset(dimensionNames, values);
    112 
    113       // Estimations
    114       var model = Content.Model;
    115       var means = model.GetEstimatedValues(dataset, Enumerable.Range(0, DrawingSteps)).ToList();
    116       var variances = model.GetEstimatedVariances(dataset, Enumerable.Range(0, DrawingSteps)).ToList();
    117 
    118       // Charting config
    119       chart.ChartAreas[0].AxisX.Minimum = minX;
    120       chart.ChartAreas[0].AxisX.Maximum = maxX;
    121       chart.ChartAreas[0].AxisX.Interval = (maxX - minX) / 10;
    122 
    123       // ToDo only databind and put config in codebehind
    124       chart.Series.Add(EstimatedVarianceSeriesName);
    125       chart.Series[EstimatedVarianceSeriesName].LegendText = EstimatedVarianceSeriesName;
    126       chart.Series[EstimatedVarianceSeriesName].ChartType = SeriesChartType.Range;
    127       chart.Series[EstimatedVarianceSeriesName].EmptyPointStyle.Color = chart.Series[EstimatedVarianceSeriesName].Color;
    128 
    129       chart.Series.Add(EstimatedMeanSeriesName);
    130       chart.Series[EstimatedMeanSeriesName].LegendText = EstimatedMeanSeriesName;
    131       chart.Series[EstimatedMeanSeriesName].ChartType = SeriesChartType.FastLine;
    132 
    133       // Charting databind
    134       var lower = means.Zip(variances, GetLowerConfBound).ToList();
    135       var upper = means.Zip(variances, GetUpperConfBound).ToList();
    136       chart.Series[EstimatedVarianceSeriesName].Points.DataBindXY(activeXs, lower, upper);
    137       chart.Series[EstimatedMeanSeriesName].Points.DataBindXY(activeXs, means);
    138 
    139       // Update StripLines
    140       var trainingValues = Content.ProblemData.Dataset.GetDoubleValues(dimensionNames[ActiveDimension],
    141         Content.ProblemData.TrainingIndices);
    142       var trainingRange = new DoubleRange(trainingValues.Min(), trainingValues.Max());
    143       if (minX < trainingRange.Start)
    144         CreateAndAddStripLine(minX, trainingRange.Start, Color.FromArgb(40, 223, 58, 2), Color.Transparent);
    145       if (maxX > trainingRange.End)
    146         CreateAndAddStripLine(trainingRange.End, maxX, Color.FromArgb(40, 223, 58, 2), Color.Transparent);
    147 
    148       // Update axis description
    149       chart.ChartAreas[0].AxisX.Title = dimensionNames[ActiveDimension];
    150     }
    151 
    152     private void CreateAndAddStripLine(double start, double end, Color color, Color secondColor) {
    153       StripLine stripLine = new StripLine {
    154         BackColor = color,
    155         BackSecondaryColor = secondColor,
    156         StripWidth = end - start,
    157         IntervalOffset = start
    158       };
    159       chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
    16077    }
    16178
    16279    private void UpdateConfigurationControls() {
    163       tableLayoutPanel.SuspendRepaint();
    164       tableLayoutPanel.SuspendLayout();
     80      variableNames.Clear();
     81      trackbars.Clear();
    16582
    16683      tableLayoutPanel.RowCount = 0;
    16784      tableLayoutPanel.Controls.Clear();
    16885
    169       dimensionNames.Clear();
    170       dimensionTrackbars.Clear();
     86      if (Content == null) return;
    17187
    172       if (Content == null) {
    173         tableLayoutPanel.ResumeLayout(true);
    174         tableLayoutPanel.ResumeRepaint(true);
    175         return;
     88      variableNames.AddRange(Content.ProblemData.AllowedInputVariables);
     89
     90      var newTrackbars = CreateConfiguration();
     91
     92      sharedFixedVariables = new ModifiableDataset(variableNames, newTrackbars.Select(tb => new List<double>(1) { (double)tb.Value }));
     93      gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableNames.First(), DrawingSteps);
     94      gradientChart.UpdateChart();
     95
     96      // Add to table and observable lists     
     97      tableLayoutPanel.RowCount = variableNames.Count;
     98      while (tableLayoutPanel.RowStyles.Count < variableNames.Count)
     99        tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
     100      for (int i = 0; i < newTrackbars.Count; i++) {
     101        // events registered automatically
     102        trackbars.Add(newTrackbars[i]);
     103        tableLayoutPanel.Controls.Add(newTrackbars[i], 0, i);
    176104      }
    177105
    178       dimensionNames.AddRange(Content.ProblemData.AllowedInputVariables);
     106      trackbars.First().Checked = true;
     107    }
     108
     109    private IList<DensityTrackbar> CreateConfiguration() {
    179110      var ranges = new List<DoubleLimit>();
    180       for (int i = 0; i < dimensionNames.Count; i++) {
    181         var values = Content.ProblemData.Dataset.GetDoubleValues(dimensionNames[i], Content.ProblemData.AllIndices);
     111      foreach (string variableName in variableNames) {
     112        var values = Content.ProblemData.Dataset.GetDoubleValues(variableName, Content.ProblemData.AllIndices);
    182113        double min, max, interval;
    183114        ChartUtil.CalculateAxisInterval(values.Min(), values.Max(), 10, out min, out max, out interval);
     
    185116      }
    186117
    187       tableLayoutPanel.RowCount = dimensionNames.Count;
    188       while (tableLayoutPanel.RowStyles.Count < dimensionNames.Count)
    189         tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
     118      var newTrackbars = new List<DensityTrackbar>();
     119      for (int i = 0; i < variableNames.Count; i++) {
     120        var name = variableNames[i];
     121        var trainingData = Content.ProblemData.Dataset.GetDoubleValues(name, Content.ProblemData.TrainingIndices).ToList();
    190122
    191       for (int i = 0; i < dimensionNames.Count; i++) {
    192         var name = dimensionNames[i];
    193         var trainingData =
    194           Content.ProblemData.Dataset.GetDoubleValues(name, Content.ProblemData.TrainingIndices).ToList();
    195 
    196         var dimensionTrackbar = new DensityTrackbar(name, ranges[i], trainingData);
    197 
    198         // events registered automatically
    199         dimensionTrackbars.Add(dimensionTrackbar);
    200 
    201         dimensionTrackbar.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
    202         tableLayoutPanel.Controls.Add(dimensionTrackbar, 0, i);
     123        var dimensionTrackbar = new DensityTrackbar(name, ranges[i], trainingData) {
     124          Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
     125        };
     126        newTrackbars.Add(dimensionTrackbar);
    203127      }
    204128
    205       if (dimensionTrackbars.Any())
    206         dimensionTrackbars.First().Checked = true;
    207 
    208       tableLayoutPanel.ResumeLayout(true);
    209       tableLayoutPanel.ResumeRepaint(true);
     129      return newTrackbars;
    210130    }
    211131
    212132    private void RegisterEvents(DensityTrackbar trackbar) {
    213       trackbar.CheckedChanged += DimensionTrackbar_CheckedChanged;
    214       trackbar.ValueChanged += DimensionTrackbar_ValueChanged;
    215       trackbar.LimitsChanged += DimensionTrackbar_LimitsChanged;
     133      trackbar.CheckedChanged += trackbar_CheckedChanged;
     134      trackbar.ValueChanged += trackbar_ValueChanged;
     135      trackbar.LimitsChanged += trackbar_LimitsChanged;
     136    }
     137    private void DeregisterEvents(DensityTrackbar trackbar) {
     138      trackbar.CheckedChanged -= trackbar_CheckedChanged;
     139      trackbar.ValueChanged -= trackbar_ValueChanged;
     140      trackbar.LimitsChanged -= trackbar_LimitsChanged;
    216141    }
    217142
    218     private void DeregisterEvents(DensityTrackbar trackbar) {
    219       trackbar.CheckedChanged -= DimensionTrackbar_CheckedChanged;
    220       trackbar.ValueChanged -= DimensionTrackbar_ValueChanged;
    221       trackbar.LimitsChanged -= DimensionTrackbar_LimitsChanged;
     143    private void trackbar_CheckedChanged(object sender, EventArgs e) {
     144      var trackBar = sender as DensityTrackbar;
     145      if (trackBar == null || !trackBar.Checked) return;
     146      // Uncheck all others
     147      foreach (var tb in trackbars.Except(new[] { trackBar }))
     148        tb.Checked = false;
     149      gradientChart.FreeVariable = variableNames[trackbars.IndexOf(trackBar)];
    222150    }
    223151
    224     private void DimensionTrackbar_CheckedChanged(object sender, EventArgs e) {
    225       var trackBarSender = sender as DensityTrackbar;
    226       if (trackBarSender == null || !trackBarSender.Checked) return;
    227       // Uncheck all others
    228       foreach (var tb in dimensionTrackbars.Except(new[] { trackBarSender }))
    229         tb.Checked = false;
    230       RedrawChart();
     152    private void trackbar_LimitsChanged(object sender, EventArgs e) {
     153      // Todo adapt bounds
    231154    }
    232155
    233     private void DimensionTrackbar_LimitsChanged(object sender, EventArgs e) {
    234       RedrawChart();
    235     }
    236 
    237     private void DimensionTrackbar_ValueChanged(object sender, EventArgs e) {
    238       RedrawChart();
     156    private void trackbar_ValueChanged(object sender, EventArgs e) {
     157      var trackBar = sender as DensityTrackbar;
     158      if (trackBar == null) return;
     159      sharedFixedVariables.SetVariableValue((double)trackBar.Value, variableNames[trackbars.IndexOf(trackBar)], 0);
     160      gradientChart.UpdateChart();
    239161    }
    240162
    241163    #region Events
    242 
    243164    protected override void RegisterContentEvents() {
    244165      base.RegisterContentEvents();
     
    256177      base.OnContentChanged();
    257178      UpdateConfigurationControls();
    258       RedrawChart();
    259179    }
    260180
    261181    private void Content_ModelChanged(object sender, EventArgs e) {
    262       RedrawChart();
     182      UpdateConfigurationControls();
    263183    }
    264184
    265185    private void Content_ProblemDataChanged(object sender, EventArgs e) {
    266186      UpdateConfigurationControls();
    267       RedrawChart();
    268187    }
    269 
    270     private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
    271       var result = chart.HitTest(e.X, e.Y);
    272       if (true || result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea ||
    273                                                result.ChartElementType == ChartElementType.Gridlines) ||
    274           result.ChartElementType == ChartElementType.StripLines) {
    275         foreach (var axis in result.ChartArea.Axes)
    276           axis.ScaleView.ZoomReset(int.MaxValue);
    277       }
    278     }
    279 
    280     private void chart_MouseMove(object sender, MouseEventArgs e) {
    281       //HitTestResult result = chart.HitTest(e.X, e.Y);
    282       //if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME)
    283       //  Cursor = Cursors.Hand;
    284       //else
    285       //  Cursor = Cursors.Default;
    286     }
    287 
    288     private void chart_MouseDown(object sender, MouseEventArgs e) {
    289       //HitTestResult result = chart.HitTest(e.X, e.Y);
    290       //if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME) {
    291       //  ToggleSeriesData(result.Series);
    292       //}
    293     }
    294 
    295     private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
    296       //if (chart.Series.Count != 4) return;
    297       //e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[EstimatedMeanSeriesName].Points.Count == 0 ? Color.Gray : Color.Black;
    298       //e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
    299       //e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
    300       //e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
    301     }
    302 
    303188    #endregion
    304 
    305     #region Helper
    306 
    307     private double GetLowerConfBound(double m, double s2) {
    308       return m - 1.96 * Math.Sqrt(s2);
    309     }
    310 
    311     private double GetUpperConfBound(double m, double s2) {
    312       return m + 1.96 * Math.Sqrt(s2);
    313     }
    314189
    315190    public static void ForEach<T>(IEnumerable<T> source, Action<T> action) {
     
    317192        action(item);
    318193    }
    319 
    320     #endregion
    321194  }
    322195}
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionTargetResponseGradientView.cs

    r13828 r13831  
    2626using HeuristicLab.Common;
    2727using HeuristicLab.MainForm;
    28 using HeuristicLab.MainForm.WindowsForms;
    2928
    3029namespace HeuristicLab.Problems.DataAnalysis.Views {
     
    3231  [Content(typeof(IRegressionSolution))]
    3332  public partial class RegressionSolutionTargetResponseGradientView : DataAnalysisSolutionEvaluationView {
    34     private Dictionary<string, GradientChart> charts;
    35     private const int Points = 1000;
     33    private readonly Dictionary<string, GradientChart> charts;
     34    private const int Points = 200;
    3635
    3736    public RegressionSolutionTargetResponseGradientView() {
    3837      InitializeComponent();
     38      charts = new Dictionary<string, GradientChart>();
    3939    }
    4040
    4141    public new IRegressionSolution Content {
    4242      get { return (IRegressionSolution)base.Content; }
    43       set {
    44         if (value == null || value == Content) return;
    45         base.Content = value;
    46       }
     43      set { base.Content = value; }
    4744    }
    4845
     
    6057      base.OnContentChanged();
    6158      if (Content == null) return;
    62       var pd = Content.ProblemData;
    63       var ds = pd.Dataset;
     59      var problemData = Content.ProblemData;
    6460      // create dataset
    6561      var variableNames = Content.GetUsedVariablesForPrediction().ToList();
    66       var variableValues = variableNames.Select(x => new List<double> { pd.Dataset.GetDoubleValues(x, pd.TrainingIndices).Median() });
    67       var dataset = new ModifiableDataset(variableNames, variableValues);
     62      var variableValues = variableNames.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
     63      var sharedFixedVariables = new ModifiableDataset(variableNames, variableValues);
    6864      // create charts
    69       charts = new Dictionary<string, GradientChart>();
    70       foreach (var x in variableNames) {
    71         double min = 0, max = 0;
    72         foreach (var v in ds.GetDoubleValues(x, pd.TrainingIndices)) {
    73           if (v > max) max = v;
    74           if (v < min) min = v;
    75         }
     65      charts.Clear();
     66      foreach (var variableName in variableNames) {
    7667        var gradientChart = new GradientChart {
    7768          Dock = DockStyle.Fill,
     
    8071          ShowCursor = true,
    8172          ShowXAxisLabel = true,
    82           ShowYAxisLabel = true
     73          ShowYAxisLabel = true,
    8374        };
    8475        gradientChart.VariableValueChanged += (o, e) => {
     
    8879          }
    8980        };
    90         gradientChart.Configure(new[] { Content }, pd, dataset, x, min, max, Points);
    91         charts[x] = gradientChart;
     81        gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableName, Points);
     82        charts[variableName] = gradientChart;
    9283      }
    9384      // update variable list
     
    10192      var indices = variableListView.CheckedItems.Cast<ListViewItem>().ToDictionary(checkedItem => checkedItem.Text, checkedItem => checkedItem.Index);
    10293      var count = tl.Controls.Count;
    103       var controls = new GradientChart[count];
    104       for (int i = 0; i < count; ++i) controls[i] = (GradientChart)tl.Controls[i];
    105       Array.Sort(controls, (a, b) => indices[a.Variable].CompareTo(indices[b.Variable]));
     94      var charts = new GradientChart[count];
     95      for (int i = 0; i < count; ++i) charts[i] = (GradientChart)tl.Controls[i];
     96      Array.Sort(charts, (a, b) => indices[a.FreeVariable].CompareTo(indices[b.FreeVariable]));
    10697      tl.Controls.Clear();
    107       tl.Controls.AddRange(controls);
     98      tl.Controls.AddRange(charts);
    10899    }
    109100
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs

    r12012 r13831  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    111111    protected override void DeregisterItemEvents(IEnumerable<IResult> items) { }
    112112
     113    public virtual IEnumerable<string> GetUsedVariablesForPrediction() {
     114      return this.ProblemData.AllowedInputVariables;
     115    }
     116
    113117    #region INamedItem Members
    114118    [Storable]
  • branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs

    r12012 r13831  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using HeuristicLab.Common;
    2425using HeuristicLab.Core;
     
    2829    IDataAnalysisModel Model { get; }
    2930    IDataAnalysisProblemData ProblemData { get; set; }
     31    IEnumerable<string> GetUsedVariablesForPrediction();
    3032
    3133    event EventHandler ModelChanged;
Note: See TracChangeset for help on using the changeset viewer.