📄 piegraph.cs
字号:
// Disclaimer and Copyright Information
// PieGraph.cs :
//
// All rights reserved.
//
// Written by Pardesi Services, LLC
// Version 1.01
//
// Distribute freely, except: don't remove our name from the source or
// documentation (don't take credit for my work), mark your changes (don't
// get me blamed for your possible bugs), don't alter or remove this
// notice.
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// softomatix@CommonComponent.com
///////////////////////////////////////////////////////////////////////////////
//
using System;
using System.Collections;
using System.Diagnostics;
using System.Xml;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace CommonComponent.CommonChart
{
/// <summary>
///
/// </summary>
abstract public class PieGraph : CommonChart.AxialGraph
{
internal float m_fBoundingSquareSize;
internal float m_fRadialTickerBuffer;
public PieGraph()
{
m_LegendAlignment = LegendAlignmentType.Vertical;
m_fBoundingSquareSize = 0.0F;
m_fRadialTickerBuffer = 12.0F;
this.m_QuadrantToShow = QuadrantType.Quad1234;
}
/// <summary>
///
/// </summary>
internal float BoundingSquareSize
{
get{return this.m_fBoundingSquareSize;}
set{this.m_fBoundingSquareSize = value;}
}
/// <summary>
///
/// </summary>
public float RadialTickerBuffer
{
get{return this.m_fRadialTickerBuffer;}
set{this.m_fRadialTickerBuffer = value;}
}
/// <summary>
/// The method will process the XML document containing the data and
/// store it in the appropriare format for use in drawing.
/// </summary>
/// <returns></returns>
override protected bool ProcessChartData()
{
if (null == this.m_obGraphData)
{
throw new ArgumentException("Null XML document provided");
}
// Select the nodes of data from document.
XmlElement obRoot;
string strLegend = "";
string strIslandLegend = "";
obRoot = this.m_obGraphData.DocumentElement;
// Get the nodes.
this.m_obDataIslandNodes = obRoot.SelectNodes("//chartdataisland");
this.m_iNumberOfDataIslands = m_obDataIslandNodes.Count;
if (m_iNumberOfDataIslands == 0)
{
Trace.WriteLine("There is no data in the xml document.");
return false;
}
// Set the flag if the data has multiple islands or not.
this.MultiIslandData = (m_iNumberOfDataIslands > 1);
m_obIslandList = new ArrayList(m_iNumberOfDataIslands);
// Initialize legends text collection.
InitializeLegendsCollection();
for (int i = 0; i < m_iNumberOfDataIslands; i++)
{
XmlNode obIslandNode = m_obDataIslandNodes[i];
if (obIslandNode != null)
{
// Get the legend text for island.
try
{
strIslandLegend = obIslandNode.Attributes["legend"].Value;
}
catch (Exception ex)
{
Trace.Write(ex.Message);
}
if (strIslandLegend.Length == 0)
{
strIslandLegend = ("Data" + i.ToString());
}
this.AddIslandLegendTextToCollection(strIslandLegend);
XmlNodeList obDataNodes = obIslandNode.SelectNodes("chartdata");
if (obDataNodes != null)
{
int nCount = obDataNodes.Count;
this.m_sLegendCount = (short)nCount;
// Incase the user has specified data series with uneven numbers of points,
// we need to make sure that we have the count as MAX of all counts.
DataPointCount = Math.Max(nCount, this.DataPointCount);
if (nCount > 0)
{
ArrayList obDataList = new ArrayList(nCount);
ArrayList xValList = new ArrayList(nCount);
ArrayList yValList = new ArrayList(nCount);
for (int j = 0; j < nCount; j++)
{
XmlNode obDataNode = obDataNodes[j];
if (obDataNode != null)
{
GraphDataObject ob = new GraphDataObject();
ob.X = Convert.ToSingle(obDataNode["x"].InnerText);
ob.Y = Convert.ToSingle(obDataNode["y"].InnerText);
strLegend = obDataNode["x"].Attributes["legend"].Value;
this.AddLegendTextToCollection(strLegend);
obDataList.Add(ob);
xValList.Add(ob.X);
yValList.Add(ob.Y);
}
}
GetMinMax(xValList, ref m_fMinXDataValue, ref m_fMaxXDataValue);
GetMinMax(yValList, ref m_fMinYDataValue, ref m_fMaxYDataValue);
m_obIslandList.Add(obDataList);
}
}
}
}
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
override protected bool CalculateQudarantToShow()
{
//this.m_QuadrantToShow = QuadrantType.Quad1234;
this.m_QuadrantToShow = QuadrantType.Quad1;
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
override protected bool CalculateAxisLocation()
{
// Calculate the origin of axis.
CalculateAxis();
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
override protected bool CalculateAxis()
{
Point x1, x2, y1, y2;
x1 = new Point();
x2 = new Point();
y1 = new Point();
y2 = new Point();
this.m_Origin = new Point();
// Calculate location of origin from bottom.
this.m_Origin.X = (int)LeftSpacing;
this.m_Origin.Y = (int)(Height - BottomSpacing);
x1.X = (int)LeftSpacing;
x2.X = x1.X + this.m_iXAxisSpan;
x1.Y = x2.Y = this.m_Origin.Y;
y1.X = y2.X = this.m_Origin.X;
y1.Y = (int)TopSpacing;
y2.Y = y1.Y + this.m_iYAxisSpan;
this.m_ChartAxis.Origin = this.m_Origin;
this.m_ChartAxis.X1 = x1;
this.m_ChartAxis.X2 = x2;
this.m_ChartAxis.Y1 = y1;
this.m_ChartAxis.Y2 = y2;
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
override protected bool DrawGraphAxis(bool bDrawGrid)
{
// Calculate the width of x-axis and y-axis lines
CalculateAxisSpan();
// Calculate the axis location.
CalculateAxisLocation();
CalculateAxisLabelLocations();
return true;
}
/// <summary>
///
/// </summary>
/// <param name="ob"></param>
/// <param name="obBrush"></param>
/// <param name="obPen"></param>
/// <param name="ptCenter"></param>
/// <param name="fRadius"></param>
/// <param name="fRadialBuffer"></param>
/// <param name="fAngle"></param>
/// <param name="strData"></param>
/// <param name="strTickerDesc"></param>
/// <returns></returns>
protected bool DrawChartTicker(Graphics ob, SolidBrush obBrush, Pen obPen, Point ptCenter, float fRadius, float fRadialBuffer, float fAngle, string strData, string strTickerDesc)
{
float fX = 0.0F;
float fY = 0.0F;
float fAngleRad = 0.0F;
SmoothingMode sMode = ob.SmoothingMode;
try
{
PointF ptAnchor = new PointF();
PointF ptDesc = new PointF();
PointF ptData = new PointF();
Point pt1 = new Point();
Point pt2 = new Point();
float fRadialDist = fRadius + fRadialBuffer;
fAngleRad = (float)(fAngle*Math.PI/180.0F);
pt1.X = ptCenter.X + (int)(fRadius * Math.Cos(fAngleRad));
pt1.Y = ptCenter.Y + (int)(fRadius * Math.Sin(fAngleRad));
// Calculate the anchor point for displaying ticker.
fX = (float)(fRadialDist * Math.Cos(fAngleRad));
fY = (float)(fRadialDist * Math.Sin(fAngleRad));
ptAnchor.X = ptCenter.X + fX;
ptAnchor.Y = ptCenter.Y + fY;
// Calculate the width of text strings.
SizeF dataSize = ob.MeasureString(strData, this.m_TickerDataFont);
SizeF descSize = ob.MeasureString(strTickerDesc, this.m_TickerDescFont);
// Depending on the angle, we need to decided which side of this
// anchor point the text will be shown.
if ((fAngle >= 0 && fAngle <= 90) ||
(fAngle >=0 && fAngle >= 270))
{
pt2.X = (int)(ptAnchor.X + 4);
pt2.Y = (int)ptAnchor.Y;
ptDesc.X = pt2.X + 1;
ptDesc.Y = pt2.Y;
if (this.DrawYTickerText)
{
ptDesc.Y = pt2.Y - descSize.Height;
}
ptData.X = (float)(ptDesc.X);
ptData.Y = ptDesc.Y - dataSize.Height/2.0F;
if (this.DrawYTickerText)
{
ptData.X = (float)(ptDesc.X + (descSize.Width/2.0 - dataSize.Width/2.0));
// using 3 pixel buffer between desc and data string display
ptData.Y = ptDesc.Y + (descSize.Height);
}
}
else
{
pt2.X = (int)(ptAnchor.X - 4);
pt2.Y = (int)ptAnchor.Y;
ptDesc.X = pt2.X;
ptDesc.Y = pt2.Y;
ptData.X = (float)(ptDesc.X - dataSize.Width);
ptData.Y = ptDesc.Y - dataSize.Height/2.0F;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -