using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace UsageControl { /// /// Summary description for UsageHistoryControl. /// public class UsageHistoryControl : UserControl { /// /// Required designer variable. /// private Container components = null; private const int squareWidth = 12; private const int maxLastValuesCount = 2000; private const int shiftStep = 3; private int shift = 0; private int [] lastValues1 = new int[maxLastValuesCount]; private int [] lastValues2 = new int[maxLastValuesCount]; private int nextValueIndex; private int lastValuesCount; private int max = 100; private int min = 0; public UsageHistoryControl() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); EnableDoubleBuffering(); Reset(); } public void Reset() { lastValues1.Initialize(); lastValues2.Initialize(); nextValueIndex = 0; lastValuesCount = 0; Invalidate(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { // // UsageHistoryControl // this.BackColor = System.Drawing.Color.Black; this.Name = "UsageHistoryControl"; } #endregion private void EnableDoubleBuffering() { // Set the value of the double-buffering style bits to true. SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); UpdateStyles(); } protected override void OnResize(EventArgs e) { // Invalidate the control to get a repaint. Invalidate(); } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; for(int i = 0; i <= ClientRectangle.Width+squareWidth; i += squareWidth) { g.DrawLine(Pens.Green, i-shift, 0, i-shift, ClientRectangle.Height); } for(int i = 0; i < ClientRectangle.Height; i += squareWidth) { g.DrawLine(Pens.Green, 0, i, ClientRectangle.Width, i); } int startValueIndex = (nextValueIndex-1+maxLastValuesCount)%maxLastValuesCount; int prevVal1 = GetRelativeValue(lastValues1[startValueIndex]); int prevVal2 = GetRelativeValue(lastValues2[startValueIndex]); for(int i = 1; i < lastValuesCount; ++i) { int index = nextValueIndex - 1 - i; if (index < 0) { index += maxLastValuesCount; } int val1 = GetRelativeValue(lastValues1[index]); int val2 = GetRelativeValue(lastValues2[index]); g.DrawLine( Pens.Red, ClientRectangle.Width-(i-1)*shiftStep, ClientRectangle.Height-prevVal2, ClientRectangle.Width-i*shiftStep, ClientRectangle.Height-val2); g.DrawLine( Pens.LawnGreen, ClientRectangle.Width-(i-1)*shiftStep, ClientRectangle.Height-prevVal1, ClientRectangle.Width-i*shiftStep, ClientRectangle.Height-val1); prevVal1 = val1; prevVal2 = val2; } } private int GetRelativeValue(int val) { int result = val * (ClientRectangle.Height-2) / max + 1; return result; } public void AddValues(int val1, int val2) { lastValues1[nextValueIndex] = val1; lastValues2[nextValueIndex] = val2; nextValueIndex++; nextValueIndex %= maxLastValuesCount; lastValuesCount++; if (lastValuesCount > maxLastValuesCount) { lastValuesCount = maxLastValuesCount; } shift += shiftStep; shift %= squareWidth; Invalidate(); } public int Maximum { get { return max; } set { // Make sure that the maximum value is never set lower than the minimum value. if (value < min) { min = value; } max = value; // Invalidate the control to get a repaint. Invalidate(); } } } }