/// <summary> /// Get the absolute location of dp /// </summary> /// <param name="cg">for finding the absolute location</param> /// <param name="dp"></param> /// <returns></returns> public static PointF GetAbsolutePoint(ChartGraphics cg, DataPoint dp) { PointF p1 = new PointF( (float)cg.GetPositionFromAxis("Default", AxisName.X, dp.XValue), (float)cg.GetPositionFromAxis("Default", AxisName.Y, dp.YValues[0])); p1 = cg.GetAbsolutePoint(p1); return p1; }
/// <summary> /// Draw strip/line title text /// </summary> /// <param name="graph">Chart graphics object.</param> /// <param name="rect">Rectangle to draw in.</param> private void PaintTitle(ChartGraphics graph, RectangleF rect) { if (this.Text.Length > 0) { // Get title text string titleText = this.Text; // Prepare string format using (StringFormat format = new StringFormat()) { format.Alignment = this.TextAlignment; if (graph.IsRightToLeft) { if (format.Alignment == StringAlignment.Far) { format.Alignment = StringAlignment.Near; } else if (format.Alignment == StringAlignment.Near) { format.Alignment = StringAlignment.Far; } } format.LineAlignment = this.TextLineAlignment; // Adjust default title angle for horizontal lines int angle = 0; switch (this.TextOrientation) { case (TextOrientation.Rotated90): angle = 90; break; case (TextOrientation.Rotated270): angle = 270; break; case (TextOrientation.Auto): if (this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top) { angle = 270; } break; } // Set vertical text for horizontal lines if (angle == 90) { format.FormatFlags = StringFormatFlags.DirectionVertical; angle = 0; } else if (angle == 270) { format.FormatFlags = StringFormatFlags.DirectionVertical; angle = 180; } // Measure string size SizeF size = graph.MeasureStringRel(titleText.Replace("\\n", "\n"), this.Font, new SizeF(100, 100), format, this.GetTextOrientation()); // Adjust text size float zPositon = 0f; if (this.Axis.ChartArea.Area3DStyle.Enable3D) { // Get projection coordinates Point3D[] textSizeProjection = new Point3D[3]; zPositon = this.Axis.ChartArea.IsMainSceneWallOnFront() ? this.Axis.ChartArea.areaSceneDepth : 0f; textSizeProjection[0] = new Point3D(0f, 0f, zPositon); textSizeProjection[1] = new Point3D(size.Width, 0f, zPositon); textSizeProjection[2] = new Point3D(0f, size.Height, zPositon); // Transform coordinates of text size this.Axis.ChartArea.matrix3D.TransformPoints(textSizeProjection); // Adjust text size int index = this.Axis.ChartArea.IsMainSceneWallOnFront() ? 0 : 1; size.Width *= size.Width / (textSizeProjection[index].X - textSizeProjection[(index == 0) ? 1 : 0].X); size.Height *= size.Height / (textSizeProjection[2].Y - textSizeProjection[0].Y); } // Get relative size of the border width SizeF sizeBorder = graph.GetRelativeSize(new SizeF(this.BorderWidth, this.BorderWidth)); // Find the center of rotation PointF rotationCenter = PointF.Empty; if (format.Alignment == StringAlignment.Near) { // Near rotationCenter.X = rect.X + size.Width / 2 + sizeBorder.Width; } else if (format.Alignment == StringAlignment.Far) { // Far rotationCenter.X = rect.Right - size.Width / 2 - sizeBorder.Width; } else { // Center rotationCenter.X = (rect.Left + rect.Right) / 2; } if (format.LineAlignment == StringAlignment.Near) { // Near rotationCenter.Y = rect.Top + size.Height / 2 + sizeBorder.Height; } else if (format.LineAlignment == StringAlignment.Far) { // Far rotationCenter.Y = rect.Bottom - size.Height / 2 - sizeBorder.Height; } else { // Center rotationCenter.Y = (rect.Bottom + rect.Top) / 2; } // Reset string alignment to center point format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; if (this.Axis.ChartArea.Area3DStyle.Enable3D) { // Get projection coordinates Point3D[] rotationCenterProjection = new Point3D[2]; rotationCenterProjection[0] = new Point3D(rotationCenter.X, rotationCenter.Y, zPositon); if (format.FormatFlags == StringFormatFlags.DirectionVertical) { rotationCenterProjection[1] = new Point3D(rotationCenter.X, rotationCenter.Y - 20f, zPositon); } else { rotationCenterProjection[1] = new Point3D(rotationCenter.X - 20f, rotationCenter.Y, zPositon); } // Transform coordinates of text rotation point this.Axis.ChartArea.matrix3D.TransformPoints(rotationCenterProjection); // Adjust rotation point rotationCenter = rotationCenterProjection[0].PointF; // Adjust angle of the text if (angle == 0 || angle == 180 || angle == 90 || angle == 270) { if (format.FormatFlags == StringFormatFlags.DirectionVertical) { angle += 90; } // Convert coordinates to absolute rotationCenterProjection[0].PointF = graph.GetAbsolutePoint(rotationCenterProjection[0].PointF); rotationCenterProjection[1].PointF = graph.GetAbsolutePoint(rotationCenterProjection[1].PointF); // Calcuate axis angle float angleXAxis = (float)Math.Atan( (rotationCenterProjection[1].Y - rotationCenterProjection[0].Y) / (rotationCenterProjection[1].X - rotationCenterProjection[0].X)); angleXAxis = (float)Math.Round(angleXAxis * 180f / (float)Math.PI); angle += (int)angleXAxis; } } // Draw string using (Brush brush = new SolidBrush(this.ForeColor)) { graph.DrawStringRel( titleText.Replace("\\n", "\n"), this.Font, brush, rotationCenter, format, angle, this.GetTextOrientation()); } } } }
/// <summary> /// </summary> /// <param name="cg"></param> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private PointF ToPixelsPos(ChartGraphics cg, double x, double y) { var p = new PointF((float) cg.GetPositionFromAxis(kChartAreaName, AxisName.X, x), (float) cg.GetPositionFromAxis(kChartAreaName, AxisName.Y, y)); return cg.GetAbsolutePoint(p); }
/// <summary> /// Paints an annotation object on the specified graphics. /// </summary> /// <param name="graphics"> /// A <see cref="ChartGraphics"/> object, used to paint an annotation object. /// </param> /// <param name="chart"> /// Reference to the <see cref="Chart"/> owner control. /// </param> override internal void Paint(Chart chart, ChartGraphics graphics) { // Get annotation position in relative coordinates PointF firstPoint = PointF.Empty; PointF anchorPoint = PointF.Empty; SizeF size = SizeF.Empty; GetRelativePosition(out firstPoint, out size, out anchorPoint); PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); // Create selection rectangle RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); // Adjust coordinates AdjustLineCoordinates(ref firstPoint, ref secondPoint, ref selectionRect); // Check if text position is valid if (float.IsNaN(firstPoint.X) || float.IsNaN(firstPoint.Y) || float.IsNaN(secondPoint.X) || float.IsNaN(secondPoint.Y)) { return; } // Set line caps bool capChanged = false; LineCap oldStartCap = LineCap.Flat; LineCap oldEndCap = LineCap.Flat; if (this._startCap != LineAnchorCapStyle.None || this._endCap != LineAnchorCapStyle.None) { capChanged = true; oldStartCap = graphics.Pen.StartCap; oldEndCap = graphics.Pen.EndCap; // Apply anchor cap settings if (this._startCap == LineAnchorCapStyle.Arrow) { // Adjust arrow size for small line width if (this.LineWidth < 4) { int adjustment = 3 - this.LineWidth; graphics.Pen.StartCap = LineCap.Custom; graphics.Pen.CustomStartCap = new AdjustableArrowCap( this.LineWidth + adjustment, this.LineWidth + adjustment, true); } else { graphics.Pen.StartCap = LineCap.ArrowAnchor; } } else if (this._startCap == LineAnchorCapStyle.Diamond) { graphics.Pen.StartCap = LineCap.DiamondAnchor; } else if (this._startCap == LineAnchorCapStyle.Round) { graphics.Pen.StartCap = LineCap.RoundAnchor; } else if (this._startCap == LineAnchorCapStyle.Square) { graphics.Pen.StartCap = LineCap.SquareAnchor; } if (this._endCap == LineAnchorCapStyle.Arrow) { // Adjust arrow size for small line width if (this.LineWidth < 4) { int adjustment = 3 - this.LineWidth; graphics.Pen.EndCap = LineCap.Custom; graphics.Pen.CustomEndCap = new AdjustableArrowCap( this.LineWidth + adjustment, this.LineWidth + adjustment, true); } else { graphics.Pen.EndCap = LineCap.ArrowAnchor; } } else if (this._endCap == LineAnchorCapStyle.Diamond) { graphics.Pen.EndCap = LineCap.DiamondAnchor; } else if (this._endCap == LineAnchorCapStyle.Round) { graphics.Pen.EndCap = LineCap.RoundAnchor; } else if (this._endCap == LineAnchorCapStyle.Square) { graphics.Pen.EndCap = LineCap.SquareAnchor; } } if (this.Common.ProcessModePaint) { // Draw line graphics.DrawLineRel( this.LineColor, this.LineWidth, this.LineDashStyle, firstPoint, secondPoint, this.ShadowColor, this.ShadowOffset); } if (this.Common.ProcessModeRegions) { // Create line graphics path using (GraphicsPath path = new GraphicsPath()) { path.AddLine( graphics.GetAbsolutePoint(firstPoint), graphics.GetAbsolutePoint(secondPoint)); using (Pen pen = (Pen)graphics.Pen.Clone()) { // Increase pen size by 2 pixels pen.DashStyle = DashStyle.Solid; pen.Width += 2; try { path.Widen(pen); } catch (OutOfMemoryException) { // GraphicsPath.Widen incorrectly throws OutOfMemoryException // catching here and reacting by not widening } catch (ArgumentException) { } } // Add hot region this.Common.HotRegionsList.AddHotRegion( graphics, path, false, ReplaceKeywords(this.ToolTip), String.Empty, String.Empty, String.Empty, this, ChartElementType.Annotation); } } // Restore line caps if (capChanged) { graphics.Pen.StartCap = oldStartCap; graphics.Pen.EndCap = oldEndCap; } // Paint selection handles PaintSelectionHandles(graphics, selectionRect, null); }