#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using HeuristicLab.BioBoost.Representation;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Core.Views;
using HeuristicLab.MainForm;
using HeuristicLab.PluginInfrastructure;
namespace HeuristicLab.BioBoost.Views {
[Content(typeof (ItemCollection), false)]
public partial class BioBoostParetoSetView : ItemView {
private Point mouseDownPos;
public new ItemCollection Content {
get { return (ItemCollection)base.Content; }
set { base.Content = value; }
}
public BioBoostParetoSetView() {
InitializeComponent();
}
protected override void RegisterContentEvents() {
base.RegisterContentEvents();
Content.ItemsAdded += UpdateChart;
Content.ItemsRemoved += UpdateChart;
Content.CollectionReset += UpdateChart;
}
protected override void DeregisterContentEvents() {
base.DeregisterContentEvents();
Content.CollectionReset -= UpdateChart;
Content.ItemsRemoved -= UpdateChart;
Content.CollectionReset -= UpdateChart;
}
protected override void OnContentChanged() {
base.OnContentChanged();
UpdateChart(this, EventArgs.Empty);
}
protected virtual void UpdateChart(object sender, EventArgs args) {
if (InvokeRequired) {
Invoke(new EventHandler(UpdateChart), sender, args);
} else {
try {
if (paretoSetChart.IsDisposed) return;
var points = paretoSetChart.Series[0].Points;
if (Content == null) {
points.Clear();
return;
}
var newPoints = Content.Where(solution => solution.Qualities.Length >= 2).Select(s => new { x = s.Qualities[0], y = s.Qualities[1], solution = s}).ToList();
if (newPoints.Count > 0) {
var chartArea = paretoSetChart.ChartAreas[0];
AdaptAxis(chartArea.AxisX, newPoints.Select(p => p.x), 1);
AdaptAxis(chartArea.AxisY, newPoints.Select(p => p.y), 1);
paretoSetChart.BeginInit();
points.Clear();
foreach (var point in newPoints) {
points.Add(new DataPoint(point.x, point.y) {
Tag = point.solution,
});
}
paretoSetChart.EndInit();
}
} catch (Exception x) {
ErrorHandling.ShowErrorDialog(x);
}
}
}
private void AdaptAxis(Axis axis, IEnumerable values, int precision = 0, double overshot = 0.5, double margin = 0.25) {
var newMax = values.Max();
var newMin = values.Min();
var range = newMax - newMin;
newMax = newMax + range*margin;
newMin = newMin - range*margin;
if (range == 0) return;
var oldRange = axis.Maximum - axis.Minimum;
if (range*3 < oldRange) {
axis.Maximum = Math.Round(newMax+range*overshot, precision);
axis.Minimum = Math.Round(newMin-range*overshot , precision);
} else {
if (newMax > axis.Maximum) axis.Maximum = Math.Round(newMax+range*overshot, precision);
if (newMin < axis.Minimum) axis.Minimum = Math.Round(newMin-range*overshot, precision);
}
}
private void paretoSetChart_MouseDown(object sender, MouseEventArgs e) { mouseDownPos = e.Location; }
private void paretoSetChart_DoubleClick(object sender, EventArgs e) {
var pos = mouseDownPos;
var result = paretoSetChart.HitTest(pos.X, pos.Y, ChartElementType.DataPoint);
var point = result.Object as DataPoint;
if (point != null && point.Tag is IContent)
MainFormManager.MainForm.ShowContent((IContent)point.Tag);
}
}
}