using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using BCMToolbox; namespace VisualBCM { public partial class NetVisualiser : UserControl { const int MARKER_LENGTH = 5; const double LEGEND_FACTOR = 0.2; BCMToolbox.NetworkState __lastNetworkState = null; BCMToolbox.TraceableNetwork __network = null; Brush __background = null; bool __autoRefresh = false; Bitmap __backgroundBitmap = null; Bitmap __outputBitmap1 = null; Bitmap __outputBitmap2 = null; Color[] __wtPalette = new Color[] { Color.DarkBlue, Color.Blue, Color.Magenta, Color.Red, Color.White, Color.Pink}; Color[] __outPalette = new Color[] { Color.Black, Color.DarkGreen, Color.Green, Color.GreenYellow, Color.Yellow}; //Color[] __palette = new Color[] { Color.Black, Color.White }; double __scaleMin = 0.0; double __scaleMax = 0.0; bool __autoScale = true; public NetVisualiser() { InitializeComponent(); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); __background = new SolidBrush(Color.Black); } #region Binding to Networks public TraceableNetwork BoundNetwork { get { return __network; } set { if (__network != null) Unbind(); if(value != null) BindToNetwork(value); __network_WeightsChanged(this, EventArgs.Empty); } } void Unbind() { __network.WeightsChanged -= new EventHandler(__network_WeightsChanged); __network = null; } void BindToNetwork(BCMToolbox.TraceableNetwork network) { __network = network; __network.WeightsChanged += new EventHandler(__network_WeightsChanged); __backgroundBitmap = new Bitmap(__network.Count, __network.Count, System.Drawing.Imaging.PixelFormat.Format24bppRgb); __outputBitmap1 = new Bitmap(__network.Count, MARKER_LENGTH, System.Drawing.Imaging.PixelFormat.Format24bppRgb); __outputBitmap2 = new Bitmap(MARKER_LENGTH, __network.Count, System.Drawing.Imaging.PixelFormat.Format24bppRgb); } public bool AutoRefresh { get { return __autoRefresh; } set { __autoRefresh = value; } } void __network_WeightsChanged(object sender, EventArgs e) { if (!__autoRefresh) return; if (this.InvokeRequired) this.BeginInvoke( new Action(this.Invalidate)); else this.Invalidate(); } public void RefreshNetwork() { this.Invalidate(); } #endregion #region Painting public void SetAutoScale() { __autoScale = true; Invalidate(); } public void SetManualScale(double minValue, double MaxValue) { __autoScale = false; __scaleMin = minValue; __scaleMax = MaxValue; Invalidate(); } public BCMToolbox.NetworkState LastNetworkState { get { return __lastNetworkState; } } protected override void OnPaint(PaintEventArgs e) { // System.Diagnostics.Debug.WriteLine("Painting..."); if (__network == null) { e.Graphics.FillRectangle( __background, 0, 0, Width, Height); return; } BCMToolbox.NetworkState capturedState = __network.BuildNetworkState(); __lastNetworkState = capturedState; // draw output graphs { double min = double.MaxValue; double max = 0.0; if (__autoScale) { for (int i = 0; i < capturedState.Count; i++) { if (capturedState[i] < min) min = capturedState[i]; if (capturedState[i] > max) max = capturedState[i]; } } else { min = __scaleMin; max = __scaleMax; } for (int i = 0; i < capturedState.Count; i++) { double val = (capturedState[i] - min) / (max - min); if (val < 0) val = 0; if (val > 1.0) val = 1.0; Color c = GUIUtilities.GetPaletteColor(val, __outPalette); for (int j = 0; j < MARKER_LENGTH; j++) { __outputBitmap1.SetPixel(i, j, c); __outputBitmap2.SetPixel(j, i, c); } } } // draw weight graphs { double min = double.MaxValue; double max = 0.0; if (__autoScale) { for (int i = 0; i < capturedState.Count; i++) for (int j = 0; j < capturedState.Count; j++) { if (capturedState[i, j] < min) min = capturedState[i, j]; if (capturedState[i, j] > max) max = capturedState[i, j]; } } else { min = __scaleMin; max = __scaleMax; } for (int i = 0; i < capturedState.Count; i++) for (int j = 0; j < capturedState.Count; j++) { double val = (capturedState[i, j] - min) / (max - min); if (val < 0) val = 0; if (val > 1.0) val = 1.0; __backgroundBitmap.SetPixel(i, j, GUIUtilities.GetPaletteColor(val, __wtPalette)); } } // paint on the screen e.Graphics.DrawImage(__backgroundBitmap, (int)(Width*LEGEND_FACTOR), (int)(Height * LEGEND_FACTOR), (int)(Width * (1-LEGEND_FACTOR)), (int)(Height * (1-LEGEND_FACTOR))); e.Graphics.DrawImage(__outputBitmap1, (int)(Width*LEGEND_FACTOR), 0, (int)(Width * (1 - LEGEND_FACTOR)), (int)(Height * LEGEND_FACTOR)); e.Graphics.DrawImage(__outputBitmap2, 0, (int)(Height * LEGEND_FACTOR), (int)(Width * LEGEND_FACTOR), (int)(Height * (1 - LEGEND_FACTOR))); } #endregion } public class GUIUtilities { // returns the color corresponding to a value between 0 and 1 vs. a specified palette public static Color GetPaletteColor(double val, Color[] Palette) { if (double.IsNaN(val)) return Color.Black; int len = Palette.Length - 1; Color PaletteLow = Palette[(int)Math.Floor(val * len)]; Color PaletteHigh = Palette[(int)Math.Ceiling(val * len)]; if (PaletteLow == PaletteHigh) return PaletteHigh; val -= Math.Floor(val * Palette.Length) * (1.0 / Palette.Length); return Color.FromArgb( (int)(PaletteLow.R + val * (PaletteHigh.R - PaletteLow.R)), (int)(PaletteLow.G + val * (PaletteHigh.G - PaletteLow.G)), (int)(PaletteLow.B + val * (PaletteHigh.B - PaletteLow.B))); } public static Color[] GetColorWheel() { Color[] toRet = new Color[23]; toRet[0] = Color.FromArgb(204, 0, 0); toRet[1] = Color.FromArgb(102, 0, 0); toRet[2] = Color.FromArgb(204, 0, 204); toRet[3] = Color.FromArgb(153, 0, 153); toRet[4] = Color.FromArgb(102, 0, 204); toRet[5] = Color.FromArgb(51, 0, 102); toRet[6] = Color.FromArgb(51, 0, 153); toRet[7] = Color.FromArgb(0, 51, 153); toRet[8] = Color.FromArgb(0, 0, 51); toRet[9] = Color.FromArgb(102, 204, 205); toRet[10] = Color.FromArgb(0, 255, 153); toRet[11] = Color.FromArgb(0, 153, 51); toRet[12] = Color.FromArgb(0, 102, 51); toRet[13] = Color.FromArgb(0, 153, 0); toRet[14] = Color.FromArgb(102, 204, 0); toRet[15] = Color.FromArgb(204, 204, 0); toRet[16] = Color.FromArgb(153, 153, 0); toRet[17] = Color.FromArgb(255, 153, 0); toRet[18] = Color.FromArgb(204, 102, 0); toRet[19] = Color.FromArgb(255, 102, 0); toRet[20] = Color.FromArgb(204, 51, 0); toRet[21] = Color.FromArgb(153, 0, 0); toRet[22] = Color.FromArgb(102, 0, 0); return toRet; } } }