//private DataCollection dc_sub = new DataCollection(); public Chart2D() { chartSize = new Size(600, 400); cs = new ChartStyle(this); //DataCollection dc = new DataCollection(); //dclist.Add(dc); //dc_sub.ColorTable = "WarnColors.txt"; }
public Chart2D(Size chartsize) { chartSize = chartsize; cs = new ChartStyle(this); //DataCollection dc = new DataCollection(); //dclist.Add(dc); //dc_sub.ColorTable = "WarnColors.txt"; }
/// <summary> /// 样式复制,包括绘图区大小、颜色和边距 /// </summary> /// <returns></returns> public ChartStyle Clone() { ChartStyle newCS = new ChartStyle(this.chart2d); newCS.chartArea = new Rectangle(this.ChartArea.X, this.ChartArea.Y, this.ChartArea.Width, this.ChartArea.Height); newCS.plotArea = new Rectangle(this.PlotArea.X, this.PlotArea.Y, this.PlotArea.Width, this.PlotArea.Height); newCS.ChartAreaColor = this.ChartAreaColor.Clone(); newCS.PlotAreaColor = this.PlotAreaColor.Clone(); newCS.XOffset = this.XOffset; newCS.YOffset = this.YOffset; return(newCS); }
/// <summary> /// x轴标记角度自适应 /// </summary> /// <param name="g"></param> /// <param name="cs"></param> /// <param name="lb"></param> /// <param name="xa"></param> internal static void SetTickAngle(Graphics g, ChartStyle cs, XYLabel lb, XAxis xa) { SizeF sizeXTick; float maxlength = 0; float maxheight = 0; for (int n = 0; n < xa.XTickMarkFull.Length; n++) { sizeXTick = g.MeasureString(xa.XTickMarkFull[n], xa.XTickStyle.TextFont); maxlength = (sizeXTick.Width > maxlength) ? sizeXTick.Width : maxlength; maxheight = (sizeXTick.Height > maxheight)? sizeXTick.Height:maxheight; } float xticklength = xa.XTick * cs.PlotArea.Width / (xa.XLimMax - xa.XLimMin); xa.XTickAngle = (xa.XMarkInterval * xticklength > maxlength) ? 0 : ((xa.XMarkInterval * xticklength > maxlength / 2) ? -45 : -90); }
internal static void AddPie(DataCollectionPie dc, Graphics g, ChartStyle cs) { SolidBrush aBrush = new SolidBrush(Color.Black); Pen aPen = new Pen(dc.BorderColor); int nData = dc.DataSeriesList.Count; float fSum = 0; for (int i = 0; i < nData; i++) { fSum = fSum + (float)((DataSeries)dc.DataSeriesList[i]).PointList[0]; } float startAngle = 0; float sweepAngle = 0; for (int i = 0; i < nData; i++) { DataSeries ds = (DataSeries)(dc.DataSeriesList[i]); aBrush = new SolidBrush(ds.FillColor); int explode = (ds.IsExplode) ? cs.PlotArea.Width / 10 : 0; if (fSum < 1 && dc.PieChartType == PieChartTypeEnum.Partial) { startAngle = startAngle + sweepAngle; sweepAngle = 360 * (float)ds.PointList[0]; } else { startAngle = startAngle + sweepAngle; sweepAngle = 360 * (float)ds.PointList[0] / fSum; } int xshift = (int)(explode * Math.Cos((startAngle + sweepAngle / 2) * Math.PI / 180)); int yshift = (int)(explode * Math.Sin((startAngle + sweepAngle / 2) * Math.PI / 180)); Rectangle rect1 = new Rectangle(cs.polarArea.X + xshift, cs.polarArea.Y + yshift, cs.polarArea.Width, cs.polarArea.Height); g.FillPie(aBrush, rect1, startAngle, sweepAngle); if (dc.IsBorderVis) { g.DrawPie(aPen, rect1, startAngle, sweepAngle); } } }
internal static void AddAreas(DataCollectionArea dc, Graphics g, ChartStyle cs, XAxis xa, YAxis ya, Y2Axis y2a) { if (dc.ChartType != Chart2DTypeEnum.AreaChart || dc.DataSeriesList.Count == 0) { return; } //比较各列点数,面积图需统一点数(暂不处理,待优化:以最少点数为准) int nPoints = 0; bool isConsistant = true; bool isY2 = false; foreach (DataSeries ds in dc.DataSeriesList) { if (nPoints == 0) { nPoints = ds.PointList.Count; } else if (nPoints != ds.PointList.Count) { isConsistant = false; } if (ds.IsY2Data) { isY2 = true; } } if (!isConsistant) { return; } float[] ySum = new float[nPoints]; PointF[] pts = new PointF[2 * nPoints]; PointF[] pt0 = new PointF[nPoints]; PointF[] pt1 = new PointF[nPoints]; for (int i = 0; i < nPoints; i++) { ySum[i] = dc.AreaAxis; } int n = 0; Pen aPen = new Pen(Color.Black); SolidBrush aBrush = new SolidBrush(Color.Black); foreach (DataSeries ds in dc.DataSeriesList) { //Color fillColor = Color.FromArgb(dc.CMap[n, 0], dc.CMap[n, 1], dc.CMap[n, 2], dc.CMap[n, 3]); if (ds.FillColor != Color.Empty) { aBrush = new SolidBrush(ds.FillColor); } else { aBrush = new SolidBrush(Color.FromArgb(180, ds.LineStyle.LineColor)); } aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.LineThickness); aPen.DashStyle = ds.LineStyle.LinePattern; // Draw lines and areas: if (dc.AreaChartType == AreaChartTypeEnum.Area) { if (!isY2) { for (int i = 0; i < nPoints; i++) { pt0[i] = new PointF(((PointF)ds.PointList[i]).X, ySum[i]); ySum[i] = ySum[i] + ((PointF)ds.PointList[i]).Y; pt1[i] = new PointF(((PointF)ds.PointList[i]).X, ySum[i]); pts[i] = cs.Point2D(pt0[i], xa, ya); pts[2 * nPoints - 1 - i] = cs.Point2D(pt1[i], xa, ya); } } else { for (int i = 0; i < nPoints; i++) { pt0[i] = new PointF(((PointF)ds.PointList[i]).X, ySum[i]); ySum[i] = ySum[i] + ((PointF)ds.PointList[i]).Y; pt1[i] = new PointF(((PointF)ds.PointList[i]).X, ySum[i]); pts[i] = cs.Point2DY2(pt0[i], xa, y2a); pts[2 * nPoints - 1 - i] = cs.Point2DY2(pt1[i], xa, y2a); } } g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } n++; } } aPen.Dispose(); aBrush.Dispose(); }
internal static void AddPolar(DataCollectionPolar dc, Graphics g, ChartStyle cs, RAxis ra) { if (!dc.CheckNegative()) { return; } float xc = cs.polarArea.X + cs.polarArea.Width / 2; float yc = cs.polarArea.Y + cs.polarArea.Height / 2; Pen aPen = null; SolidBrush aBrush = null; // Plot lines: //雷达图 if (dc.PolarChartType == PolarChartTypeEnum.Radar || dc.PolarChartType == PolarChartTypeEnum.RadarPolygon) { foreach (DataSeries ds in dc.DataSeriesList) { aBrush = new SolidBrush(ds.FillColor); aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.LineThickness); aPen.DashStyle = ds.LineStyle.LinePattern; PointF[] pts = new PointF[ds.PointList.Count]; for (int i = 0; i < ds.PointList.Count; i++) { pts[i] = cs.Point2DR((PointF)ds.PointList[i], ra); } if (ds.LineStyle.IsVisible == true) { g.DrawPolygon(aPen, pts); } if (dc.PolarChartType == PolarChartTypeEnum.RadarPolygon) { g.FillPolygon(aBrush, pts); } } } //玫瑰图 else if (dc.PolarChartType == PolarChartTypeEnum.Rose) { Dictionary <float, float> rSum = new Dictionary <float, float>(); for (int a = 0; a < 360 / ra.AngleStep; a++) { rSum.Add(a * ra.AngleStep, 0); } foreach (DataSeries ds in dc.DataSeriesList) { foreach (PointF p in ds.PointList) { if (p.Y < 0) { return; } if (rSum.ContainsKey(p.X)) { rSum[p.X] += p.Y; } else { return; } } } for (int i = dc.DataSeriesList.Count - 1; i >= 0; i--) { DataSeries ds = (DataSeries)dc.DataSeriesList[i]; aBrush = new SolidBrush(ds.FillColor); aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.LineThickness); aPen.DashStyle = ds.LineStyle.LinePattern; //ds.LineStyle.IsVisible = false; float sweepAngle = ra.AngleStep * dc.RoseBarWidth; float pStartAngle = 0; int pBarLeng = 0; foreach (PointF p in ds.PointList) { pStartAngle = p.X + ra.StartAngle - sweepAngle / 2; pBarLeng = (int)Math.Ceiling(cs.RNorm(rSum[p.X], ra)); Rectangle rect1 = new Rectangle((int)xc - pBarLeng, (int)yc - pBarLeng, pBarLeng * 2, pBarLeng * 2); g.FillPie(aBrush, rect1, pStartAngle, sweepAngle); if (ds.LineStyle.IsVisible) { g.DrawPie(aPen, rect1, pStartAngle, sweepAngle); } rSum[p.X] -= p.Y; } } } //曲线图 else if (dc.PolarChartType == PolarChartTypeEnum.Spline) { foreach (DataSeries ds in dc.DataSeriesList) { aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.LineThickness); aPen.DashStyle = ds.LineStyle.LinePattern; PointF[] pts = new PointF[ds.PointList.Count]; if (ds.LineStyle.IsVisible == true) { for (int i = 0; i < ds.PointList.Count; i++) { pts[i] = cs.Point2DR((PointF)ds.PointList[i], ra); } g.DrawClosedCurve(aPen, pts); } } } // Plot Symbols: if (dc.PolarChartType == PolarChartTypeEnum.Radar || dc.PolarChartType == PolarChartTypeEnum.Spline) { foreach (DataSeries ds in dc.DataSeriesList) { for (int i = 0; i < ds.PointList.Count; i++) { PointF pt = cs.Point2DR((PointF)ds.PointList[i], ra); if (!pt.IsEmpty) { ds.SymbolStyle.DrawSymbol(g, pt); } } } } if (aPen != null) { aPen.Dispose(); } if (aBrush != null) { aBrush.Dispose(); } }
/// <summary> /// 绘制矩形图,根据BarChartType和ds数量确定Bar绘制方式。 /// 当BarChartType为Vertical或Horizontal,且ds数量大于1时,为多组柱图;其余情况为单柱图 /// </summary> /// <param name="dc"></param> /// <param name="g"></param> /// <param name="cs"></param> /// <param name="xa"></param> /// <param name="ya"></param> internal static void AddBars(DataCollectionBar dc, Graphics g, ChartStyle cs, XAxis xa, YAxis ya, Y2Axis y2a) { int numberOfDataSeries = dc.DataSeriesList.Count; //比较各列个数,柱状图需统一个数,以最多个数为准 int nPoints = 0; bool isConsistant = true; bool isY2 = false; foreach (DataSeries ds in dc.DataSeriesList) { if (nPoints < ds.PointList.Count) { nPoints = ds.PointList.Count; } if (ds.IsY2Data) { isY2 = true; } } // Draw bars: ArrayList temp = new ArrayList(); float[] tempy = new float[nPoints]; PointF temppt = new PointF(); int n = 0; foreach (DataSeries ds in dc.DataSeriesList) { Pen aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.LineThickness); aPen.DashStyle = ds.LineStyle.LinePattern; SolidBrush aBrush; if (ds.FillColor != Color.Empty) { aBrush = new SolidBrush(ds.FillColor); } else { aBrush = new SolidBrush(Color.FromArgb(180, ds.LineStyle.LineColor)); } PointF[] pts = new PointF[4]; PointF pt; float width; if (dc.BarChartType == BarChartTypeEnum.Vertical) { if (numberOfDataSeries == 1) { width = (float)xa.XTick * dc.BarWidth; if (!isY2) { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; float x = pt.X - xa.XTick / 2; pts[0] = cs.Point2D(new PointF(x - width / 2, 0), xa, ya); pts[1] = cs.Point2D(new PointF(x + width / 2, 0), xa, ya); pts[2] = cs.Point2D(new PointF(x + width / 2, pt.Y), xa, ya); pts[3] = cs.Point2D(new PointF(x - width / 2, pt.Y), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; float x = pt.X - xa.XTick / 2; pts[0] = cs.Point2DY2(new PointF(x - width / 2, 0), xa, y2a); pts[1] = cs.Point2DY2(new PointF(x + width / 2, 0), xa, y2a); pts[2] = cs.Point2DY2(new PointF(x + width / 2, pt.Y), xa, y2a); pts[3] = cs.Point2DY2(new PointF(x - width / 2, pt.Y), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } } else if (numberOfDataSeries > 1) { //width = 0.7f * (float)xa.XTick; dc.BarWidth = (dc.BarWidth > 0 && dc.BarWidth <= 1) ? dc.BarWidth : 0.95f; width = (float)xa.XTick * dc.BarWidth; if (!isY2) { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; float x = pt.X;// - (float)xa.XTick / 2 float w1 = width / numberOfDataSeries; float w = dc.BarWidth * w1; float space = (w1 - w) / 2; pts[0] = cs.Point2D(new PointF(x - width / 2 + space + n * w1, 0), xa, ya); pts[1] = cs.Point2D(new PointF(x - width / 2 + space + n * w1 + w, 0), xa, ya); pts[2] = cs.Point2D(new PointF(x - width / 2 + space + n * w1 + w, pt.Y), xa, ya); pts[3] = cs.Point2D(new PointF(x - width / 2 + space + n * w1, pt.Y), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; float x = pt.X - (float)xa.XTick / 2; float w1 = width / numberOfDataSeries; float w = dc.BarWidth * w1; float space = (w1 - w) / 2; pts[0] = cs.Point2DY2(new PointF(x - width / 2 + space + n * w1, 0), xa, y2a); pts[1] = cs.Point2DY2(new PointF(x - width / 2 + space + n * w1 + w, 0), xa, y2a); pts[2] = cs.Point2DY2(new PointF(x - width / 2 + space + n * w1 + w, pt.Y), xa, y2a); pts[3] = cs.Point2DY2(new PointF(x - width / 2 + space + n * w1, pt.Y), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } } } else if (dc.BarChartType == BarChartTypeEnum.VerticalOverlay && numberOfDataSeries > 1) { width = (float)xa.XTick * dc.BarWidth; width = width / (float)Math.Pow(2, n); if (!isY2) { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; float x = pt.X - xa.XTick / 2; pts[0] = cs.Point2D(new PointF(x - width / 2, 0), xa, ya); pts[1] = cs.Point2D(new PointF(x + width / 2, 0), xa, ya); pts[2] = cs.Point2D(new PointF(x + width / 2, pt.Y), xa, ya); pts[3] = cs.Point2D(new PointF(x - width / 2, pt.Y), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; float x = pt.X - xa.XTick / 2; pts[0] = cs.Point2DY2(new PointF(x - width / 2, 0), xa, y2a); pts[1] = cs.Point2DY2(new PointF(x + width / 2, 0), xa, y2a); pts[2] = cs.Point2DY2(new PointF(x + width / 2, pt.Y), xa, y2a); pts[3] = cs.Point2DY2(new PointF(x - width / 2, pt.Y), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } } else if (dc.BarChartType == BarChartTypeEnum.VerticalStack && numberOfDataSeries > 1) { width = xa.XTick * dc.BarWidth; if (!isY2) { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; if (temp.Count > 0) { tempy[i] = tempy[i] + ((PointF)temp[i]).Y; } float x = pt.X - xa.XTick / 2; pts[0] = cs.Point2D(new PointF(x - width / 2, 0 + tempy[i]), xa, ya); pts[1] = cs.Point2D(new PointF(x + width / 2, 0 + tempy[i]), xa, ya); pts[2] = cs.Point2D(new PointF(x + width / 2, pt.Y + tempy[i]), xa, ya); pts[3] = cs.Point2D(new PointF(x - width / 2, pt.Y + tempy[i]), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; if (temp.Count > 0) { tempy[i] = tempy[i] + ((PointF)temp[i]).Y; } float x = pt.X - xa.XTick / 2; pts[0] = cs.Point2DY2(new PointF(x - width / 2, 0 + tempy[i]), xa, y2a); pts[1] = cs.Point2DY2(new PointF(x + width / 2, 0 + tempy[i]), xa, y2a); pts[2] = cs.Point2DY2(new PointF(x + width / 2, pt.Y + tempy[i]), xa, y2a); pts[3] = cs.Point2DY2(new PointF(x - width / 2, pt.Y + tempy[i]), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } temp = ds.PointList; } else if (dc.BarChartType == BarChartTypeEnum.Horizontal) { if (numberOfDataSeries == 1) { if (!isY2) { width = ya.YTick * dc.BarWidth; for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); float y = pt.Y - ya.YTick / 2; pts[0] = cs.Point2D(new PointF(0, y - width / 2), xa, ya); pts[1] = cs.Point2D(new PointF(0, y + width / 2), xa, ya); pts[2] = cs.Point2D(new PointF(pt.X, y + width / 2), xa, ya); pts[3] = cs.Point2D(new PointF(pt.X, y - width / 2), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { width = y2a.Y2Tick * dc.BarWidth; for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); float y = pt.Y - y2a.Y2Tick / 2; pts[0] = cs.Point2DY2(new PointF(0, y - width / 2), xa, y2a); pts[1] = cs.Point2DY2(new PointF(0, y + width / 2), xa, y2a); pts[2] = cs.Point2DY2(new PointF(pt.X, y + width / 2), xa, y2a); pts[3] = cs.Point2DY2(new PointF(pt.X, y - width / 2), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } } else if (numberOfDataSeries > 1) { //width = 0.7f * ya.YTick; dc.BarWidth = (dc.BarWidth > 0 && dc.BarWidth <= 1) ? dc.BarWidth : 0.95f; if (!isY2) { width = (float)ya.YTick * dc.BarWidth; for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); float w1 = width / numberOfDataSeries; float w = dc.BarWidth * w1; float space = (w1 - w) / 2; float y = pt.Y - ya.YTick / 2; pts[0] = cs.Point2D(new PointF(0, y - width / 2 + space + n * w1), xa, ya); pts[1] = cs.Point2D(new PointF(0, y - width / 2 + space + n * w1 + w), xa, ya); pts[2] = cs.Point2D(new PointF(pt.X, y - width / 2 + space + n * w1 + w), xa, ya); pts[3] = cs.Point2D(new PointF(pt.X, y - width / 2 + space + n * w1), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { width = (float)y2a.Y2Tick * dc.BarWidth; for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); float w1 = width / numberOfDataSeries; float w = dc.BarWidth * w1; float space = (w1 - w) / 2; float y = pt.Y - y2a.Y2Tick / 2; pts[0] = cs.Point2DY2(new PointF(0, y - width / 2 + space + n * w1), xa, y2a); pts[1] = cs.Point2DY2(new PointF(0, y - width / 2 + space + n * w1 + w), xa, y2a); pts[2] = cs.Point2DY2(new PointF(pt.X, y - width / 2 + space + n * w1 + w), xa, y2a); pts[3] = cs.Point2DY2(new PointF(pt.X, y - width / 2 + space + n * w1), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } } } else if (dc.BarChartType == BarChartTypeEnum.HorizontalOverlay && numberOfDataSeries > 1) { if (!isY2) { width = ya.YTick * dc.BarWidth; width = width / (float)Math.Pow(2, n); for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); float y = pt.Y - ya.YTick / 2; pts[0] = cs.Point2D(new PointF(0, y - width / 2), xa, ya); pts[1] = cs.Point2D(new PointF(0, y + width / 2), xa, ya); pts[2] = cs.Point2D(new PointF(pt.X, y + width / 2), xa, ya); pts[3] = cs.Point2D(new PointF(pt.X, y - width / 2), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { width = y2a.Y2Tick * dc.BarWidth; width = width / (float)Math.Pow(2, n); for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); float y = pt.Y - y2a.Y2Tick / 2; pts[0] = cs.Point2DY2(new PointF(0, y - width / 2), xa, y2a); pts[1] = cs.Point2DY2(new PointF(0, y + width / 2), xa, y2a); pts[2] = cs.Point2DY2(new PointF(pt.X, y + width / 2), xa, y2a); pts[3] = cs.Point2DY2(new PointF(pt.X, y - width / 2), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } } else if (dc.BarChartType == BarChartTypeEnum.HorizontalStack && numberOfDataSeries > 1) { if (!isY2) { width = ya.YTick * dc.BarWidth; for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); if (temp.Count > 0) { temppt = (PointF)temp[i]; tempy[i] = tempy[i] + temppt.Y; } float y = pt.Y - ya.YTick / 2; pts[0] = cs.Point2D(new PointF(0 + tempy[i], y - width / 2), xa, ya); pts[1] = cs.Point2D(new PointF(0 + tempy[i], y + width / 2), xa, ya); pts[2] = cs.Point2D(new PointF(pt.X + tempy[i], y + width / 2), xa, ya); pts[3] = cs.Point2D(new PointF(pt.X + tempy[i], y - width / 2), xa, ya); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } else { width = y2a.Y2Tick * dc.BarWidth; for (int i = 0; i < ds.PointList.Count; i++) { temppt = (PointF)ds.PointList[i]; pt = new PointF(temppt.Y, temppt.X); if (temp.Count > 0) { temppt = (PointF)temp[i]; tempy[i] = tempy[i] + temppt.Y; } float y = pt.Y - y2a.Y2Tick / 2; pts[0] = cs.Point2DY2(new PointF(0 + tempy[i], y - width / 2), xa, y2a); pts[1] = cs.Point2DY2(new PointF(0 + tempy[i], y + width / 2), xa, y2a); pts[2] = cs.Point2DY2(new PointF(pt.X + tempy[i], y + width / 2), xa, y2a); pts[3] = cs.Point2DY2(new PointF(pt.X + tempy[i], y - width / 2), xa, y2a); g.FillPolygon(aBrush, pts); if (ds.LineStyle.IsVisible) { g.DrawPolygon(aPen, pts); } } } temp = ds.PointList; } n++; aPen.Dispose(); aBrush.Dispose(); } }
//绘制线性图 internal static void AddLines(DataCollection dc, Graphics g, ChartStyle cs, XAxis xa, YAxis ya, Y2Axis y2a) { if (dc.ChartType != Chart2DTypeEnum.LineChart || dc.DataSeriesList.Count == 0) { return; } //SeriesColor.SetSeriesColor(dc); // Plot lines: foreach (DataSeries ds in dc.DataSeriesList) { if (ds.LineStyle.IsVisible == true) { PointF pt = new PointF(); PointF pt0 = new PointF(); Pen aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.LineThickness); aPen.DashStyle = ds.LineStyle.LinePattern; #region line // Plot Line: if (ds.LineChartType == LineChartTypeEnum.Line) { for (int i = 1; i < ds.PointList.Count; i++) { if (!ds.IsY2Data) { g.DrawLine(aPen, cs.Point2D((PointF)ds.PointList[i - 1], xa, ya), cs.Point2D((PointF)ds.PointList[i], xa, ya)); } else { g.DrawLine(aPen, cs.Point2DY2((PointF)ds.PointList[i - 1], xa, y2a), cs.Point2DY2((PointF)ds.PointList[i], xa, y2a)); } } } // Plot Spline: else if (ds.LineChartType == LineChartTypeEnum.Spline) { PointF[] pts = new PointF[ds.PointList.Count]; for (int i = 0; i < pts.Length; i++) { if (!ds.IsY2Data) { pts[i] = cs.Point2D((PointF)(ds.PointList[i]), xa, ya); } else { pts[i] = cs.Point2DY2((PointF)(ds.PointList[i]), xa, y2a); } } g.DrawCurve(aPen, pts); } #endregion #region Stairstep // Plot Stairstep: else if (ds.LineChartType == LineChartTypeEnum.StairStep) { ArrayList aList = new ArrayList(); if (!ds.IsY2Data) { // Create Stairstep data: for (int i = 0; i < ds.PointList.Count - 1; i++) { pt = (PointF)ds.PointList[i]; pt0 = (PointF)ds.PointList[i + 1]; aList.Add(pt); aList.Add(new PointF(pt0.X, pt.Y)); } aList.Add(ds.PointList[ds.PointList.Count - 1]); // Draw stairstep chart: for (int i = 1; i < aList.Count; i++) { g.DrawLine(aPen, cs.Point2D((PointF)aList[i - 1], xa, ya), cs.Point2D((PointF)aList[i], xa, ya)); } } else { for (int i = 0; i < ds.PointList.Count - 1; i++) { pt = (PointF)ds.PointList[i]; pt0 = (PointF)ds.PointList[i + 1]; aList.Add(pt); aList.Add(new PointF(pt0.X, pt.Y)); } aList.Add(ds.PointList[ds.PointList.Count - 1]); for (int i = 1; i < aList.Count; i++) { g.DrawLine(aPen, cs.Point2DY2((PointF)aList[i - 1], xa, y2a), cs.Point2DY2((PointF)aList[i], xa, y2a)); } } } #endregion #region Stem // Plot Stems: else if (ds.LineChartType == LineChartTypeEnum.Stem) { if (!ds.IsY2Data) { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; pt0 = new PointF(pt.X, 0); g.DrawLine(aPen, cs.Point2D(pt0, xa, ya), cs.Point2D(pt, xa, ya)); } } else { for (int i = 0; i < ds.PointList.Count; i++) { pt = (PointF)ds.PointList[i]; pt0 = new PointF(pt.X, 0); g.DrawLine(aPen, cs.Point2DY2(pt0, xa, y2a), cs.Point2DY2(pt, xa, y2a)); } } } #endregion #region ErrorBar //Plot ErrorBar else if (ds.LineChartType == LineChartTypeEnum.ErrorBar) { Pen errorPen = new Pen(ds.ErrorLineStyle.LineColor, ds.ErrorLineStyle.LineThickness); errorPen.DashStyle = ds.ErrorLineStyle.LinePattern; float barLength = 0; if (!ds.IsY2Data) { // Draw lines: for (int i = 1; i < ds.PointList.Count; i++) { pt0 = (PointF)ds.PointList[i - 1]; pt = (PointF)ds.PointList[i]; g.DrawLine(aPen, cs.Point2D(pt0, xa, ya), cs.Point2D(pt, xa, ya)); barLength = (pt.X - pt0.X) / 4; } // Draw error lines: for (int i = 0; i < ds.ErrorList.Count; i++) { PointF errorPoint = (PointF)ds.ErrorList[i]; PointF linePoint = (PointF)ds.PointList[i]; pt0 = new PointF(linePoint.X, linePoint.Y - errorPoint.Y / 2); pt = new PointF(linePoint.X, linePoint.Y + errorPoint.Y / 2); g.DrawLine(errorPen, cs.Point2D(pt0, xa, ya), cs.Point2D(pt, xa, ya)); PointF pt1 = new PointF(pt0.X - barLength / 2, pt0.Y); PointF pt2 = new PointF(pt0.X + barLength / 2, pt0.Y); g.DrawLine(errorPen, cs.Point2D(pt1, xa, ya), cs.Point2D(pt2, xa, ya)); pt1 = new PointF(pt.X - barLength / 2, pt.Y); pt2 = new PointF(pt.X + barLength / 2, pt.Y); g.DrawLine(errorPen, cs.Point2D(pt1, xa, ya), cs.Point2D(pt2, xa, ya)); } } else { for (int i = 1; i < ds.PointList.Count; i++) { pt0 = (PointF)ds.PointList[i - 1]; pt = (PointF)ds.PointList[i]; g.DrawLine(aPen, cs.Point2DY2(pt0, xa, y2a), cs.Point2DY2(pt, xa, y2a)); barLength = (pt.X - pt0.X) / 4; } for (int i = 0; i < ds.ErrorList.Count; i++) { PointF errorPoint = (PointF)ds.ErrorList[i]; PointF linePoint = (PointF)ds.PointList[i]; pt0 = new PointF(linePoint.X, linePoint.Y - errorPoint.Y / 2); pt = new PointF(linePoint.X, linePoint.Y + errorPoint.Y / 2); g.DrawLine(errorPen, cs.Point2DY2(pt0, xa, y2a), cs.Point2DY2(pt, xa, y2a)); PointF pt1 = new PointF(pt0.X - barLength / 2, pt0.Y); PointF pt2 = new PointF(pt0.X + barLength / 2, pt0.Y); g.DrawLine(errorPen, cs.Point2DY2(pt1, xa, y2a), cs.Point2DY2(pt2, xa, y2a)); pt1 = new PointF(pt.X - barLength / 2, pt.Y); pt2 = new PointF(pt.X + barLength / 2, pt.Y); g.DrawLine(errorPen, cs.Point2DY2(pt1, xa, y2a), cs.Point2DY2(pt2, xa, y2a)); } } errorPen.Dispose(); } #endregion #region Stock else if ((ds.LineChartType == LineChartTypeEnum.HiLo || ds.LineChartType == LineChartTypeEnum.HiLoOpenClose || ds.LineChartType == LineChartTypeEnum.Candle) && ds.DataString != null) { SolidBrush aBrush = new SolidBrush(ds.LineStyle.LineColor); SolidBrush whiteBrush = new SolidBrush(Color.White); float barLength = cs.PlotArea.Width / (5 * ds.DataString.GetLength(1)); for (int i = 0; i < ds.DataString.GetLength(1); i++) { float[] stockdata = new float[4]; for (int j = 0; j < stockdata.Length; j++) { stockdata[j] = Convert.ToSingle(ds.DataString[j + 1, i]); } PointF ptHigh, ptLow, ptOpen, ptCLose; if (!ds.IsY2Data) { ptHigh = cs.Point2D(new PointF(i, stockdata[1]), xa, ya); ptLow = cs.Point2D(new PointF(i, stockdata[2]), xa, ya); ptOpen = cs.Point2D(new PointF(i, stockdata[0]), xa, ya); ptCLose = cs.Point2D(new PointF(i, stockdata[3]), xa, ya); } else { ptHigh = cs.Point2DY2(new PointF(i, stockdata[1]), xa, y2a); ptLow = cs.Point2DY2(new PointF(i, stockdata[2]), xa, y2a); ptOpen = cs.Point2DY2(new PointF(i, stockdata[0]), xa, y2a); ptCLose = cs.Point2DY2(new PointF(i, stockdata[3]), xa, y2a); } PointF ptOpen1 = new PointF(ptOpen.X - barLength, ptOpen.Y); PointF ptClose1 = new PointF(ptCLose.X + barLength, ptCLose.Y); PointF ptOpen2 = new PointF(ptOpen.X + barLength, ptOpen.Y); PointF ptClose2 = new PointF(ptCLose.X - barLength, ptCLose.Y); // Draw Hi-Lo stock chart: if (ds.LineChartType == LineChartTypeEnum.HiLo) { g.DrawLine(aPen, ptHigh, ptLow); } // Draw Hi-Li-Open-Close chart: else if (ds.LineChartType == LineChartTypeEnum.HiLoOpenClose) { g.DrawLine(aPen, ptHigh, ptLow); g.DrawLine(aPen, ptOpen, ptOpen1); g.DrawLine(aPen, ptCLose, ptClose1); } // Draw candle chart: else if (ds.LineChartType == LineChartTypeEnum.Candle) { PointF[] pts = new PointF[4]; pts[0] = ptOpen1; pts[1] = ptOpen2; pts[2] = ptClose1; pts[3] = ptClose2; g.DrawLine(aPen, ptHigh, ptLow); if (stockdata[0] > stockdata[3]) { g.FillPolygon(aBrush, pts); } else if (stockdata[0] < stockdata[3]) { g.FillPolygon(whiteBrush, pts); } g.DrawPolygon(aPen, pts); } } aBrush.Dispose(); whiteBrush.Dispose(); } #endregion aPen.Dispose(); } } // Plot Symbols: foreach (DataSeries ds in dc.DataSeriesList) { if (ds.LineChartType != LineChartTypeEnum.HiLo && ds.LineChartType != LineChartTypeEnum.HiLoOpenClose && ds.LineChartType != LineChartTypeEnum.Candle) { for (int i = 0; i < ds.PointList.Count; i++) { PointF pt = (PointF)ds.PointList[i]; if (!ds.IsY2Data) { if (pt.X >= xa.XLimMin && pt.X <= xa.XLimMax && pt.Y >= ya.YLimMin && pt.Y <= ya.YLimMax) { ds.SymbolStyle.DrawSymbol(g, cs.Point2D((PointF)ds.PointList[i], xa, ya)); } } else { if (pt.X >= xa.XLimMin && pt.X <= xa.XLimMax && pt.Y >= y2a.Y2LimMin && pt.Y <= y2a.Y2LimMax) { ds.SymbolStyle.DrawSymbol(g, cs.Point2DY2((PointF)ds.PointList[i], xa, y2a)); } } } } } }