using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using HeuristicLab.Core.Views; using HeuristicLab.MainForm; using HeuristicLab.PDPSimulation.DomainModel; using HeuristicLab.MainForm.WindowsForms; using HeuristicLab.Analysis; namespace HeuristicLab.PDPSimulation.Views { [View("VehicleHistoryView")] [Content(typeof(VehicleHistoryVisualization), true)] public partial class VehicleHistoryView : ItemView { public new VehicleHistoryVisualization Content { get { return (VehicleHistoryVisualization)base.Content; } set { base.Content = value; } } public VehicleHistoryView() { InitializeComponent(); } protected override void DeregisterContentEvents() { Content.ContentChanged -= new EventHandler(Content_ContentChanged); base.DeregisterContentEvents(); } protected override void RegisterContentEvents() { base.RegisterContentEvents(); Content.ContentChanged += new EventHandler(Content_ContentChanged); } void Content_ContentChanged(object sender, EventArgs e) { GenerateImage(); } void pictureBox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { GenerateImage(); } } private List GetServicedOrders(VehicleHistory vehicle) { List result = new List(); Order current = null; for (int i = 0; i < vehicle.VehicleState.Count; i++) { current = vehicle.ActiveOrders[i]; if (vehicle.VehicleState[i] == VehicleState.Servicing && !result.Contains(current)) result.Add(current); } return result; } private void GenerateImage() { if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) { VehicleHistoryVisualization content = Content; if (content == null) { pictureBox.Image = null; } else { Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height); using (Graphics graphics = Graphics.FromImage(bitmap)) { IEnumerable vehicles = content.VehicleHistory.Where(v => v.VehicleState.Any(s => s != VehicleState.Parked && s != VehicleState.Waiting)); int vehicleCount = vehicles.Count(); if (vehicleCount > 0) { float width = pictureBox.Width - 1; float height = pictureBox.Height - 1; int orderCount = 0; foreach (VehicleHistory vehicle in vehicles) orderCount += GetServicedOrders(vehicle).Count; int totalRows = vehicleCount * 3 + orderCount; float rowHeight = height / (float)totalRows; int totalColumns = vehicles.First().VehicleState.Count; float columnWidth = width / (float)totalColumns; float timeWidth = columnWidth / (float)content.ResultCollectionInterval; float curY = 0; foreach (VehicleHistory vehicle in vehicles) { float curX = 0; int curAvailability = 1; VehicleState curState = VehicleState.Parked; int counter = 0; for (int i = 0; i <= vehicle.VehicleState.Count; i++) { counter++; int availability = 1; VehicleState state = VehicleState.Parked; if (i < vehicle.VehicleState.Count) { state = vehicle.VehicleState[i]; availability = vehicle.VehicleAvailability[i]; } if (state != curState || availability != curAvailability || (i == vehicle.VehicleState.Count && i != 0)) { float stateWidth = columnWidth * (float)counter; Brush brush = Brushes.White; if (curAvailability <= 0) brush = Brushes.DarkGray; if (curState == VehicleState.Moving) brush = Brushes.Green; else if (curState == VehicleState.Servicing) brush = Brushes.Red; else if (curState == VehicleState.InvalidAction) brush = Brushes.Gray; graphics.FillRectangle(brush, curX, curY, stateWidth, rowHeight); curState = state; curAvailability = availability; counter = 0; curX += stateWidth; } } graphics.DrawRectangle(Pens.Black, 0, curY, width, rowHeight); curY += rowHeight; curY += rowHeight; foreach (Order order in GetServicedOrders(vehicle)) { float begin = Math.Min(pictureBox.Width, (float)order.PickupReadyTime * timeWidth); float end = Math.Min(pictureBox.Width, (float)order.PickupDueTime * timeWidth); graphics.DrawLine(Pens.Blue, begin, curY + rowHeight / 2, end, curY + rowHeight / 2); graphics.DrawLine(Pens.Blue, begin, curY, begin, curY + rowHeight); graphics.DrawLine(Pens.Blue, end, curY, end, curY + rowHeight); if (order.OrderState != OrderState.Waiting) { float pickupTime = Math.Min(width, (float)order.PickupTime * timeWidth); graphics.FillEllipse(Brushes.Blue, pickupTime - rowHeight / 4, curY + rowHeight / 4, rowHeight / 2, rowHeight / 2); } if (!order.ServiceRequest) { begin = Math.Min(pictureBox.Width, (float)order.DeliveryReadyTime * timeWidth); end = Math.Min(pictureBox.Width, (float)order.DeliveryDueTime * timeWidth); graphics.DrawLine(Pens.Green, begin, curY + rowHeight / 2, end, curY + rowHeight / 2); graphics.DrawLine(Pens.Green, begin, curY, begin, curY + rowHeight); graphics.DrawLine(Pens.Green, end, curY, end, curY + rowHeight); if (order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp && order.OrderState != OrderState.PickedUp) { float deliveryTime = Math.Min(width, (float)order.DeliveryTime * timeWidth); graphics.FillEllipse(Brushes.Green, deliveryTime - rowHeight / 4, curY + rowHeight / 4, rowHeight / 2, rowHeight / 2); } } curY += rowHeight; } curY += rowHeight; } } pictureBox.Image = bitmap; } } } } protected override void OnContentChanged() { base.OnContentChanged(); GenerateImage(); } private void VehicleHistoryView_SizeChanged(object sender, EventArgs e) { GenerateImage(); } } }