#region License Information /* HeuristicLab * Copyright (C) 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.Windows.Forms; using HeuristicLab.MainForm; namespace HeuristicLab.Problems.Knapsack.Views { /// /// A view for a Knapsack solution. /// [View("Knapsack View")] [Content(typeof(KnapsackSolution), true)] public partial class KnapsackSolutionView : HeuristicLab.Core.Views.ItemView { public new KnapsackSolution Content { get { return (KnapsackSolution)base.Content; } set { base.Content = value; } } public KnapsackSolutionView() { InitializeComponent(); } protected override void DeregisterContentEvents() { Content.BinaryVectorChanged -= new EventHandler(Content_BinaryVectorChanged); Content.CapacityChanged -= new EventHandler(Content_CapacityChanged); Content.WeightsChanged -= new EventHandler(Content_WeightsChanged); Content.ValuesChanged -= new EventHandler(Content_ValuesChanged); Content.QualityChanged -= new EventHandler(Content_QualityChanged); base.DeregisterContentEvents(); } protected override void RegisterContentEvents() { base.RegisterContentEvents(); Content.BinaryVectorChanged += new EventHandler(Content_BinaryVectorChanged); Content.CapacityChanged += new EventHandler(Content_CapacityChanged); Content.WeightsChanged += new EventHandler(Content_WeightsChanged); Content.ValuesChanged += new EventHandler(Content_ValuesChanged); Content.QualityChanged += new EventHandler(Content_QualityChanged); } private void Content_BinaryVectorChanged(object sender, EventArgs e) { if (InvokeRequired) Invoke(new EventHandler(Content_BinaryVectorChanged), sender, e); else GenerateImage(); } private void Content_QualityChanged(object sender, EventArgs e) { if (InvokeRequired) Invoke(new EventHandler(Content_QualityChanged), sender, e); else GenerateImage(); } private void Content_CapacityChanged(object sender, EventArgs e) { if (InvokeRequired) Invoke(new EventHandler(Content_CapacityChanged), sender, e); else GenerateImage(); } private void Content_WeightsChanged(object sender, EventArgs e) { if (InvokeRequired) Invoke(new EventHandler(Content_WeightsChanged), sender, e); else GenerateImage(); } private void Content_ValuesChanged(object sender, EventArgs e) { if (InvokeRequired) Invoke(new EventHandler(Content_ValuesChanged), sender, e); else GenerateImage(); } protected override void OnContentChanged() { base.OnContentChanged(); if (Content == null) pictureBox.Image = null; else GenerateImage(); } protected override void SetEnabledStateOfControls() { base.SetEnabledStateOfControls(); pictureBox.Enabled = Content != null; } private void GenerateImage() { if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) { if (Content == null) { pictureBox.Image = null; } else { Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height); using (Graphics graphics = Graphics.FromImage(bitmap)) { int border = 10; int borderX = border; if (pictureBox.Width - border * 2 < 0) borderX = 0; int width = pictureBox.Width - borderX * 2; int borderY = border; if (pictureBox.Height - border * 2 < 0) borderY = 0; int height = pictureBox.Height - borderY * 2; //preprocess double capacity = Content.Capacity.Value; if (capacity != 0) { double packedCapacity = 0; double maxValue = 0; for (int i = 0; i < Content.BinaryVector.Length; i++) { if (Content.BinaryVector[i]) { packedCapacity += Content.Weights[i]; } if (Content.Values[i] > maxValue) maxValue = Content.Values[i]; } int knapsackHeight = height; if (packedCapacity > capacity) { knapsackHeight = (int)Math.Round(capacity / packedCapacity * (double)height); } //draw knapsack using (Pen pen = new Pen(Color.Black, 2)) { graphics.DrawRectangle(pen, borderX - 2, pictureBox.Height - borderY - knapsackHeight - 2, width + 4, knapsackHeight + 4); } //draw items sorted by value List sortedIndices = new List(); for (int i = 0; i < Content.BinaryVector.Length; i++) { if (Content.BinaryVector[i]) { sortedIndices.Add(i); } } sortedIndices.Sort( delegate(int i, int j) { if (Content.Values[i] < Content.Values[j]) return -1; else if (Content.Values[i] > Content.Values[j]) return 1; else return 0; }); int currentPosition = pictureBox.Height - borderY; foreach (int i in sortedIndices) { if (Content.BinaryVector[i]) { double weight = Content.Weights[i]; double factor = weight / capacity; int elementHeight = (int)Math.Floor(knapsackHeight * factor); double value = Content.Values[i]; //color according to value int colorValue = 0; if (value != 0) colorValue = (int)Math.Round(255.0 * value / maxValue); Color color = Color.FromArgb( 0, 0, colorValue); using (Brush brush = new SolidBrush(color)) { graphics.FillRectangle(brush, borderX, currentPosition - elementHeight, width, elementHeight); } graphics.DrawRectangle(Pens.White, borderX, currentPosition - elementHeight, width, elementHeight); currentPosition -= elementHeight; } } } } pictureBox.Image = bitmap; } } } private void pictureBox_SizeChanged(object sender, EventArgs e) { GenerateImage(); } } }