using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Diagnostics;
namespace Nolme.WinForms
{
/// <summary>
/// Summary description for ChartColumn.
/// </summary>
public class ChartColumn
{
private int[] m_Values; /// Values in column
private int m_PositiveValuesSum; /// Sum of all positives values stored (usd for debug & scaling)
private int m_NegativeValuesSum; /// Sum of all negatives values stored (usd for debug & scaling)
private int m_HighestValue; /// Highest value in all values stored
private int m_LowestValue; /// Lowest value in all values stored
private string m_Title; /// Title of column
public ChartColumn(int []values)
{
this.Init (values);
}
public ChartColumn(int []values, string title)
{
this.Title = title;
this.Init (values);
}
void Init (int []values)
{
SetValues (values);
}
#region Properties
public int HighestValue
{
get {return m_HighestValue;}
}
public int LowestValue
{
get {return m_LowestValue;}
}
public int PositiveValuesSum
{
get {return m_PositiveValuesSum;}
}
public int NegativeValuesSum
{
get {return m_NegativeValuesSum;}
}
public int Length
{
get {return m_Values.Length;}
}
public string Title
{
get {return m_Title; }
set {m_Title = value; }
}
public int[] GetValues ()
{
return m_Values;
}
public void SetValues (int[] value)
{
m_Values = value;
m_NegativeValuesSum = 0;
m_PositiveValuesSum = 0;
m_HighestValue = int.MinValue;
m_LowestValue = int.MaxValue;
for (int i = 0; i < value.Length; i++)
{
if (value [i] >= 0)
m_PositiveValuesSum += value [i];
else
m_NegativeValuesSum += value [i];
if (value [i] > m_HighestValue)
{
m_HighestValue = value [i];
}
if (value [i] < m_LowestValue)
{
m_LowestValue = value [i];
}
}
}
#endregion
#region Drawing
virtual internal void DisplayAsLinear (System.Windows.Forms.PaintEventArgs pevent, Chart parent, ChartColumn previousColumn,
int columnWidthNoMargin, int verticalAxisMaxValueInPixels,
Point base0, Point base1, Point base2, Point base3,
Point prevBase0, Point prevBase1, Point prevBase2, Point prevBase3)
{
Debug.Assert (parent.RenderingMode == ChartRenderingMode.Linear3d, "ChartColumn.DisplayBars", "Rendering mode not yet managed");
// First column, nothing to draw
if (previousColumn == null)
return;
// Draw all values
for (int i = 0; i < this.m_Values.Length; i++)
{
Color currentColor = parent.GetPredefinedColors (i);
Brush currentBrush = new SolidBrush (currentColor);
Brush currentBrushDarken = new SolidBrush (Color.FromArgb (currentColor.A, currentColor.R /2, currentColor.G /2, currentColor.B /2));
// Compute points
int prevY = prevBase0.Y - (previousColumn.m_Values[i] * verticalAxisMaxValueInPixels / (parent.VerticalAxisMaxValue-parent.VerticalAxisMinValue));
int y = base0.Y - (this.m_Values[i] * verticalAxisMaxValueInPixels / (parent.VerticalAxisMaxValue-parent.VerticalAxisMinValue));
Point currentPoint0 = new Point (prevBase0.X + columnWidthNoMargin / 2, prevY);
Point currentPoint1 = new Point (base0.X + columnWidthNoMargin / 2, y);
Point currentPoint2 = new Point (base3.X + columnWidthNoMargin / 2, y - parent.DeltaDepth);
Point currentPoint3 = new Point (prevBase3.X + columnWidthNoMargin / 2, prevY - parent.DeltaDepth);
// Local top value path
GraphicsPath pathSubValueTop = new GraphicsPath ();
pathSubValueTop.AddLine (currentPoint0, currentPoint1);
pathSubValueTop.AddLine (currentPoint1, currentPoint2);
pathSubValueTop.AddLine (currentPoint2, currentPoint3);
pathSubValueTop.AddLine (currentPoint3, currentPoint0);
if (prevY > y)
pevent.Graphics.FillPath (currentBrushDarken, pathSubValueTop);
else
pevent.Graphics.FillPath (currentBrush, pathSubValueTop);
}
}
virtual internal void DisplayAsBarWith3d (System.Windows.Forms.PaintEventArgs pevent, Chart parent, ChartColumn previousColumn,
int columnWidthNoMargin, int verticalAxisMaxValueInPixels,
Point base0, Point base1, Point base2, Point base3,
Point prevBase0, Point prevBase1, Point prevBase2, Point prevBase3)
{
bool FirstNegativeBarToDraw = true;
// Draw all values
Point currentBase0 = base0;
Point currentBase1 = base1;
Point currentBase2 = base2;
Point currentBase3 = base3;
Point currentBasePositive0 = base0;
Point currentBasePositive1 = base1;
Point currentBasePositive2 = base2;
Point currentBasePositive3 = base3;
Point currentBaseNegative0 = base0;
Point currentBaseNegative1 = base1;
Point currentBaseNegative2 = base2;
Point currentBaseNegative3 = base3;
for (int i = 0; i < this.m_Values.Length; i++)
{
if (this.m_Values[i] != 0)
{
int offset = this.m_Values[i] * (verticalAxisMaxValueInPixels) / (parent.VerticalAxisMaxValue-parent.VerticalAxisMinValue);
if (this.m_Values[i] >= 0)
{
currentBase0 = currentBasePositive0;
currentBase1 = currentBasePositive1;
currentBase2 = currentBasePositive2;
currentBase3 = currentBasePositive3;
}
else
{
currentBase0 = currentBaseNegative0;
currentBase1 = currentBaseNegative1;
currentBase2 = currentBaseNegative2;
currentBase3 = currentBaseNegative3;
}
Point currentTop0 = new Point (currentBase0.X, currentBase0.Y - offset);
Point currentTop1 = new Point (currentBase1.X, currentBase1.Y - offset);
Point currentTop2 = new Point (currentBase2.X, currentBase2.Y - offset);
Point currentTop3 = new Point (currentBase3.X, currentBase3.Y - offset);
Color currentColor = parent.GetPredefinedColors (i);
Brush currentBrush = new SolidBrush (currentColor);
//Brush currentBrushDarken = new SolidBrush (Color.FromArgb (currentColor.A, currentColor.R /2, currentColor.G /2, currentColor.B /2));
if (parent.RenderingMode == ChartRenderingMode.BarWith3d)
{
if (parent.DisplayHiddenSides)
{
if (this.m_Values[i] >= 0)
{
pevent.Graphics.DrawLine (parent.HiddenColumnPen, currentBase0, currentBase3);
pevent.Graphics.DrawLine (parent.HiddenColumnPen, currentBase3, currentTop3);
pevent.Graphics.DrawLine (parent.HiddenColumnPen, currentBase3, currentBase2);
}
else
{
pevent.Graphics.DrawLine (parent.HiddenColumnPen, currentTop0, currentTop3);
pevent.Graphics.DrawLine (parent.HiddenColumnPen, currentBase3, currentTop3);
pevent.Graphics.DrawLine (parent.HiddenColumnPen, currentTop3, currentTop2);
}
}
if (this.m_Values[i] >= 0)
{
// Local top value path
GraphicsPath pathSubValueTop = new GraphicsPath ();
pathSubValueTop.AddLine (currentTop0, currentTop1);
pathSubValueTop.AddLine (currentTop1, currentTop2);
pathSubValueTop.AddLine (currentTop2, currentTop3);
pathSubValueTop.AddLine (currentTop3, currentTop0);
//if (i == this.m_Values.Length-1)
{
pevent.Graphics.FillPath (currentBrush, pathSubValueTop);
}
}
else
{
if ( FirstNegativeBarToDraw)
{
// Local bottom value path
GraphicsPath pathSubValueBottom = new GraphicsPath ();
pathSubValueBottom.AddLine (currentBase0, currentBase1);
pathSubValueBottom.AddLine (currentBase1, currentBase2);
pathSubValueBottom.AddLine (currentBase2, currentBase3);
pathSubValueBottom.AddLine (currentBase3, currentBase0);
pevent.Graphics.FillPath (currentBrush, pathSubValueBottom);
FirstNegativeBarToDraw = false;
}
}
// Left
/*
GraphicsPath pathSubValueLeft = new GraphicsPath ();
pathSubValueLeft.AddLine (currentBase0, currentBase3);
pathSubValueLeft.AddLine (currentBase3, currentTop3);
pathSubValueLeft.AddLine (currentTop3, currentTop0);
pathSubValueLeft.AddLine (currentTop0, currentBase0);
pevent.Graphics.FillPath (currentBrushDarken, pathSubValueLeft);
*/
// Back
/*
GraphicsPath pathSubValueBack = new GraphicsPath ();
pathSubValueBack.AddLine (currentBase3, currentBase2);
pathSubValueBack.AddLine (currentBase2, currentTop2);
pathSubValueBack.AddLine (currentTop2, currentTop3);
pathSubValueBack.AddLine (currentTop3, currentBase3);
pevent.Graphics.FillPath (currentBrushDarken, pathSubValueBack);
*/
// Front
GraphicsPath pathSubValueFront = new GraphicsPath ();
pathSubValueFront.AddLine (currentBase0, currentBase1);
pathSubValueFront.AddLine (currentBase1, currentTop1);
pathSubValueFront.AddLine (currentTop1, currentTop0);
pathSubValueFront.AddLine (currentTop0, currentBase0);
pevent.Graphics.FillPath (currentBrush, pathSubValueFront);
pevent.Graphics.DrawPath (parent.ColumnPen, pathSubValueFront);
// Right
GraphicsPath pathSubValueRightSide = new GraphicsPath ();
pathSubValueRightSide.AddLine (currentBase1, currentBase2);
pathSubValueRightSide.AddLine (currentBase2, currentTop2);
pathSubValueRightSide.AddLine (currentTop2, currentTop1);
pathSubValueRightSide.AddLine (currentTop1, currentBase1);
pevent.Graphics.FillPath (currentBrush, pathSubValueRightSide);
pevent.Graphics.DrawPath (parent.ColumnPen, pathSubValueRightSide);
}
else
{
Debug.Assert (parent.RenderingMode == ChartRenderingMode.Linear3d, "ChartColumn.DisplayBars", "Rendering mode not yet managed");
}
// Next
if (parent.CumulativeMode == ChartCumulativeMode.StartFromLastValue)
{
if (this.m_Values[i] >= 0)
{
currentBasePositive0 = currentTop0;
currentBasePositive1 = currentTop1;
currentBasePositive2 = currentTop2;
currentBasePositive3 = currentTop3;
}
else
{
currentBaseNegative0 = currentTop0;
currentBaseNegative1 = currentTop1;
currentBaseNegative2 = currentTop2;
currentBaseNegative3 = currentTop3;
}
}
}
}
// Redraw top to override hidden pen color
GraphicsPath pathTop = new GraphicsPath ();
pathTop.AddLine (currentBasePositive0, currentBasePositive1);
pathTop.AddLine (currentBasePositive1, currentBasePositive2);
pathTop.AddLine (currentBasePositive2, currentBasePositive3);
pathTop.AddLine (currentBasePositive3, currentBasePositive0);
pevent.Graphics.DrawPath (parent.ColumnPen, pathTop);
}
virtual internal void DisplayTitle (System.Windows.Forms.PaintEventArgs pevent, Chart parent, Point base0, Point base1)
{
//System.Drawing.SizeF size = new SizeF (base1.X - base0.X + parent.DeltaDepth + parent.MarginBetweenColumn, base1.Y - base0.Y);
//RectangleF backgroundRectangle = new RectangleF (base0, size);
if (this.Title != null)
{
StringFormat legendDrawFormat = new StringFormat();
legendDrawFormat.Alignment = StringAlignment.Far;
legendDrawFormat.LineAlignment = StringAlignment.Center;
// Draw oblique
Matrix oldMatrix = pevent.Graphics.Transform.Clone();
pevent.Graphics.TranslateTransform( base0.X + (base1.X-base0.X)/2, base0.Y + 5); // Add few pixels
pevent.Graphics.RotateTransform(-45);
pevent.Graphics.DrawString(this.Title, parent.ColumnTitleFont, parent.LegendBrush, 0, 0, legendDrawFormat);
pevent.Graphics.Transform = oldMatrix;
// Draw horizontal
// pevent.Graphics.DrawString (this.Title.ToString (), parent.ColumnTitleFont, parent.LegendBrush, backgroundRectangle);
}
}
virtual internal void DisplayText (System.Windows.Forms.PaintEventArgs pevent, Chart parent, RectangleF backgroundRectangle)
{
// Draw legend background
LinearGradientBrush backgroundBrush = new LinearGradientBrush (backgroundRectangle, Color.White, Color.Gray, 45.0f, true);
pevent.Graphics.FillRectangle (backgroundBrush, backgroundRectangle);
pevent.Graphics.DrawRectangle (parent.ColumnPen, backgroundRectangle.X, backgroundRectangle.Y, backgroundRectangle.Width, backgroundRectangle.Height);
// Draw legend
int TotalValues = this.PositiveValuesSum - this.NegativeValuesSum;
pevent.Graphics.DrawString (TotalValues.ToString (CultureInfo.InvariantCulture), parent.ColumnFont, parent.LegendBrush, backgroundRectangle);
}
#endregion
}
}