Ignore:
Timestamp:
04/04/17 17:52:44 (6 months ago)
Author:
gkronber
Message:

#2650: merged the factors branch into trunk

Location:
trunk/sources
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources

  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Views

  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionTargetResponseGradientView.cs

    r14464 r14826  
    2121
    2222using System;
     23using System.Collections;
    2324using System.Collections.Generic;
    2425using System.Drawing;
     
    3536  [Content(typeof(IRegressionSolution))]
    3637  public partial class RegressionSolutionTargetResponseGradientView : DataAnalysisSolutionEvaluationView {
    37     private readonly Dictionary<string, GradientChart> gradientCharts;
     38    private readonly Dictionary<string, IGradientChart> gradientCharts;
    3839    private readonly Dictionary<string, DensityChart> densityCharts;
    3940    private readonly Dictionary<string, Panel> groupingPanels;
     
    4950      }
    5051    }
    51     private IEnumerable<GradientChart> VisibleGradientCharts {
     52    private IEnumerable<IGradientChart> VisibleGradientCharts {
    5253      get { return VisibleVariables.Select(v => gradientCharts[v]); }
    5354    }
     
    6162    public RegressionSolutionTargetResponseGradientView() {
    6263      InitializeComponent();
    63       gradientCharts = new Dictionary<string, GradientChart>();
     64      gradientCharts = new Dictionary<string, IGradientChart>();
    6465      densityCharts = new Dictionary<string, DensityChart>();
    6566      groupingPanels = new Dictionary<string, Panel>();
     
    120121
    121122
    122       var variableValues = allowedInputVariables.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
     123      var doubleVariables = allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>);
     124      var doubleVariableValues = (IEnumerable<IList>)doubleVariables.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
     125
     126      var factorVariables = allowedInputVariables.Where(problemData.Dataset.VariableHasType<string>);
     127      var factorVariableValues = (IEnumerable<IList>)factorVariables.Select(x => new List<string> {
     128        problemData.Dataset.GetStringValues(x, problemData.TrainingIndices)
     129        .GroupBy(val => val).OrderByDescending(g => g.Count()).First().Key // most frequent value
     130      });
     131
    123132      if (sharedFixedVariables != null)
    124133        sharedFixedVariables.ItemChanged -= SharedFixedVariables_ItemChanged;
    125       sharedFixedVariables = new ModifiableDataset(allowedInputVariables, variableValues);
    126       // ItemChanged eventhandler is registered later, after creating the gradient charts
     134
     135      sharedFixedVariables = new ModifiableDataset(doubleVariables.Concat(factorVariables), doubleVariableValues.Concat(factorVariableValues));
     136
    127137
    128138      // create controls
     
    130140      densityCharts.Clear();
    131141      groupingPanels.Clear();
    132       foreach (var variableName in allowedInputVariables) {
     142      foreach (var variableName in doubleVariables) {
    133143        var gradientChart = CreateGradientChart(variableName, sharedFixedVariables);
    134144        gradientCharts.Add(variableName, gradientChart);
     
    158168        // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...)
    159169        // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting.
    160         gradientChart.ChartPostPaint += OnGradientChartOnChartPostPaint;
     170        gradientChart.ChartPostPaint += OnGradientChartPostPaint;
    161171
    162172        var panel = new Panel() {
     
    170180        groupingPanels.Add(variableName, panel);
    171181      }
    172 
     182      foreach (var variableName in factorVariables) {
     183        var gradientChart = CreateFactorGradientChart(variableName, sharedFixedVariables);
     184        gradientCharts.Add(variableName, gradientChart);
     185
     186        var densityChart = new DensityChart() {
     187          Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right,
     188          Margin = Padding.Empty,
     189          Height = 12,
     190          Visible = false,
     191          Top = (int)(gradientChart.Height * 0.1),
     192        };
     193        densityCharts.Add(variableName, densityChart);
     194        gradientChart.ZoomChanged += (o, e) => {
     195          var gradient = (FactorGradientChart)o;
     196          var density = densityCharts[gradient.FreeVariable];
     197          density.Visible = densityComboBox.SelectedIndex != 0 && !gradient.IsZoomed;
     198          if (density.Visible)
     199            UpdateDensityChart(density, gradient.FreeVariable);
     200        };
     201        gradientChart.SizeChanged += (o, e) => {
     202          var gradient = (FactorGradientChart)o;
     203          var density = densityCharts[gradient.FreeVariable];
     204          density.Top = (int)(gradient.Height * 0.1);
     205        };
     206
     207        // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...)
     208        // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting.
     209        gradientChart.ChartPostPaint += OnFactorGradientChartPostPaint;
     210
     211        var panel = new Panel() {
     212          Dock = DockStyle.Fill,
     213          Margin = Padding.Empty,
     214          BackColor = Color.White
     215        };
     216
     217        panel.Controls.Add(densityChart);
     218        panel.Controls.Add(gradientChart);
     219        groupingPanels.Add(variableName, panel);
     220      }
    173221      // update variable list
    174222      variableListView.ItemChecked -= variableListView_ItemChecked;
     
    196244    }
    197245
    198     private void OnGradientChartOnChartPostPaint(object o, EventArgs e) {
     246
     247    private void OnGradientChartPostPaint(object o, EventArgs e) {
    199248      var gradient = (GradientChart)o;
    200249      var density = densityCharts[gradient.FreeVariable];
     
    209258      // removed after succesful layouting due to performance reasons
    210259      if (gcPlotPosition.Width != 0)
    211         gradient.ChartPostPaint -= OnGradientChartOnChartPostPaint;
     260        gradient.ChartPostPaint -= OnGradientChartPostPaint;
     261    }
     262
     263    private void OnFactorGradientChartPostPaint(object o, EventArgs e) {
     264      var gradient = (FactorGradientChart)o;
     265      var density = densityCharts[gradient.FreeVariable];
     266
     267      density.Width = gradient.Width;
     268
     269      var gcPlotPosition = gradient.InnerPlotPosition;
     270      density.Left = (int)(gcPlotPosition.X / 100.0 * gradient.Width);
     271      density.Width = (int)(gcPlotPosition.Width / 100.0 * gradient.Width);
     272      gradient.UpdateTitlePosition();
     273
     274      // removed after succesful layouting due to performance reasons
     275      if (gcPlotPosition.Width != 0)
     276        gradient.ChartPostPaint -= OnFactorGradientChartPostPaint;
    212277    }
    213278
     
    215280      foreach (var variable in VisibleVariables) {
    216281        var gradientChart = gradientCharts[variable];
    217         await gradientChart.RecalculateAsync();
     282        await gradientChart.RecalculateAsync(false, false);
    218283      }
    219284      gradientChartTableLayout.SuspendLayout();
     
    224289      gradientChartTableLayout.Refresh();
    225290      foreach (var variable in VisibleVariables) {
    226         var densityChart = densityCharts[variable];
    227         UpdateDensityChart(densityChart, variable);
     291        DensityChart densityChart;
     292        if (densityCharts.TryGetValue(variable, out densityChart)) {
     293          UpdateDensityChart(densityChart, variable);
     294        }
    228295      }
    229296    }
     
    238305      };
    239306      gradientChart.VariableValueChanged += async (o, e) => {
    240         var recalculations = VisibleGradientCharts.Except(new[] { (GradientChart)o }).Select(async chart => {
    241           await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
    242         }).ToList();
     307        var recalculations = VisibleGradientCharts
     308          .Except(new[] { (IGradientChart)o })
     309          .Select(async chart => {
     310            await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
     311          }).ToList();
    243312        await Task.WhenAll(recalculations);
    244313
     
    251320      return gradientChart;
    252321    }
    253 
     322    private FactorGradientChart CreateFactorGradientChart(string variableName, ModifiableDataset sharedFixedVariables) {
     323      var gradientChart = new FactorGradientChart {
     324        Dock = DockStyle.Fill,
     325        Margin = Padding.Empty,
     326        ShowLegend = false,
     327        ShowCursor = true,
     328        YAxisTicks = 5,
     329      };
     330      gradientChart.VariableValueChanged += async (o, e) => {
     331        var recalculations = VisibleGradientCharts
     332          .Except(new[] { (FactorGradientChart)o })
     333          .Select(async chart => {
     334            await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
     335          }).ToList();
     336        await Task.WhenAll(recalculations);
     337
     338        if (recalculations.All(t => t.IsCompleted))
     339          SetupYAxis();
     340      };
     341      var variableValues = Content.ProblemData.Dataset.GetStringValues(variableName).Distinct().OrderBy(n => n).ToList();
     342      gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableName, variableValues);
     343      gradientChart.SolutionAdded += gradientChart_SolutionAdded;
     344      gradientChart.SolutionRemoved += gradientChart_SolutionRemoved;
     345      return gradientChart;
     346    }
    254347    private void SetupYAxis() {
    255348      double axisMin, axisMax;
     
    345438      if (item.Checked) {
    346439        tl.Controls.Add(chartsPanel);
    347         await gradientChart.RecalculateAsync();
     440        await gradientChart.RecalculateAsync(false, false);
    348441      } else {
    349442        tl.Controls.Remove(chartsPanel);
     
    409502        indices = GetDensityIndices(densityComboBox.SelectedIndex).ToList();
    410503      }
    411       var data = Content.ProblemData.Dataset.GetDoubleValues(variable, indices).ToList();
    412       var gradientChart = gradientCharts[variable];
    413       var min = gradientChart.FixedXAxisMin;
    414       var max = gradientChart.FixedXAxisMax;
    415       var buckets = gradientChart.DrawingSteps;
    416       if (min.HasValue && max.HasValue) {
    417         densityChart.UpdateChart(data, min.Value, max.Value, buckets);
    418         densityChart.Width = gradientChart.Width;
    419 
    420         var gcPlotPosition = gradientChart.InnerPlotPosition;
    421         densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);
    422         densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);
    423 
    424         densityChart.Visible = true;
    425       }
    426 
    427       gradientChart.UpdateTitlePosition();
     504      if (Content.ProblemData.Dataset.VariableHasType<double>(variable)) {
     505        var data = Content.ProblemData.Dataset.GetDoubleValues(variable, indices).ToList();
     506        var gradientChart = gradientCharts[variable] as GradientChart;
     507        if (gradientChart != null) {
     508          var min = gradientChart.FixedXAxisMin;
     509          var max = gradientChart.FixedXAxisMax;
     510          var buckets = gradientChart.DrawingSteps;
     511          if (min.HasValue && max.HasValue) {
     512            densityChart.UpdateChart(data, min.Value, max.Value, buckets);
     513            densityChart.Width = gradientChart.Width;
     514
     515            var gcPlotPosition = gradientChart.InnerPlotPosition;
     516            densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);
     517            densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);
     518
     519            densityChart.Visible = true;
     520          }
     521          gradientChart.UpdateTitlePosition();
     522        }
     523      } else if (Content.ProblemData.Dataset.VariableHasType<string>(variable)) {
     524        var data = Content.ProblemData.Dataset.GetStringValues(variable).ToList();
     525        var gradientChart = gradientCharts[variable] as FactorGradientChart;
     526        if (gradientChart != null) {
     527          densityChart.UpdateChart(data);
     528          densityChart.Width = gradientChart.Width;
     529
     530          var gcPlotPosition = gradientChart.InnerPlotPosition;
     531          densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);
     532          densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);
     533
     534          densityChart.Visible = true;
     535
     536          gradientChart.UpdateTitlePosition();
     537        }
     538      }
    428539    }
    429540
     
    448559        var densityChart = densityCharts[variable];
    449560        // recalculate and refresh
    450         await gradientChart.RecalculateAsync();
     561        await gradientChart.RecalculateAsync(false, false);
    451562        gradientChart.Refresh();
    452563        UpdateDensityChart(densityChart, variable);
Note: See TracChangeset for help on using the changeset viewer.