public void PaintOn(Graphics g, RectangleF _area) { GraphicsState _s = g.Save(); // _area is assumed to be provided in the same coordinate system as // g.PageUnit provides. The plotting library works assuming that // PageUnit is Inch, so we must transform the Rectangle into the // appropriate rect. PointF[] trans = new PointF[] { new PointF(_area.Left, _area.Top), new PointF(_area.Left + _area.Width, _area.Top + _area.Height) }; g.TransformPoints(CoordinateSpace.Device, CoordinateSpace.Page, trans); g.PageUnit = GraphicsUnit.Inch; g.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Device, trans); AdvancedRect area = new AdvancedRect(trans[0], trans[1]); using (Brush bg = background.CreateBrush()) g.FillRectangle(bg, area.Rect); outerMargins.Apply(ref area); //using (Brush tmp = new SolidBrush(Color.Red)) // g.FillRectangle(tmp, area.Rect); SizeF headerSize = new SizeF(0, 0); if (centerHeader != null) { using (Brush br = centerHeaderFont.CreateBrush()) using (Font f = centerHeaderFont.CreateFont()) { headerSize = g.MeasureString(centerHeader, f); g.DrawString(centerHeader, f, br, area.Center.X - (headerSize.Width / 2), area.TopLeft.Y); } } if (rightHeader != null || leftHeader != null) { using (Brush left_br = leftHeaderFont.CreateBrush()) using (Font left_f = leftHeaderFont.CreateFont()) using (Brush right_br = rightHeaderFont.CreateBrush()) using (Font right_f = rightHeaderFont.CreateFont()) { SizeF leftHeaderSize = (leftHeader != null) ? g.MeasureString(leftHeader, left_f) : new SizeF(0, 0); SizeF rightHeaderSize = (rightHeader != null) ? g.MeasureString(rightHeader, right_f) : new SizeF(0, 0); // determine y location = is this going to be aligned to the bottom of the center // header, or underneath it? underneath is necessary if the two will hit each other. float left_xLoc = area.TopLeft.X; float right_xLoc = area.BottomRight.X - rightHeaderSize.Width; float left_yLoc; float right_yLoc; if ((right_xLoc - 0.2f) < (area.Center.X + (headerSize.Width / 2)) || (left_xLoc + leftHeaderSize.Width + 0.2f) > (area.Center.X - (headerSize.Width / 2))) { // looks like we're too close - have to move down a bit. left_yLoc = right_yLoc = area.TopLeft.Y + headerSize.Height; headerSize.Height += Math.Max(rightHeaderSize.Height, leftHeaderSize.Height); } else { // We're good to place it next to the header. // But, check our height - are the side headers bigger than the center header? if (rightHeaderSize.Height > headerSize.Height || leftHeaderSize.Height > headerSize.Height) { // the side headers are bigger than the center header. Make enough room. headerSize.Height = Math.Max(leftHeaderSize.Height, rightHeaderSize.Height); } right_yLoc = area.TopLeft.Y + (headerSize.Height - rightHeaderSize.Height); left_yLoc = area.TopLeft.Y + (headerSize.Height - leftHeaderSize.Height); } if (rightHeader != null) { g.DrawString(rightHeader, right_f, right_br, right_xLoc, right_yLoc); } if (leftHeader != null) { g.DrawString(leftHeader, left_f, left_br, left_xLoc, left_yLoc); } } } if (headerSize.Height != 0) { area.TopLeft.Y += headerSize.Height; area.TopLeft.Y += 0.1f; } if (displayLegend) { area.BottomRight.Y -= DrawLegend(g, area); } float yAxisWidthLeft = yAxes.CalculateWidthLeft(g); float yAxisWidthRight = yAxes.CalculateWidthRight(g); float xAxisHeight = xAxis.CalculateHeight(g, area.Width - yAxisWidthLeft - yAxisWidthRight); AdvancedRect xAxisArea = area.Clone(); xAxisArea.TopLeft.X += yAxisWidthLeft; xAxisArea.BottomRight.X -= yAxisWidthRight; xAxisArea.TopLeft.Y = xAxisArea.BottomRight.Y - xAxisHeight; // calculate internal data area area.TopLeft.X += yAxisWidthLeft; area.BottomRight.X -= yAxisWidthRight; area.BottomRight.Y -= xAxisHeight; yAxes.Draw(g, area); xAxis.DrawX(g, xAxisArea, area); series.Draw(g, yAxes, xAxis, area); annotations.Draw(g, area); using (Pen p = borderPen.CreatePen()) { g.DrawLine(p, area.TopLeft.X, area.TopLeft.Y, area.TopLeft.X, area.BottomRight.Y); g.DrawLine(p, area.TopLeft.X, area.TopLeft.Y, area.BottomRight.X, area.TopLeft.Y); g.DrawLine(p, area.BottomRight.X, area.BottomRight.Y, area.BottomRight.X, area.TopLeft.Y); g.DrawLine(p, area.BottomRight.X, area.BottomRight.Y, area.TopLeft.X, area.BottomRight.Y); } dataArea = area; g.Restore(_s); }