/// <summary> /// 初始化样式布局(默认为直角坐标,无图例) /// </summary> /// <param name="g"></param> /// <param name="xa"></param> /// <param name="ya"></param> /// <param name="y2a"></param> /// <param name="gd"></param> /// <param name="lb"></param> /// <param name="tl"></param> internal void AddChartStyle(Graphics g, Title tl, XYLabel lb, Grid gd, XAxis xa, YAxis ya, Y2Axis y2a) { //设置绘图区位置、大小 SetPlotArea(g, tl, lb, gd, xa, ya, y2a); //ChartArea和PlotArea底色绘制(通用) FillColorInChartAreas(g); //直角坐标通用网格线 AddGirdSquare(g, gd, xa, ya); //绘制x,y,y2 轴刻度线和标记 float fX, fY; SolidBrush aBrush = new SolidBrush(xa.XTickStyle.TextColor); for (fX = xa.XLimMin; fX <= xa.XLimMax; fX += xa.XTick) { fX = DataDeal.FloatAccur(fX); PointF yAxisPoint = Point2D(new PointF(fX, ya.YLimMin), xa, ya); g.DrawLine(Pens.Black, yAxisPoint, new PointF(yAxisPoint.X, yAxisPoint.Y - 5f)); StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Far; SizeF sizeXTick = g.MeasureString(fX.ToString(), xa.XTickStyle.TextFont); g.DrawString(fX.ToString(), xa.XTickStyle.TextFont, aBrush, new PointF(yAxisPoint.X + sizeXTick.Width / 2, yAxisPoint.Y + 4f), sFormat); } aBrush = new SolidBrush(ya.YTickStyle.TextColor); SizeF tickFontSize = g.MeasureString("A", ya.YTickStyle.TextFont); for (fY = ya.YLimMin; fY <= ya.YLimMax; fY += ya.YTick) { fY = DataDeal.FloatAccur(fY); PointF xAxisPoint = Point2D(new PointF(xa.XLimMin, fY), xa, ya); g.DrawLine(Pens.Black, xAxisPoint, new PointF(xAxisPoint.X + 5f, xAxisPoint.Y)); StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Far; g.DrawString(fY.ToString(), ya.YTickStyle.TextFont, aBrush, new PointF(xAxisPoint.X - 3f, xAxisPoint.Y - tickFontSize.Height / 2), sFormat); } if (y2a.IsY2Axis) { aBrush = new SolidBrush(y2a.Y2TickStyle.TextColor); tickFontSize = g.MeasureString("A", y2a.Y2TickStyle.TextFont); for (fY = y2a.Y2LimMin; fY <= y2a.Y2LimMax; fY += y2a.Y2Tick) { fY = DataDeal.FloatAccur(fY); PointF x2AxisPoint = Point2DY2(new PointF(xa.XLimMax, fY), xa, y2a); g.DrawLine(Pens.Black, x2AxisPoint, new PointF(x2AxisPoint.X - 5f, x2AxisPoint.Y)); StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Near; g.DrawString(fY.ToString(), y2a.Y2TickStyle.TextFont, aBrush, new PointF(x2AxisPoint.X + 3f, x2AxisPoint.Y - tickFontSize.Height / 2), sFormat); } } aBrush.Dispose(); AddTitle(g, tl); AddLabels(g, tl, lb, y2a); }
/// <summary> /// 绘制标签(无图例影响的默认位置) /// </summary> /// <param name="g"></param> /// <param name="tl"></param> /// <param name="lb"></param> /// <param name="y2a"></param> private void AddLabels(Graphics g, Title tl, XYLabel lb, Y2Axis y2a) { StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Center; SizeF titleFontSize = g.MeasureString("A", tl.TitleStyle.TextFont); SolidBrush aBrush = new SolidBrush(lb.XYLabelStyle.TextColor); //添加x轴标签 SizeF labelFontSize = g.MeasureString("A", lb.XYLabelStyle.TextFont); if (lb.IsXLabelVisible) { if (string.IsNullOrWhiteSpace(lb.XLabel)) { lb.XLabel = "X Axis"; } g.DrawString(lb.XLabel, lb.XYLabelStyle.TextFont, aBrush, new Point(PlotArea.Left + PlotArea.Width / 2, ChartArea.Bottom - (int)YOffset - (int)labelFontSize.Height), sFormat); } //添加y轴标签 if (lb.IsYLabelVisible) { if (string.IsNullOrWhiteSpace(lb.YLabel)) { lb.YLabel = "Y Axis"; } // Save the state of the current Graphics object GraphicsState gState = g.Save(); g.TranslateTransform(ChartArea.X + XOffset, ChartArea.Y + YOffset + titleFontSize.Height + YOffset / 2 + PlotArea.Height / 2); g.RotateTransform(-90); g.DrawString(lb.YLabel, lb.XYLabelStyle.TextFont, aBrush, new Point(0, 0), sFormat); // Restore it: g.Restore(gState); } //添加y2轴标签 if (y2a.IsY2Axis) { if (lb.IsY2LabelVisible) { if (string.IsNullOrWhiteSpace(lb.Y2Label)) { lb.Y2Label = "Y2 Axis"; } // Save the state of the current Graphics object GraphicsState gState2 = g.Save(); g.TranslateTransform(ChartArea.X + ChartArea.Width - XOffset - labelFontSize.Width, ChartArea.Y + YOffset + titleFontSize.Height + YOffset / 2 + PlotArea.Height / 2); g.RotateTransform(-90); g.DrawString(lb.Y2Label, lb.XYLabelStyle.TextFont, aBrush, new Point(0, 0), sFormat); // Restore it: g.Restore(gState2); } } aBrush.Dispose(); }
/// <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); }
/// <summary> /// 直角坐标样式布局 /// </summary> /// <param name="g"></param> /// <param name="dcs"></param> /// <param name="xa"></param> /// <param name="ya"></param> /// <param name="y2a"></param> /// <param name="gd"></param> /// <param name="lb"></param> /// <param name="tl"></param> /// <param name="lg"></param> internal void AddChartStyleSquare(Graphics g, Title tl, XYLabel lb, Grid gd, XAxis xa, YAxis ya, Y2Axis y2a, Legend lg, List <DataCollection> dcs) { try { //设置直角坐标绘图区位置、大小(受元素之间的相互影响) SetPlotArea(g, tl, lb, xa, ya, y2a, gd, lg, dcs); //再次确定大小的原因:根据plot宽度->确定文本角度->重新确定plot高度 AxisFit.SetTickAngle(g, this, lb, xa); SetPlotArea(g, tl, lb, xa, ya, y2a, gd, lg, dcs); //ChartArea和PlotArea底色绘制(通用) FillColorInChartAreas(g); //绘制标题(通用) AddTitle(g, tl); //直角坐标通用网格线 AddGirdSquare(g, gd, xa, ya); //绘制轴标签(受图例影响) AddLabels(g, tl, lb, y2a, lg, dcs); //绘制坐标轴刻度线和标记(受数据影响) AddTicks(g, lb, xa, ya, y2a); } catch { } }
/// <summary> /// 绘制刻度线和标记(受数据影响) /// </summary> /// <param name="g"></param> /// <param name="lb"></param> /// <param name="xa"></param> /// <param name="ya"></param> /// <param name="y2a"></param> private void AddTicks(Graphics g, XYLabel lb, XAxis xa, YAxis ya, Y2Axis y2a) { float fX, fY; //绘制x轴刻度线和标记: SolidBrush aBrush = new SolidBrush(xa.XTickStyle.TextColor); SizeF sizeXTick; //出现在SetPlotArea和AddTicks中轴循环 //for(float xTick = xa.XLimMin; xTick <= xa.XLimMax; xTick += xa.XTick) //弃用原因1:防止Tick为0时出现死循环 //弃用原因2:float的精度损失程度累加 int count = (int)Math.Round((xa.XLimMax - xa.XLimMin) / xa.XTick) + 1; for (int i = 0; i < count; i++) { fX = xa.XLimMin + i * xa.XTick; fX = DataDeal.FloatAccur(fX); PointF yAxisPoint = Point2D(new PointF(fX, ya.YLimMin), xa, ya); g.DrawLine(Pens.Black, yAxisPoint, new PointF(yAxisPoint.X, yAxisPoint.Y - 5f)); StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Far; sizeXTick = g.MeasureString(xa.XTickMarkFull[i], xa.XTickStyle.TextFont); if (xa.XTickAngle != 0) { g.TranslateTransform(yAxisPoint.X, yAxisPoint.Y); //设置旋转中心为文字中心 g.RotateTransform(xa.XTickAngle); //旋转 //g.TranslateTransform(-yAxisPoint.X, -yAxisPoint.Y); g.DrawString(xa.XTickMarkFull[i], xa.XTickStyle.TextFont, aBrush, new PointF(0, 4f - sizeXTick.Height / 2), sFormat); g.ResetTransform(); } else { g.DrawString(xa.XTickMarkFull[i], xa.XTickStyle.TextFont, aBrush, new PointF(yAxisPoint.X + sizeXTick.Width / 2, yAxisPoint.Y + 4f), sFormat); } } SizeF tickFontSize = g.MeasureString("A", ya.YTickStyle.TextFont); //绘制y轴刻度线和标记: int ycount = (int)Math.Round((ya.YLimMax - ya.YLimMin) / ya.YTick) + 1; for (int i = 0; i < ycount; i++) { fY = ya.YLimMin + i * ya.YTick; fY = DataDeal.FloatAccur(fY); PointF xAxisPoint = Point2D(new PointF(xa.XLimMin, fY), xa, ya); g.DrawLine(Pens.Black, xAxisPoint, new PointF(xAxisPoint.X + 5f, xAxisPoint.Y)); StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Far; g.DrawString(fY.ToString(), ya.YTickStyle.TextFont, aBrush, new PointF(xAxisPoint.X - 3f, xAxisPoint.Y - tickFontSize.Height / 2), sFormat); } //绘制y2轴刻度线和标记: if (y2a.IsY2Axis) { int y2count = (int)Math.Round((y2a.Y2LimMax - y2a.Y2LimMin) / y2a.Y2Tick) + 1; for (int i = 0; i < y2count; i++) { fY = y2a.Y2LimMin + i * y2a.Y2Tick; fY = DataDeal.FloatAccur(fY); PointF x2AxisPoint = Point2DY2(new PointF(xa.XLimMax, fY), xa, y2a); g.DrawLine(Pens.Black, x2AxisPoint, new PointF(x2AxisPoint.X - 5f, x2AxisPoint.Y)); StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Near; g.DrawString(fY.ToString(), y2a.Y2TickStyle.TextFont, aBrush, new PointF(x2AxisPoint.X + 3f, x2AxisPoint.Y - tickFontSize.Height / 2), sFormat); } } aBrush.Dispose(); }
/// <summary> /// 绘制轴标签(受图例影响) /// </summary> /// <param name="g"></param> /// <param name="tl"></param> /// <param name="lb"></param> /// <param name="y2a"></param> /// <param name="lg"></param> /// <param name="dcs"></param> private void AddLabels(Graphics g, Title tl, XYLabel lb, Y2Axis y2a, Legend lg, List <DataCollection> dcs) { StringFormat sFormat = new StringFormat(); sFormat.Alignment = StringAlignment.Center; SolidBrush aBrush = new SolidBrush(lb.XYLabelStyle.TextColor); SizeF labelFontSize = g.MeasureString("A", lb.XYLabelStyle.TextFont); float stringX; float stringY; SizeF titleFontSize = g.MeasureString("A", tl.TitleStyle.TextFont); //图例对标题的影响 float legendWidth = 0; float legendHeight = 0; if (lg.IsLegendVisible && !lg.IsInside) { lg.GetLegendSize(g, dcs, this, out legendWidth, out legendHeight); } //添加x轴标签 if (lb.IsXLabelVisible) { if (string.IsNullOrWhiteSpace(lb.XLabel)) { lb.XLabel = "X Axis"; } stringX = PlotArea.Left + PlotArea.Width / 2; stringY = ChartArea.Bottom - (int)YOffset - (int)labelFontSize.Height; if (lg.LegendPosition == Legend.LegendPositionEnum.South) { stringY -= legendHeight; } g.DrawString(lb.XLabel, lb.XYLabelStyle.TextFont, aBrush, stringX, stringY, sFormat); } //添加y轴标签 if (string.IsNullOrWhiteSpace(lb.YLabel)) { lb.YLabel = "Y Axis"; } stringX = ChartArea.X + XOffset; stringY = ChartArea.Y + YOffset + titleFontSize.Height + YOffset / 3 + PlotArea.Height / 2; if (lg.LegendPosition == Legend.LegendPositionEnum.West || lg.LegendPosition == Legend.LegendPositionEnum.SouthWest || lg.LegendPosition == Legend.LegendPositionEnum.NorthWest) { stringX += legendWidth; } if (lg.LegendPosition == Legend.LegendPositionEnum.North) { stringY += legendHeight; } // Save the state of the current Graphics object GraphicsState gState = g.Save(); g.TranslateTransform(stringX, stringY); g.RotateTransform(-90); g.DrawString(lb.YLabel, lb.XYLabelStyle.TextFont, aBrush, 0, 0, sFormat); // Restore it: g.Restore(gState); //添加y2轴标签 if (y2a.IsY2Axis) { if (string.IsNullOrWhiteSpace(lb.Y2Label)) { lb.Y2Label = "Y2 Axis"; } stringX = ChartArea.X + ChartArea.Width - XOffset - labelFontSize.Height; stringY = ChartArea.Y + YOffset + titleFontSize.Height + YOffset / 3 + PlotArea.Height / 2; if (lg.LegendPosition == Legend.LegendPositionEnum.East || lg.LegendPosition == Legend.LegendPositionEnum.SouthEast || lg.LegendPosition == Legend.LegendPositionEnum.NorthEast) { stringX -= legendWidth; } if (lg.LegendPosition == Legend.LegendPositionEnum.North) { stringY += legendHeight; } // Save the state of the current Graphics object GraphicsState gState2 = g.Save(); g.TranslateTransform(stringX, stringY); g.RotateTransform(-90); g.DrawString(lb.Y2Label, lb.XYLabelStyle.TextFont, aBrush, 0, 0, sFormat); // Restore it: g.Restore(gState2); } aBrush.Dispose(); }
/// <summary> /// 设置直角坐标绘图区位置、大小(受元素之间的相互影响) /// </summary> /// <param name="g"></param> /// <param name="tl"></param> /// <param name="lb"></param> /// <param name="xa"></param> /// <param name="ya"></param> /// <param name="y2a"></param> /// <param name="gd"></param> /// <param name="lg"></param> /// <param name="dcs"></param> private void SetPlotArea(Graphics g, Title tl, XYLabel lb, XAxis xa, YAxis ya, Y2Axis y2a, Grid gd, Legend lg, List <DataCollection> dcs) { SizeF titleFontSize = g.MeasureString("A", tl.TitleStyle.TextFont); if (string.IsNullOrWhiteSpace(tl.TitleName) || tl.TitleName.ToUpper() == "NO TITLE") { titleFontSize.Width = 8f; titleFontSize.Height = 8f; } float xSpacing = XOffset / 2.0f; float ySpacing = YOffset / 2.0f; SizeF labelFontSize = g.MeasureString("A", lb.XYLabelStyle.TextFont); SizeF tickFontSize = g.MeasureString("A", xa.XTickStyle.TextFont); float tickSpacing = 2f; //图例所在位置影响plotarea的大小和位置 #region 受图例影响时 if (!lg.IsLegendVisible || lg.IsInside) { //X轴标记的自适应和全显示,影响底部间距 //float bottomMargin = YOffset + xlabelFontSize.Height + ySpacing + tickFontSize.Height + tickSpacing; float bottomMargin = YOffset + tickSpacing + ySpacing; if (lb.IsXLabelVisible) { bottomMargin += labelFontSize.Height; } SizeF xTickSize = g.MeasureString(xa.XLimMin.ToString(), xa.XTickStyle.TextFont); int xcount = (int)Math.Round((xa.XLimMax - xa.XLimMin) / xa.XTick) + 1; for (int i = 0; i < xcount; i++) { SizeF tempSize = g.MeasureString(xa.XTickMarkFull[i], xa.XTickStyle.TextFont); if (xTickSize.Width < tempSize.Width) { xTickSize = tempSize; } } if (xa.XTickAngle == 0) { bottomMargin += xTickSize.Height; } else if (xa.XTickAngle == -90) { bottomMargin += xTickSize.Width; } else { bottomMargin += xTickSize.Width * 0.72f; } //获取y轴标记宽度 SizeF yTickSize = g.MeasureString(ya.YLimMin.ToString(), ya.YTickStyle.TextFont); int ycount = (int)Math.Round((ya.YLimMax - ya.YLimMin) / ya.YTick) + 1; for (int i = 0; i < ycount; i++) { float yTick = ya.YLimMin + i * ya.YTick; SizeF tempSize = g.MeasureString(yTick.ToString(), ya.YTickStyle.TextFont); if (yTickSize.Width < tempSize.Width) { yTickSize = tempSize; } } float leftMargin = XOffset + labelFontSize.Height + xSpacing + yTickSize.Width + tickSpacing; float rightMargin = 2 * XOffset; float topMargin = YOffset + titleFontSize.Height + ySpacing; //单y轴绘图区 int plotX = ChartArea.X + (int)leftMargin; int plotY = ChartArea.Y + (int)topMargin; int plotHeight = ChartArea.Height - (int)topMargin - (int)bottomMargin; int plotWidth = ChartArea.Width - (int)leftMargin - (int)rightMargin; //双y轴:重新定义绘图区宽度 if (y2a.IsY2Axis) { //y2轴标记宽度 SizeF y2TickSize = g.MeasureString(y2a.Y2LimMin.ToString(), y2a.Y2TickStyle.TextFont); int y2count = (int)Math.Round((y2a.Y2LimMax - y2a.Y2LimMin) / y2a.Y2Tick) + 1; for (int i = 0; i < y2count; i++) { float y2Tick = y2a.Y2LimMin + i * y2a.Y2Tick; SizeF tempSize2 = g.MeasureString(y2Tick.ToString(), y2a.Y2TickStyle.TextFont); if (y2TickSize.Width < tempSize2.Width) { y2TickSize = tempSize2; } } rightMargin = XOffset + labelFontSize.Height + xSpacing + y2TickSize.Width + tickSpacing; plotWidth = ChartArea.Width - (int)leftMargin - (int)rightMargin; } plotArea = new Rectangle(plotX, plotY, plotWidth, plotHeight); } #endregion #region 外部图例 else { //X轴标记的自适应和全显示,影响底部间距bottom float bottomMargin = YOffset + tickSpacing + ySpacing; if (lb.IsXLabelVisible) { bottomMargin += labelFontSize.Height; } SizeF xTickSize = g.MeasureString(xa.XLimMin.ToString(), xa.XTickStyle.TextFont); int count = (int)Math.Round((xa.XLimMax - xa.XLimMin) / xa.XTick) + 1; for (int i = 0; i < count; i++) { SizeF tempSize = g.MeasureString(xa.XTickMarkFull[i], xa.XTickStyle.TextFont); if (xTickSize.Width < tempSize.Width) { xTickSize = tempSize; } } if (xa.XTickAngle == 0) { bottomMargin += xTickSize.Height; } else if (xa.XTickAngle == -90) { bottomMargin += xTickSize.Width; } else { bottomMargin += xTickSize.Width * 0.72f; } //获取y轴标记宽度 SizeF yTickSize = g.MeasureString(ya.YLimMin.ToString(), ya.YTickStyle.TextFont); int ycount = (int)Math.Round((ya.YLimMax - ya.YLimMin) / ya.YTick) + 1; for (int i = 0; i < ycount; i++) { float yTick = ya.YLimMin + i * ya.YTick; SizeF tempSize = g.MeasureString(yTick.ToString(), ya.YTickStyle.TextFont); if (yTickSize.Width < tempSize.Width) { yTickSize = tempSize; } } float leftMargin = XOffset + labelFontSize.Height + xSpacing + yTickSize.Width + tickSpacing; float rightMargin = XOffset + xSpacing; float topMargin = YOffset + titleFontSize.Height + ySpacing; //根据图例位置确定边距 float legendWidth = 0; float legendHeight = 0; lg.GetLegendSize(g, dcs, this, out legendWidth, out legendHeight); if (lg.LegendPosition == Legend.LegendPositionEnum.East || lg.LegendPosition == Legend.LegendPositionEnum.SouthEast || lg.LegendPosition == Legend.LegendPositionEnum.NorthEast) { rightMargin += legendWidth; } if (lg.LegendPosition == Legend.LegendPositionEnum.West || lg.LegendPosition == Legend.LegendPositionEnum.SouthWest || lg.LegendPosition == Legend.LegendPositionEnum.NorthWest) { leftMargin += legendWidth; } if (lg.LegendPosition == Legend.LegendPositionEnum.North) { topMargin += legendHeight; } if (lg.LegendPosition == Legend.LegendPositionEnum.South) { bottomMargin += legendHeight; } //单y轴绘图区大小 int plotX = ChartArea.X + (int)leftMargin; int plotY = ChartArea.Y + (int)topMargin; int plotHeight = ChartArea.Height - (int)topMargin - (int)bottomMargin; int plotWidth = ChartArea.Width - (int)leftMargin - (int)rightMargin; //双y轴:重新定义绘图区宽度 if (y2a.IsY2Axis) { //y2轴标记宽度 SizeF y2TickSize = g.MeasureString(y2a.Y2LimMin.ToString(), y2a.Y2TickStyle.TextFont); int y2count = (int)Math.Round((y2a.Y2LimMax - y2a.Y2LimMin) / y2a.Y2Tick) + 1; for (int i = 0; i < y2count; i++) { float y2Tick = y2a.Y2LimMin + i * y2a.Y2Tick; SizeF tempSize2 = g.MeasureString(y2Tick.ToString(), y2a.Y2TickStyle.TextFont); if (y2TickSize.Width < tempSize2.Width) { y2TickSize = tempSize2; } } rightMargin = XOffset + labelFontSize.Height + xSpacing + y2TickSize.Width + tickSpacing; if (lg.LegendPosition == Legend.LegendPositionEnum.East || lg.LegendPosition == Legend.LegendPositionEnum.SouthEast || lg.LegendPosition == Legend.LegendPositionEnum.NorthEast) { rightMargin += legendWidth; } plotWidth = ChartArea.Width - (int)leftMargin - (int)rightMargin; } plotArea = new Rectangle(plotX, plotY, plotWidth, plotHeight); } #endregion }
/// <summary> /// 设置默认绘图区位置,大小(无图例影响的默认位置) /// </summary> /// <param name="g"></param> /// <param name="xa"></param> /// <param name="ya"></param> /// <param name="y2a"></param> /// <param name="gd"></param> /// <param name="lb"></param> /// <param name="tl"></param> private void SetPlotArea(Graphics g, Title tl, XYLabel lb, Grid gd, XAxis xa, YAxis ya, Y2Axis y2a) { SizeF titleFontSize = g.MeasureString("A", tl.TitleStyle.TextFont); if (string.IsNullOrWhiteSpace(tl.TitleName) || tl.TitleName.ToUpper() == "NO TITLE") { titleFontSize.Width = 8f; titleFontSize.Height = 8f; } float xSpacing = XOffset / 2.0f; float ySpacing = YOffset / 2.0f; SizeF tickFontSize = g.MeasureString("A", xa.XTickStyle.TextFont); float tickSpacing = 2f; //获取y轴标记宽度 SizeF yTickSize = g.MeasureString(ya.YLimMin.ToString(), ya.YTickStyle.TextFont); int ycount = (int)Math.Round((ya.YLimMax - ya.YLimMin) / ya.YTick) + 1; for (int i = 0; i < ycount; i++) { float yTick = ya.YLimMin + i * ya.YTick; yTick = DataDeal.FloatAccur(yTick); SizeF tempSize = g.MeasureString(yTick.ToString(), ya.YTickStyle.TextFont); if (yTickSize.Width < tempSize.Width) { yTickSize = tempSize; } } SizeF labelFontSize = g.MeasureString("A", lb.XYLabelStyle.TextFont); float leftMargin = XOffset + labelFontSize.Height + xSpacing + yTickSize.Width + tickSpacing; float rightMargin = 2 * XOffset; float topMargin = YOffset + titleFontSize.Height + ySpacing; float bottomMargin = YOffset + labelFontSize.Height + ySpacing + tickFontSize.Height + tickSpacing; //单y轴绘图区大小 int plotX = ChartArea.X + (int)leftMargin; int plotY = ChartArea.Y + (int)topMargin; int plotHeight = ChartArea.Height - (int)topMargin - (int)bottomMargin; int plotWidth = ChartArea.Width - (int)leftMargin - (int)rightMargin; //双y轴:重新定义绘图区宽度 if (y2a.IsY2Axis) { //y2轴标记宽度 SizeF y2TickSize = g.MeasureString(y2a.Y2LimMin.ToString(), y2a.Y2TickStyle.TextFont); int y2count = (int)Math.Round((y2a.Y2LimMax - y2a.Y2LimMin) / y2a.Y2Tick) + 1; for (int i = 0; i < ycount; i++) { float y2Tick = y2a.Y2LimMin + i * y2a.Y2Tick; y2Tick = DataDeal.FloatAccur(y2Tick); SizeF tempSize2 = g.MeasureString(y2Tick.ToString(), y2a.Y2TickStyle.TextFont); if (y2TickSize.Width < tempSize2.Width) { y2TickSize = tempSize2; } } rightMargin = XOffset + labelFontSize.Height + xSpacing + y2TickSize.Width + tickSpacing; plotWidth = ChartArea.Width - (int)leftMargin - (int)rightMargin; } plotArea = new Rectangle(plotX, plotY, plotWidth, plotHeight); }