using System; using System.ComponentModel; using System.Collections; using System.Diagnostics; using System.Windows.Forms; using System.Drawing.Drawing2D; using System.Drawing; using System.Globalization; namespace Nolme.WinForms {   public enum ChartRenderingMode   {     Linear3d,     BarWith3d,     Max   };   public enum ChartCumulativeMode   {     StartFrom0,     StartFromLastValue,     Max   };   /// <summary>   /// Summary description for Chart.   /// </summary>   public class Chart : CustomPanel  //System.ComponentModel.Component   {     /// <summary>     /// Required designer variable.     /// </summary>     private System.ComponentModel.Container components = null;     private int    m_LeftMargin;     private int    m_RightMargin;     private int    m_TopMargin;     private int    m_BottomMargin;     private int    m_DeltaDepth;     private bool  m_DisplayTextOnColumns;     private bool  m_DisplayHiddenSides;     private Pen    m_GridPen;     private Pen    m_GridPenFor0;     private Pen    m_ColumnPen;     private Font  m_ColumnFont;     private Font  m_ColumnTitleFont;     private Pen    m_HiddenColumnPen;          private Brush  m_LegendBrush;     private Font  m_LegendFont;     private int    m_VerticalAxisMinValue;     private int    m_VerticalAxisMaxValue;     private int    m_VerticalAxisStep;     private int    m_MarginBetweenColumn;     private string  m_MainTitle;     private Font  m_MainTitleFont;     private ArrayList  m_Columns;     private Color  []m_PredefinedColors = {Color.FromArgb (125, Color.Red),                            Color.FromArgb (125, Color.Green),                            Color.FromArgb (125, Color.Blue),                            Color.FromArgb (125, Color.Yellow),                            Color.FromArgb (125, Color.Cyan),                            Color.FromArgb (125, Color.Magenta),                            Color.FromArgb (125, Color.Maroon),                            Color.FromArgb (125, Color.Aqua),                            Color.FromArgb (125, Color.Beige),                            Color.FromArgb (125, Color.Orange),                            Color.FromArgb (125, Color.Coral),                            Color.FromArgb (125, Color.Lavender),                            Color.FromArgb (125, Color.Gainsboro),                            Color.FromArgb (125, Color.Ivory),                            Color.FromArgb (125, Color.LemonChiffon),                            Color.FromArgb (125, Color.Pink)};     private  ChartRenderingMode  m_RenderingMode;     private ChartCumulativeMode  m_CumulativeMode;     public Chart(System.ComponentModel.IContainer container)     {       ///       /// Required for Windows.Forms Class Composition Designer support       ///       if (container != null)         container.Add(this);       InitializeComponent();       //       // TODO: Add any constructor code after InitializeComponent call       //       this.InitDefault ();     }     public Chart()     {       ///       /// Required for Windows.Forms Class Composition Designer support       ///       InitializeComponent();       //       // TODO: Add any constructor code after InitializeComponent call       //       this.InitDefault ();     }     private void InitDefault ()     {       this.LeftMargin        = 50;       this.RightMargin      = 20;       this.TopMargin        = 20;       this.BottomMargin      = 20;       this.DeltaDepth        = 10;       this.GridPen        = new Pen (Color.Black, 1);       this.GridPenFor0      = new Pen (Color.Violet, 2);       this.ColumnPen        = new Pen (Color.Black, 1);       this.HiddenColumnPen    = new Pen (Color.Gray, 1);       this.LegendFont        = new Font("Arial", 11F, FontStyle.Bold);       this.LegendBrush      = new SolidBrush(Color.Black);       this.ColumnFont        = new Font("Arial", 8F, FontStyle.Italic);       this.ColumnTitleFont    = new Font("Arial", 10F, FontStyle.Underline);       this.MainTitle        = "Main title";       this.MainTitleFont      = new Font("Arial", 16F, FontStyle.Underline | FontStyle.Bold);       this.DisplayTextOnColumns  = true;       this.DisplayHiddenSides    = true;       this.VerticalAxisMinValue  = 0;       this.VerticalAxisMaxValue  = 5000;       this.VerticalAxisStep    = 1000;       this.MarginBetweenColumn  = 20;       this.m_Columns        = new ArrayList ();       this.RenderingMode      = ChartRenderingMode.Linear3d;       this.CumulativeMode      = ChartCumulativeMode.StartFrom0;     }     #region Properties     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public ChartCumulativeMode  CumulativeMode     {       get { return m_CumulativeMode; }       set { m_CumulativeMode = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public ChartRenderingMode  RenderingMode     {       get { return m_RenderingMode; }       set { m_RenderingMode = value; }     }     public Color[]  GetPredefinedColors ()     {       return m_PredefinedColors;     }     public Color  GetPredefinedColors (int colorIndex)     {       return m_PredefinedColors [colorIndex];     }     public void SetPredefinedColors (Color[] value)     {       m_PredefinedColors = value;     }     public int  NumberOfItemsPerColumn     {       get       {         int iCount = 0;         if ((m_Columns != null) && (m_Columns.Count != 0))         {           ChartColumn column = (ChartColumn)m_Columns[0];           iCount = column.Length;         }         return iCount;       }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int  LeftMargin     {       get {return m_LeftMargin; }       set {m_LeftMargin = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int  RightMargin     {       get {return m_RightMargin; }       set {m_RightMargin = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int  TopMargin     {       get {return m_TopMargin; }       set {m_TopMargin = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int  BottomMargin     {       get {return m_BottomMargin; }       set {m_BottomMargin = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int DeltaDepth     {       get {return m_DeltaDepth; }       set {m_DeltaDepth = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public bool  DisplayTextOnColumns     {       get {return m_DisplayTextOnColumns; }       set {m_DisplayTextOnColumns = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public bool  DisplayHiddenSides     {       get {return m_DisplayHiddenSides; }       set {m_DisplayHiddenSides = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Pen    GridPen     {       get {return m_GridPen; }       set {m_GridPen = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Pen    GridPenFor0     {       get {return m_GridPenFor0; }       set {m_GridPenFor0 = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Pen    ColumnPen     {       get {return m_ColumnPen; }       set {m_ColumnPen = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Pen    HiddenColumnPen     {       get {return m_HiddenColumnPen; }       set {m_HiddenColumnPen = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Brush  LegendBrush     {       get {return m_LegendBrush; }       set {m_LegendBrush = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Font  LegendFont     {       get {return m_LegendFont; }       set {m_LegendFont = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Font  ColumnFont     {       get {return m_ColumnFont; }       set {m_ColumnFont = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Font  ColumnTitleFont     {       get {return m_ColumnTitleFont; }       set {m_ColumnTitleFont = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public Font  MainTitleFont     {       get {return m_MainTitleFont; }       set {m_MainTitleFont = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public string  MainTitle     {       get {return m_MainTitle; }       set {m_MainTitle = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int    VerticalAxisMinValue     {       get {return m_VerticalAxisMinValue; }       set {m_VerticalAxisMinValue = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int    VerticalAxisMaxValue     {       get {return m_VerticalAxisMaxValue; }       set {m_VerticalAxisMaxValue = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int    VerticalAxisStep     {       get {return m_VerticalAxisStep; }       set {m_VerticalAxisStep = value; }     }     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]     public int    MarginBetweenColumn     {       get {return m_MarginBetweenColumn; }       set {m_MarginBetweenColumn = value; }     }          public ArrayList  Columns     {       get {return m_Columns; }    // Use carefully     }     #endregion     #region Highlevel functions     public ChartColumn  AddColumn (int value)     {       int []localArray = new int [1];       localArray[0] = value;              return AddColumn (localArray);     }     public ChartColumn  AddColumn (int value0, int value1)     {       int []localArray = new int [2];       localArray[0] = value0;       localArray[1] = value1;              return AddColumn (localArray);     }     public ChartColumn  AddColumn (int value0, int value1, int value2)     {       int []localArray = new int [3];       localArray[0] = value0;       localArray[1] = value1;       localArray[2] = value2;              return AddColumn (localArray);     }     public ChartColumn  AddColumn (int value0, int value1, int value2, int value3)     {       int []localArray = new int [4];       localArray[0] = value0;       localArray[1] = value1;       localArray[2] = value2;       localArray[3] = value3;              return AddColumn (localArray);     }     public ChartColumn  AddColumn (int []values)     {       return this.AddColumn (values, null);     }     public ChartColumn  AddColumn (int []values, string title)     {       // Create new column       ChartColumn  newColumn = this.AllocateColumn (values, title);       // Resize vertical axis       if (newColumn.PositiveValuesSum > this.VerticalAxisMaxValue)         this.VerticalAxisMaxValue = newColumn.PositiveValuesSum;       if (newColumn.NegativeValuesSum < this.VerticalAxisMinValue)         this.VerticalAxisMinValue = newColumn.NegativeValuesSum;       // Add column       this.Columns.Add (newColumn);       return newColumn;     }     virtual protected ChartColumn  AllocateColumn (int []values, string title)     {       ChartColumn  newColumn = new ChartColumn (values, title);       return newColumn;     }     /// <summary>     /// Automatic detection and adjustment of vertical axis maximum     /// </summary>     public void AdjustVerticalAxis ()     {       // Reset current max       this.VerticalAxisMaxValue = 0;       this.VerticalAxisMinValue = 0;       int savedVerticalAxisMaxValue = int.MinValue;       int savedVerticalAxisMinValue = int.MaxValue;       // Iterate to get highest value       if (this.CumulativeMode == ChartCumulativeMode.StartFromLastValue)       {         IEnumerator Iterator = Columns.GetEnumerator ();         while (Iterator.MoveNext ())         {           ChartColumn currentColumn = (ChartColumn)Iterator.Current;           if (currentColumn.PositiveValuesSum > savedVerticalAxisMaxValue)             savedVerticalAxisMaxValue = currentColumn.PositiveValuesSum;           if (currentColumn.NegativeValuesSum < savedVerticalAxisMinValue)             savedVerticalAxisMinValue = currentColumn.NegativeValuesSum;         }       }       else if (this.CumulativeMode == ChartCumulativeMode.StartFrom0)       {         IEnumerator Iterator = Columns.GetEnumerator ();         while (Iterator.MoveNext ())         {           ChartColumn currentColumn = (ChartColumn)Iterator.Current;           if (currentColumn.HighestValue > savedVerticalAxisMaxValue)             savedVerticalAxisMaxValue = currentColumn.HighestValue;           if (currentColumn.LowestValue < savedVerticalAxisMinValue)             savedVerticalAxisMinValue = currentColumn.LowestValue;         }       }       else       {         Debug.Assert (this.CumulativeMode == ChartCumulativeMode.Max, "Chart.AdjustVerticalAxis", "Cumulative mode not managed");       }       // Round max value       if (savedVerticalAxisMaxValue != 0)       {         string Value = savedVerticalAxisMaxValue.ToString (CultureInfo.InvariantCulture);         int NbDigits = Value.Length;         int Round    = (int)Math.Pow (10.0F, (double)(NbDigits - 1));         // N.B.: Round must be an even number in order to make the following calculation works         // As Round is a base-10 number, this condition is true.         Debug.Assert (Round%2 == 0, "Chart.AdjustVerticalAxis ()", "Can't proceed when Round is odd");         //this.VerticalAxisMaxValue = ((savedVerticalAxisMaxValue + Round/2) / Round) * Round;         this.VerticalAxisMaxValue = ((savedVerticalAxisMaxValue + Round) / Round) * Round;         Debug.Assert (this.VerticalAxisMaxValue >= savedVerticalAxisMaxValue, "Chart.AdjustVerticalAxis", string.Format (CultureInfo.InvariantCulture, "Overflow during resize from to {0} (max {1})", this.VerticalAxisMaxValue, savedVerticalAxisMaxValue));       }       // Round min value       if (savedVerticalAxisMinValue != 0)       {         string Value = (-savedVerticalAxisMinValue).ToString (CultureInfo.InvariantCulture);         int NbDigits = Value.Length;         int Round    = (int)Math.Pow (10.0F, (double)(NbDigits - 1));         // N.B.: Round must be an even number in order to make the following calculation works         // As Round is a base-10 number, this condition is true.         Debug.Assert (Round%2 == 0, "Chart.AdjustVerticalAxis ()", "Can't proceed when Round is odd");         //this.VerticalAxisMaxValue = ((savedVerticalAxisMaxValue + Round/2) / Round) * Round;         this.VerticalAxisMinValue = - (((-savedVerticalAxisMinValue + Round) / Round) * Round);         Debug.Assert (this.VerticalAxisMinValue <= savedVerticalAxisMinValue, "Chart.AdjustVerticalAxis", string.Format (CultureInfo.InvariantCulture, "Overflow during resize from to {0} (max {1})", this.VerticalAxisMinValue, savedVerticalAxisMinValue));       }     }     #endregion     /// <summary>     /// Clean up any resources being used.     /// </summary>     protected override void Dispose( bool disposing )     {       if( disposing )       {         if(components != null)         {           components.Dispose();         }       }       base.Dispose( disposing );     }     /*   PANEL ALIGNMENT                                  CHART COLUMN *************************                     |       *            ^          * TM : Top Margin     |       T3________T2                     *         | TM       * BM : Bottom Margin  |        /        /|                     *            v          * LM : Left Margin    |       /        / |     _________         *      P3_________P6    * RM : Right Margin   |      /________/  |    /|       /|       *    P2/|         |  RM *                     |     Top0    T1|  |   / |      / |       *<--->| |         |<--->*                     |     |         |  |  /________/  |       *  LM | |         |     *                     |     |         |  | |   |     |  |       *     | |P1       |P5   *                     |     |  B3_____|B2|_|___|_____|__|____   *     |/__________/     *                     |     |  /      | /  |  /      | /    /   *    P0      ^   P4     *                     |     | /       |/   | /       |/    /   *         | BM       *                     |     |/________/____|/________/____/     *            v          *                     |     Base0    B1                         *************************                     |    <---------><---->                             ColumnWidth  MarginBetweenColumn     */     protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)     {       int  verticalAxisMaxValueInPixels;       int x0, y0, x1, y2, x5;       //int x2, x3, x4, x6;       //int y1, y3, y4, y5, y6;       base.OnPaintBackground(pevent);       pevent.Graphics.SmoothingMode  = SmoothingMode.None;       // Diagonal border       x0 = LeftMargin;       y0 = this.Height - BottomMargin;       x1 = x0 + DeltaDepth;       //y1 = y0 - DeltaDepth;       //x2= x0;       y2= TopMargin + DeltaDepth;       //x3= x1;       //y3= TopMargin;       //x4 = this.Width - RightMargin - DeltaDepth;       //y4 = y0;       x5 = this.Width - RightMargin;       //y5 = y1;       //x6 = this.Width - RightMargin;       //y6 = TopMargin;       verticalAxisMaxValueInPixels = y0 - y2;       // Draw main title       this.DisplayGrid (pevent);       // Draw columns       int numberOfColumns = Columns.Count;       if (numberOfColumns != 0)       {         int  columnWidth      = (x5 - x1) / (numberOfColumns);         int  columnWidthNoMargin = columnWidth - MarginBetweenColumn;         int columnStartOffset  = x0 + MarginBetweenColumn / 2;    // Center columns on graph         // Draw columns title         this.DisplayColumnsTitle (pevent, columnWidth, columnWidthNoMargin, columnStartOffset, verticalAxisMaxValueInPixels, x0, y0);         if (this.RenderingMode == ChartRenderingMode.BarWith3d)         {           this.DisplayColumnsAsBarWith3d (pevent, columnWidth, columnWidthNoMargin, columnStartOffset, verticalAxisMaxValueInPixels, x0, y0);         }         else if (this.RenderingMode == ChartRenderingMode.Linear3d)         {           this.DisplayColumnsAsLinear (pevent, columnWidth, columnWidthNoMargin, columnStartOffset, verticalAxisMaxValueInPixels, x0, y0);         }         if (this.DisplayTextOnColumns)         {           this.DisplayColumnsText (pevent, columnWidth, columnWidthNoMargin, columnStartOffset, verticalAxisMaxValueInPixels, x0, y0-this.DeltaDepth);         }       }       // Draw main title       this.DisplayMainTitle (pevent);     }     virtual protected void DisplayColumnsAsLinear (System.Windows.Forms.PaintEventArgs e, int columnWidth, int columnWidthNoMargin, int columnStartOffset, int verticalAxisMaxValueInPixels, int lowerLeftX, int lowerLeftY)     {       Point Base0, Base1, Base2, Base3;       IEnumerator Iterator    = Columns.GetEnumerator ();       ChartColumn  previousColumn  = null;       Point    prevBase0    = new Point (0,0);       Point    prevBase1    = new Point (0,0);       Point    prevBase2    = new Point (0,0);       Point    prevBase3    = new Point (0,0);       int      columnCurrentOffset = columnStartOffset;       int      offsetFor0      = (-this.VerticalAxisMinValue) * verticalAxisMaxValueInPixels / (this.VerticalAxisMaxValue - this.VerticalAxisMinValue);       while (Iterator.MoveNext ())       {         ChartColumn  currentColumn = (ChartColumn)Iterator.Current;         Debug.Assert (currentColumn.PositiveValuesSum <= VerticalAxisMaxValue, "Chart.DisplayColumns_BarWith3d", "Vertical axis overflow, verify why current column value is higher than axis vertical value");         Debug.Assert (this.VerticalAxisMaxValue > 0, "Chart.DisplayColumns_BarWith3d", "Integer divided by 0");         Base0 = new Point (columnCurrentOffset, lowerLeftY-offsetFor0);         Base1 = new Point (columnCurrentOffset + columnWidthNoMargin, lowerLeftY-offsetFor0);         Base2 = new Point (columnCurrentOffset + columnWidthNoMargin + DeltaDepth, lowerLeftY -offsetFor0 - DeltaDepth);         Base3 = new Point (columnCurrentOffset + DeltaDepth, lowerLeftY -offsetFor0 - DeltaDepth);         currentColumn.DisplayAsLinear (e, this, previousColumn, columnWidthNoMargin, verticalAxisMaxValueInPixels, Base0, Base1, Base2, Base3, prevBase0, prevBase1, prevBase2, prevBase3);         // Next         prevBase0 = Base0;         prevBase1 = Base1;         prevBase2 = Base2;         prevBase3 = Base3;         columnCurrentOffset += columnWidth;         previousColumn    = currentColumn;       }     }     virtual protected void DisplayColumnsAsBarWith3d (System.Windows.Forms.PaintEventArgs e, int columnWidth, int columnWidthNoMargin, int columnStartOffset, int verticalAxisMaxValueInPixels, int lowerLeftX, int lowerLeftY)     {       Point Base0, Base1, Base2, Base3;       IEnumerator Iterator    = Columns.GetEnumerator ();       ChartColumn  previousColumn  = null;       Point    prevBase0    = new Point (0,0);       Point    prevBase1    = new Point (0,0);       Point    prevBase2    = new Point (0,0);       Point    prevBase3    = new Point (0,0);       int      columnCurrentOffset = columnStartOffset;       int      offsetFor0      = (-this.VerticalAxisMinValue) * verticalAxisMaxValueInPixels / (this.VerticalAxisMaxValue - this.VerticalAxisMinValue);       while (Iterator.MoveNext ())       {         ChartColumn  currentColumn = (ChartColumn)Iterator.Current;         Debug.Assert (currentColumn.PositiveValuesSum <= VerticalAxisMaxValue, "Chart.DisplayColumns_BarWith3d", "Vertical axis overflow, verify why current column value is higher than axis vertical value");         Debug.Assert (this.VerticalAxisMaxValue > 0, "Chart.DisplayColumns_BarWith3d", "Integer divided by 0");         Base0 = new Point (columnCurrentOffset, lowerLeftY-offsetFor0);         Base1 = new Point (columnCurrentOffset + columnWidthNoMargin, lowerLeftY-offsetFor0);         Base2 = new Point (columnCurrentOffset + columnWidthNoMargin + DeltaDepth, lowerLeftY - offsetFor0 - DeltaDepth);         Base3 = new Point (columnCurrentOffset + DeltaDepth, lowerLeftY - offsetFor0 - DeltaDepth);         currentColumn.DisplayAsBarWith3d (e, this, previousColumn, columnWidthNoMargin, verticalAxisMaxValueInPixels, Base0, Base1, Base2, Base3, prevBase0, prevBase1, prevBase2, prevBase3);         // Next column         prevBase0 = Base0;         prevBase1 = Base1;         prevBase2 = Base2;         prevBase3 = Base3;         columnCurrentOffset += columnWidth;         previousColumn    = currentColumn;       }     }     virtual protected void DisplayColumnsTitle (System.Windows.Forms.PaintEventArgs e, int columnWidth, int columnWidthNoMargin, int columnStartOffset, int verticalAxisMaxValueInPixels, int lowerLeftX, int lowerLeftY)     {       IEnumerator Iterator = Columns.GetEnumerator ();       int columnCurrentOffset = columnStartOffset;       while (Iterator.MoveNext ())       {         ChartColumn  currentColumn = (ChartColumn)Iterator.Current;         Point Base0 = new Point (columnCurrentOffset, lowerLeftY);         Point Base1 = new Point (columnCurrentOffset + columnWidthNoMargin, lowerLeftY);         currentColumn.DisplayTitle (e, this, Base0, Base1);         // Jump to next offset         columnCurrentOffset += columnWidth;       }     }     virtual protected void DisplayColumnsText (System.Windows.Forms.PaintEventArgs e, int columnWidth, int columnWidthNoMargin, int columnStartOffset, int verticalAxisMaxValueInPixels, int lowerLeftX, int lowerLeftY)     {       int      offset;       int      offsetFor0;       IEnumerator Iterator      = Columns.GetEnumerator ();       int      columnCurrentOffset = columnStartOffset;              offsetFor0 = (-this.VerticalAxisMinValue) * verticalAxisMaxValueInPixels / (this.VerticalAxisMaxValue - this.VerticalAxisMinValue);       while (Iterator.MoveNext ())       {         ChartColumn  currentColumn = (ChartColumn)Iterator.Current;         Debug.Assert (currentColumn.PositiveValuesSum <= VerticalAxisMaxValue, "Chart.OnPaintBackground", "Vertical axis overflow, verify why current column value is higher than axis vertical value");         Debug.Assert (this.VerticalAxisMaxValue > 0, "Chart.OnPaintBackground", "Integer divided by 0");         if (this.CumulativeMode == ChartCumulativeMode.StartFrom0)         {           offset  = offsetFor0 + (verticalAxisMaxValueInPixels * currentColumn.HighestValue / (this.VerticalAxisMaxValue-this.VerticalAxisMinValue));         }         else if (this.CumulativeMode == ChartCumulativeMode.StartFromLastValue)         {           offset  = offsetFor0 + (verticalAxisMaxValueInPixels * currentColumn.PositiveValuesSum / (this.VerticalAxisMaxValue-this.VerticalAxisMinValue));         }         else         {           Debug.Assert (this.CumulativeMode == ChartCumulativeMode.Max, "Chart.OnPaintBackground", "Cumulative mode not managed");           offset  = 0;         }         System.Drawing.SizeF    size  = e.Graphics.MeasureString (currentColumn.PositiveValuesSum.ToString (CultureInfo.InvariantCulture), this.ColumnFont);         PointF          Base0  = new PointF ((float)columnCurrentOffset, (float)(lowerLeftY - offset) - size.Height);         RectangleF backgroundRectangle  = new RectangleF (Base0, size);         // Align rectangle on column width         backgroundRectangle.X = columnCurrentOffset + this.MarginBetweenColumn / 2 + ((columnWidthNoMargin - backgroundRectangle.Width) / 2);         currentColumn.DisplayText (e, this, backgroundRectangle);         // Jump to next offset         columnCurrentOffset += columnWidth;       }     }     virtual protected void DisplayGrid (System.Windows.Forms.PaintEventArgs e)     {       int x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6;       // Diagonal border from front side to back side       x0 = LeftMargin;       y0 = this.Height - BottomMargin;       x1 = x0 + DeltaDepth;       y1 = y0 - DeltaDepth;       e.Graphics.DrawLine (GridPen, x0, y0, x1, y1);       x2= x0;       y2= TopMargin + DeltaDepth;       x3= x1;       y3= TopMargin;       e.Graphics.DrawLine (GridPen, x2, y2, x3, y3);       x4 = this.Width - RightMargin - DeltaDepth;       y4 = y0;       x5 = this.Width - RightMargin;       y5 = y1;       e.Graphics.DrawLine (GridPen, x4, y4, x5, y5);       x6 = this.Width - RightMargin;       y6 = TopMargin;       // Horizontal & vertical borders       e.Graphics.DrawLine (GridPen, x0, y0, x4, y4);       e.Graphics.DrawLine (GridPen, x0, y0, x2, y2);       e.Graphics.DrawLine (GridPen, x1, y1, x3, y3);       e.Graphics.DrawLine (GridPen, x6, y6, x3, y3);       e.Graphics.DrawLine (GridPen, x6, y6, x5, y5);       e.Graphics.DrawLine (GridPen, x1, y1, x5, y5);       // Vertical Axis       int  currentNumber  = 0;       int  numberOfSteps  = (VerticalAxisMaxValue-VerticalAxisMinValue) / VerticalAxisStep;       int tmpY      = y0;       int deltaStep    = (y0 - y2) / numberOfSteps;       // Loop for all steps but avoid rounding error & overdraw by not drawing last step       for (int iVertical = 0; iVertical < numberOfSteps-1; iVertical++)       {         tmpY      -= deltaStep;         currentNumber  = this.VerticalAxisMinValue + (iVertical+1) * VerticalAxisStep;         if ((currentNumber == 0) && (this.VerticalAxisMinValue < 0))         {           // Draw diagonal           e.Graphics.DrawLine (GridPenFor0, x0, tmpY, x1, tmpY - DeltaDepth);           //e.Graphics.DrawLine (GridPenFor0, x4, tmpY, x5, tmpY - DeltaDepth);           // Draw horizontal on chart           e.Graphics.DrawLine (GridPenFor0, x5, tmpY - DeltaDepth, x1, tmpY - DeltaDepth);           //e.Graphics.DrawLine (GridPenFor0, x0, tmpY, x4, tmpY);         }         else         {           // Draw diagonal           e.Graphics.DrawLine (GridPen, x0, tmpY, x1, tmpY - DeltaDepth);           // Draw horizontal on chart           e.Graphics.DrawLine (GridPen, x5, tmpY - DeltaDepth, x1, tmpY - DeltaDepth);         }       }       // Draw vertical legend       StringFormat legendDrawFormat  = new StringFormat();       legendDrawFormat.Alignment    = StringAlignment.Far;       legendDrawFormat.LineAlignment  = StringAlignment.Center;       tmpY      = y0;       for (int iVertical = 0; iVertical < numberOfSteps; iVertical++)       {         tmpY  -= deltaStep;         // Draw horizontal on scaling         e.Graphics.DrawLine (GridPen, x0, tmpY, x0-5, tmpY);                  // Draw legend         currentNumber = VerticalAxisMinValue + (iVertical+1) * VerticalAxisStep;         PointF point = new PointF (x0-5, tmpY);    // remove few pixels from vertical line         e.Graphics.DrawString (currentNumber.ToString (CultureInfo.InvariantCulture), LegendFont, LegendBrush, point, legendDrawFormat);       }     }     virtual protected void DisplayMainTitle (System.Windows.Forms.PaintEventArgs e)     {       if (this.MainTitle != null)       {         Point      point        = new Point (this.LeftMargin, this.Height - this.MainTitleFont.Height);         Size      size        = new Size (this.Width - this.LeftMargin - this.RightMargin, this.MainTitleFont.Height) ; //e.Graphics.MeasureString (this.MainTitle, this.MainTitleFont);         StringFormat  legendDrawFormat  = new StringFormat();         legendDrawFormat.Alignment    = StringAlignment.Center;         legendDrawFormat.LineAlignment  = StringAlignment.Center;         Rectangle textRectangle      = new Rectangle (point, size);         e.Graphics.DrawString (this.MainTitle, this.MainTitleFont, this.LegendBrush, textRectangle, legendDrawFormat);       }     }     #region Component Designer generated code     /// <summary>     /// Required method for Designer support - do not modify     /// the contents of this method with the code editor.     /// </summary>     private void InitializeComponent()     {       components = new System.ComponentModel.Container();     }     #endregion   } }