using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Diagnostics; using BCMToolbox; namespace VisualBCM { public partial class GraphForm : Form, INetworkMonitor { Func __norm = null; Color[] __wheel = null; const int GRAPH_DEPTH = 50; List __gatheredNorms = new List(GRAPH_DEPTH + 10); double[] __gatheredTotals = null; int __normWidth = 0; int __normTotalCount = 0; public GraphForm(TraceableNetwork net, Func norms, string description) { __wheel = GUIUtilities.GetColorWheel(); InitializeComponent(); __norm = norms; if(net != null) net.RegisterMonitor(this); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.TopMost = true; if (net != null) this.Text = String.Format("VisualBCM Graphing tool [{0} - {1}]", net.Identification, description); else this.Text = String.Format("VisualBCM Graphing tool [{0}]", description); } public void RefreshGraph() { if (__gatheredNorms.Count == 0) return; Bitmap bmp = new Bitmap(GRAPH_DEPTH, 100, System.Drawing.Imaging.PixelFormat.Format24bppRgb); lock (__gatheredNorms) { int start = 0; if (__gatheredNorms.Count > GRAPH_DEPTH) start = __gatheredNorms.Count - GRAPH_DEPTH; for (int j = 0; j < __normWidth; j++) { double normAve = __gatheredTotals[j] / __normTotalCount; for (int i = start; i < __gatheredNorms.Count; i++) { double val = __gatheredNorms[i][j]; val /= normAve; val = val * 50; val = 100 - val; if (val < 0) val = 0; if (val >= 100) val = 99; bmp.SetPixel(i - start, (int)val, __wheel[j % __wheel.Length]); } } } this.pictureBox1.Image = bmp; this.label1.Text = String.Format("ticks: {0}", __normTotalCount); } #region INetworkMonitor Members public Func KernelFunction { get { return __norm; } } public void RegisterNorm(double[] newNorm) { lock (__gatheredNorms) { if (__gatheredNorms.Count == 0) { __normWidth = newNorm.Length; __gatheredTotals = new double[__normWidth]; } else if (newNorm.Length != __normWidth) return; __gatheredNorms.Add(newNorm); while (__gatheredNorms.Count > GRAPH_DEPTH) __gatheredNorms.RemoveAt(0); for (int i = 0; i < __normWidth; i++) __gatheredTotals[i] += newNorm[i]; __normTotalCount++; } } #endregion #region Plotting function graphs public static GraphForm PlotFunction(Func func, double intervalMin, double intervalMax) { GraphForm toRet = new GraphForm(null, null, "Function Graph"); double maxPlot = double.MinValue; double minPlot = double.MaxValue; for (int i = 0; i < GRAPH_DEPTH; i++) { double val = i * (intervalMax - intervalMin) / GRAPH_DEPTH + intervalMin; double y = func(val); if (y < minPlot) minPlot = y; if (y > maxPlot) maxPlot = y; toRet.RegisterNorm(new double[] { y }); } toRet.RefreshGraph(); toRet.label1.Text = String.Format("domain: [{0}, {1}] | codomain: [{2}, {3}]", intervalMin.ToString("#0.00"), intervalMax.ToString("#0.00"), minPlot.ToString("#0.00"), maxPlot.ToString("#0.00")); toRet.Show(); toRet.BringToFront(); return toRet; } #endregion } }