Free cookie consent management tool by TermsFeed Policy Generator

Changeset 571


Ignore:
Timestamp:
09/14/08 21:18:30 (16 years ago)
Author:
gkronber
Message:

implemented basic histogram (without 'brushing'). #271 (Functionality to show frequency distribution of any variable (histograms))

Location:
trunk/sources/HeuristicLab.CEDMA.Charting
Files:
3 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.CEDMA.Charting/BubbleChartControl.cs

    r569 r571  
    108108    private void pictureBox_MouseMove(object sender, MouseEventArgs e) {
    109109      toolTip.SetToolTip(pictureBox, Chart.GetToolTipText(e.Location));
    110       Cursor cursor = Chart.GetCursor(e.Location);
    111       if(cursor != null) pictureBox.Cursor = cursor;
    112       else pictureBox.Cursor = Cursors.Default;
    113 
    114110      if(e.Button != MouseButtons.None) {
    115111        if((Chart.Mode == ChartMode.Zoom || Chart.Mode == ChartMode.Select) && (e.Button == MouseButtons.Left)) {
  • trunk/sources/HeuristicLab.CEDMA.Charting/HeuristicLab.CEDMA.Charting.csproj

    r567 r571  
    7373      <DependentUpon>BubbleChartControl.cs</DependentUpon>
    7474    </Compile>
     75    <Compile Include="Histogram.cs" />
     76    <Compile Include="HistogramControl.cs">
     77      <SubType>UserControl</SubType>
     78    </Compile>
     79    <Compile Include="HistogramControl.Designer.cs">
     80      <DependentUpon>HistogramControl.cs</DependentUpon>
     81    </Compile>
    7582    <Compile Include="ModelView.cs">
    7683      <SubType>UserControl</SubType>
     
    8188    <Compile Include="Record.cs" />
    8289    <Compile Include="HeuristicLabCedmaChartingPlugin.cs" />
    83     <Compile Include="Histogram.cs" />
    8490    <Compile Include="Properties\AssemblyInfo.cs" />
    8591    <Compile Include="ResultList.cs" />
     
    138144      <SubType>Designer</SubType>
    139145    </EmbeddedResource>
     146    <EmbeddedResource Include="HistogramControl.resx">
     147      <DependentUpon>HistogramControl.cs</DependentUpon>
     148      <SubType>Designer</SubType>
     149    </EmbeddedResource>
    140150    <EmbeddedResource Include="ModelView.resx">
    141151      <DependentUpon>ModelView.cs</DependentUpon>
  • trunk/sources/HeuristicLab.CEDMA.Charting/Histogram.cs

    r560 r571  
    1 #region License Information
     1#region License Information
    22/* HeuristicLab
    33 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     
    2222using System;
    2323using System.Collections.Generic;
     24using System.Text;
     25using System.Drawing;
    2426using System.Linq;
    25 using System.Text;
    26 using HeuristicLab.Core;
    27 using System.Xml;
    28 using HeuristicLab.CEDMA.DB.Interfaces;
     27using HeuristicLab.Charting;
     28using System.Windows.Forms;
    2929
    3030namespace HeuristicLab.CEDMA.Charting {
    31   public class Histogram {
    32     private int buckets;
    33     public int Buckets {
    34       get { return buckets; }
    35       set {
    36         buckets = value;
    37         ResetBucketBounds();
     31  public class Histogram : Chart {
     32    private static readonly Color defaultColor = Color.Blue;
     33    private static readonly Color selectionColor = Color.Red;
     34
     35    private double minX;
     36    private double maxX;
     37    private double maxFrequency;
     38    private const int N_BUCKETS = 50;
     39    private List<Record> records;
     40    private ResultList results;
     41    private Dictionary<IPrimitive, List<Record>> primitiveToRecordsDictionary;
     42    private Dictionary<Record, IPrimitive> recordToPrimitiveDictionary;
     43    private Group bars;
     44    private double[] limits;
     45    private int[] buckets;
     46    private string dimension;
     47
     48    public Histogram(ResultList results, double x1, double y1, double x2, double y2)
     49      : this(results, new PointD(x1, y1), new PointD(x2, y2)) {
     50    }
     51
     52    public Histogram(ResultList results, PointD lowerLeft, PointD upperRight)
     53      : base(lowerLeft, upperRight) {
     54      records = new List<Record>();
     55      primitiveToRecordsDictionary = new Dictionary<IPrimitive, List<Record>>();
     56      recordToPrimitiveDictionary = new Dictionary<Record, IPrimitive>();
     57      this.results = results;
     58      foreach(Record r in results.Records) {
     59        records.Add(r);
     60        r.OnSelectionChanged += new EventHandler(Record_OnSelectionChanged);
     61      }
     62      results.OnRecordAdded += new EventHandler<RecordAddedEventArgs>(results_OnRecordAdded);
     63      results.Changed += new EventHandler(results_Changed);
     64      limits = new double[N_BUCKETS - 1];
     65      buckets = new int[N_BUCKETS];
     66    }
     67
     68    void results_Changed(object sender, EventArgs e) {
     69      Repaint();
     70      EnforceUpdate();
     71    }
     72
     73    void results_OnRecordAdded(object sender, RecordAddedEventArgs e) {
     74      lock(records) {
     75        e.Record.OnSelectionChanged += new EventHandler(Record_OnSelectionChanged);
     76        records.Add(e.Record);
    3877      }
    3978    }
    4079
    41     private double[] limit;
    42 
    43     private List<double> values;
    44 
    45     public Histogram(int buckets) {
    46       this.buckets = buckets;
    47       values = new List<double>();
     80    void Record_OnSelectionChanged(object sender, EventArgs e) {
     81      Record r = (Record)sender;
     82      IPrimitive primitive;
     83      recordToPrimitiveDictionary.TryGetValue(r, out primitive);
     84      if(primitive != null) {
     85        ((FixedSizeCircle)primitive).UpdateEnabled = false;
     86        bars.UpdateEnabled = false;
     87        if(r.Selected) {
     88          int alpha = primitive.Pen.Color.A;
     89          primitive.Pen.Color = Color.FromArgb(alpha, selectionColor);
     90          primitive.Brush = primitive.Pen.Brush;
     91          primitive.IntoForeground();
     92        } else {
     93          int alpha = primitive.Pen.Color.A;
     94          primitive.Pen.Color = Color.FromArgb(alpha, defaultColor);
     95          primitive.Brush = primitive.Pen.Brush;
     96          primitive.IntoBackground();
     97        }
     98        ((FixedSizeCircle)primitive).UpdateEnabled = true;
     99        bars.UpdateEnabled = true;
     100      }
    48101    }
    49102
    50     public double LowerValue(int bucketIndex) {
    51       return limit[bucketIndex];
     103    public void ShowFrequency(string dimension) {
     104      if(this.dimension != dimension) {
     105        this.dimension = dimension;
     106        ResetViewSize();
     107        Repaint();
     108        ZoomToViewSize();
     109      }
    52110    }
    53111
    54     public double UpperValue(int bucketIndex) {
    55       return limit[bucketIndex+1];
     112    private void Repaint() {
     113      if(dimension == null) return;
     114      UpdateEnabled = false;
     115      Group.Clear();
     116      primitiveToRecordsDictionary.Clear();
     117      recordToPrimitiveDictionary.Clear();
     118      bars = new Group(this);
     119      Group.Add(new Axis(this, 0, 0, AxisType.Both));
     120      UpdateViewSize(0, 0);
     121      var values = records.Select(r => r.Get(dimension)).Where(
     122        x => !double.IsNaN(x) && !double.IsInfinity(x) && x != double.MinValue && x != double.MaxValue).OrderBy(x => x);
     123      IEnumerable<IGrouping<double,double>> frequencies;
     124      double bucketSize;
     125      if(dimension == Record.TARGET_VARIABLE || dimension == Record.TREE_HEIGHT || dimension == Record.TREE_SIZE) {
     126        frequencies = values.GroupBy(x => x);
     127        bucketSize = 1.0;
     128      } else {
     129        double min = values.ElementAt((int)(values.Count() * 0.05));
     130        double max = values.ElementAt((int)(values.Count() * 0.95));
     131        bucketSize = (max - min) / N_BUCKETS;
     132        frequencies = values.GroupBy(x => Math.Min(Math.Max(min, Math.Floor((x - min) / bucketSize) * bucketSize + min), max));
     133      }
     134      Pen defaultPen = new Pen(defaultColor);
     135      Brush defaultBrush = defaultPen.Brush;
     136      foreach(IGrouping<double, double> g in frequencies) {
     137        double freq = g.Count();
     138        double lower = g.Key;
     139        double upper = g.Key+bucketSize;
     140        HeuristicLab.Charting.Rectangle bar = new HeuristicLab.Charting.Rectangle(this, lower, 0, upper, freq, defaultPen, defaultBrush);
     141        primitiveToRecordsDictionary[bar] = records;
     142        if(lower == frequencies.First().Key) bar.ToolTipText = " x < "+upper+" : "+freq;
     143        else if(lower ==frequencies.Last().Key) bar.ToolTipText = "x >= "+lower+" : "+freq;
     144        else bar.ToolTipText = "x in ["+lower+" .. "+upper+"[ : "+freq;
     145        bars.Add(bar);
     146        UpdateViewSize(lower, freq);
     147        UpdateViewSize(upper, freq);
     148      }
     149      Group.Add(bars);
     150      UpdateEnabled = true;
    56151    }
    57152
    58     public int Frequency(int bucketIndex) {
    59       return values.Count(x => x >= LowerValue(bucketIndex) && x < UpperValue(bucketIndex));
     153    private void ZoomToViewSize() {
     154      if(minX < maxX) {
     155        // enlarge view by 5% on each side
     156        double width = maxX - minX;
     157        minX = minX - width * 0.05;
     158        maxX = maxX + width * 0.05;
     159        double minY = 0 - maxFrequency * 0.05;
     160        double maxY = maxFrequency + maxFrequency * 0.05;
     161        ZoomIn(minX, minY, maxX, maxY);
     162      }
    60163    }
    61164
    62     public void AddValues(IEnumerable<double> xs) {
    63       values.AddRange(xs.Where(x=>
    64         !double.IsInfinity(x) && !double.IsNaN(x) && double.MaxValue!=x && double.MinValue !=x));
    65       ResetBucketBounds();
     165    private void UpdateViewSize(double x, double freq) {
     166      if(x < minX) minX = x;
     167      if(x > maxX) maxX = x;
     168      if(freq  > maxFrequency) maxFrequency = freq;
    66169    }
    67170
    68     private void ResetBucketBounds() {
    69       limit = new double[buckets+1];
    70       values.Sort();
    71       double min = values[10];
    72       double max = values[values.Count-10];
     171    private void ResetViewSize() {
     172      minX = double.PositiveInfinity;
     173      maxX = double.NegativeInfinity;
     174      maxFrequency = double.NegativeInfinity;
     175    }
    73176
    74       double step = (max - min) / buckets;
    75       double cur = min;
    76       for(int i = 0; i < buckets+1; i++) {
    77         limit[i] = cur;
    78         cur += step;
     177    internal List<Record> GetRecords(Point point) {
     178      List<Record> records = null;
     179      IPrimitive p = bars.GetPrimitive(TransformPixelToWorld(point));
     180      if(p != null) {
     181        primitiveToRecordsDictionary.TryGetValue(p, out records);
     182      }
     183      return records;
     184    }
     185
     186    public override void MouseClick(Point point, MouseButtons button) {
     187      if(button == MouseButtons.Left) {
     188        List<Record> rs = GetRecords(point);
     189        if(rs != null) rs.ForEach(r => r.ToggleSelected());
     190        results.FireChanged();
     191      } else {
     192        base.MouseClick(point, button);
    79193      }
    80194    }
  • trunk/sources/HeuristicLab.CEDMA.Charting/ResultListView.Designer.cs

    r561 r571  
    3232      this.yAxisComboBox = new System.Windows.Forms.ComboBox();
    3333      this.yTrackBar = new System.Windows.Forms.TrackBar();
    34       this.dataChart = new HeuristicLab.CEDMA.Charting.BubbleChartControl();
    3534      this.sizeComboBox = new System.Windows.Forms.ComboBox();
    3635      this.sizeLabel = new System.Windows.Forms.Label();
    3736      this.invertCheckbox = new System.Windows.Forms.CheckBox();
     37      this.chartPanel = new System.Windows.Forms.Panel();
    3838      ((System.ComponentModel.ISupportInitialize)(this.xTrackBar)).BeginInit();
    3939      ((System.ComponentModel.ISupportInitialize)(this.yTrackBar)).BeginInit();
     
    117117      this.yTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
    118118      this.yTrackBar.ValueChanged += new System.EventHandler(this.jitterTrackBar_ValueChanged);
    119       //
    120       // dataChart
    121       //
    122       this.dataChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    123                   | System.Windows.Forms.AnchorStyles.Left)
    124                   | System.Windows.Forms.AnchorStyles.Right)));
    125       this.dataChart.BackColor = System.Drawing.SystemColors.Control;
    126       this.dataChart.Chart = null;
    127       this.dataChart.Location = new System.Drawing.Point(3, 81);
    128       this.dataChart.Name = "dataChart";
    129       this.dataChart.ScaleOnResize = true;
    130       this.dataChart.Size = new System.Drawing.Size(447, 304);
    131       this.dataChart.TabIndex = 9;
    132119      //
    133120      // sizeComboBox
     
    164151      this.invertCheckbox.CheckedChanged += new System.EventHandler(this.sizeComboBox_SelectedIndexChanged);
    165152      //
     153      // chartPanel
     154      //
     155      this.chartPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
     156                  | System.Windows.Forms.AnchorStyles.Left)
     157                  | System.Windows.Forms.AnchorStyles.Right)));
     158      this.chartPanel.Location = new System.Drawing.Point(0, 81);
     159      this.chartPanel.Name = "chartPanel";
     160      this.chartPanel.Size = new System.Drawing.Size(447, 304);
     161      this.chartPanel.TabIndex = 17;
     162      //
    166163      // ResultListView
    167164      //
    168165      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    169166      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
     167      this.Controls.Add(this.chartPanel);
    170168      this.Controls.Add(this.invertCheckbox);
    171169      this.Controls.Add(this.sizeLabel);
    172170      this.Controls.Add(this.sizeComboBox);
    173       this.Controls.Add(this.dataChart);
    174171      this.Controls.Add(this.yJitterLabel);
    175172      this.Controls.Add(this.xJitterlabel);
     
    191188    #endregion
    192189
    193     private BubbleChartControl dataChart;
    194190    private System.Windows.Forms.Label xAxisLabel;
    195191    private System.Windows.Forms.ComboBox xAxisComboBox;
     
    203199    private System.Windows.Forms.Label sizeLabel;
    204200    private System.Windows.Forms.CheckBox invertCheckbox;
     201    private System.Windows.Forms.Panel chartPanel;
    205202  }
    206203}
  • trunk/sources/HeuristicLab.CEDMA.Charting/ResultListView.cs

    r567 r571  
    1515    private const string FREQUENCY = "<Frequency>";
    1616    private const string CONSTANT_SIZE = "<constant>";
     17    private BubbleChartControl bubbleChartControl;
     18    private HistogramControl histogramControl;
     19    private Label pleaseSelectAxisLabel = new Label();
    1720
    1821    public ResultListView(ResultList results) {
    1922      this.results = results;
    2023      InitializeComponent();
     24      InitCharts();
    2125      xAxisComboBox.Items.AddRange(results.VariableNames);
    2226      yAxisComboBox.Items.Add(FREQUENCY);
     
    2529      sizeComboBox.Items.AddRange(results.VariableNames);
    2630      sizeComboBox.SelectedItem = sizeComboBox.Items[0];
    27       InitChart();
     31      sizeComboBox.Enabled = false;
     32      invertCheckbox.Enabled = false;
     33      sizeLabel.Enabled = false;
     34      yAxisComboBox.SelectedItem = yAxisComboBox.Items[0];
     35      xAxisComboBox.SelectedItem = xAxisComboBox.Items[0];
    2836    }
    2937
    30     private void InitChart() {
    31       dataChart.Chart = new BubbleChart(results, 0, 0, 100, 100);
     38    private void InitCharts() {
     39      bubbleChartControl = new BubbleChartControl();
     40      bubbleChartControl.Chart = new BubbleChart(results, 0, 0, 100, 100);
     41      histogramControl = new HistogramControl();
     42      histogramControl.Chart = new Histogram(results, 0, 0, 100, 100);
    3243    }
    3344
     
    4354      if(xAxisComboBox.SelectedItem == null || yAxisComboBox.SelectedItem == null) return;
    4455      if(yAxisComboBox.SelectedItem.Equals(FREQUENCY)) {
    45         CreateHistogramChart();
     56        xJitterlabel.Enabled = false;
     57        xTrackBar.Enabled = false;
     58        yJitterLabel.Enabled = false;
     59        yTrackBar.Enabled = false;
     60        sizeComboBox.Enabled = false;
     61        invertCheckbox.Enabled = false;
     62        sizeLabel.Enabled = false;
     63        chartPanel.Controls.Clear();
     64        chartPanel.Controls.Add(histogramControl);
     65        histogramControl.Chart.ShowFrequency((string)xAxisComboBox.SelectedItem);
     66        histogramControl.Dock = DockStyle.Fill;
    4667      } else {
    47         dataChart.Chart.ShowXvsY((string)xAxisComboBox.SelectedItem, (string)yAxisComboBox.SelectedItem);
     68        xJitterlabel.Enabled = true;
     69        xTrackBar.Enabled = true;
     70        yJitterLabel.Enabled = true;
     71        yTrackBar.Enabled = true;
     72        sizeComboBox.Enabled = true;
     73        invertCheckbox.Enabled = true;
     74        sizeLabel.Enabled = true;
     75        chartPanel.Controls.Clear();
     76        chartPanel.Controls.Add(bubbleChartControl);
     77        bubbleChartControl.Chart.ShowXvsY((string)xAxisComboBox.SelectedItem, (string)yAxisComboBox.SelectedItem);
     78        bubbleChartControl.Dock = DockStyle.Fill;
    4879      }
    4980    }
    5081
    51     private void CreateHistogramChart() {
    52       // TASK
    53     }
    54 
    5582    private void jitterTrackBar_ValueChanged(object sender, EventArgs e) {
    56       if(dataChart.Chart != null) {
     83      if(bubbleChartControl.Chart != null) {
    5784        double xJitterFactor = xTrackBar.Value / 100.0;
    5885        double yJitterFactor = yTrackBar.Value / 100.0;
    59         dataChart.Chart.SetJitter(xJitterFactor, yJitterFactor);
     86        bubbleChartControl.Chart.SetJitter(xJitterFactor, yJitterFactor);
    6087      }
    6188      UpdateChart();
     
    6390
    6491    private void sizeComboBox_SelectedIndexChanged(object sender, EventArgs e) {
    65       if(dataChart.Chart != null) {
    66         dataChart.Chart.SetBubbleSizeDimension((string)sizeComboBox.SelectedItem, invertCheckbox.Checked);
     92      if(bubbleChartControl.Chart != null) {
     93        bubbleChartControl.Chart.SetBubbleSizeDimension((string)sizeComboBox.SelectedItem, invertCheckbox.Checked);
    6794        UpdateChart();
    6895      }
Note: See TracChangeset for help on using the changeset viewer.