void PaintLinkLine(Link link, RenderArgs e) { Rectangle rect1 = link.From.Bounds; Rectangle rect2 = link.Target.Bounds; // if bounds changed, rebuild layout info if (rect1 != link.LayoutData.StartBounds || rect2 != link.LayoutData.EndBounds) { link.RefreshLayout(); } // draw line var layout = link.LayoutData; Color color = link.Color.IsEmpty ? e.Chart.LinkLineColor : link.Color; var pen = e.Graphics.Pen(color, link.LineWidth, link.LineStyle); e.Graphics.DrawBezier(pen, layout.StartPoint, layout.ControlPoint1, layout.ControlPoint2, layout.EndPoint, link.StartCap, link.EndCap); //text if (!string.IsNullOrEmpty(link.Text)) { var pt = BezierHelper.GetPoint(layout.StartPoint, layout.ControlPoint1, layout.ControlPoint2, layout.EndPoint, 0.5f); var size = Size.Ceiling(e.Graphics.MeasureString(link.Text, e.Font)); var rectText = new Rectangle(pt.X - size.Width / 2, pt.Y - size.Height / 2, size.Width, size.Height); if (!e.Chart.BackColor.IsEmpty) { e.Graphics.FillRectangle(e.Graphics.SolidBrush(Color.FromArgb(180, e.Chart.BackColor)), rectText); } if (!e.Chart.ForeColor.IsEmpty) { var font2 = e.Font; if (!string.IsNullOrEmpty(link.Hyperlink)) { font2 = e.Graphics.Font(e.Font, e.Font.Style | FontStyle.Underline); } var sf = PaintHelper.SFCenter; e.Graphics.DrawString(link.Text, font2, e.Graphics.SolidBrush(e.Chart.ForeColor), rectText, sf); } link.LayoutData.TextBounds = rectText; } else { link.LayoutData.TextBounds = Rectangle.Empty; } // remark-icon if (e.ShowRemarkIcon && link.HaveRemark) { Image iconRemark = Properties.Resources.note_small; Point pt = BezierHelper.GetPoint(layout.StartPoint, layout.ControlPoint1, layout.ControlPoint2, layout.EndPoint, 0.5f); Rectangle rectRemark = new Rectangle(pt.X - iconRemark.Width / 2, pt.Y - iconRemark.Height / 2, iconRemark.Width, iconRemark.Height); e.Graphics.DrawImage(iconRemark, rectRemark, 0, 0, iconRemark.Width, iconRemark.Height); } }
BezierLayoutInfo GetLayoutInfo(BezierControlPoint controlPoint1, BezierControlPoint controlPoint2) { var layout = new BezierLayoutInfo(); layout.CP1 = controlPoint1; layout.CP2 = controlPoint2; Point cp1, cp2; Rectangle rect1 = From.Bounds; Rectangle rect2 = Target.Bounds; Point pts = PaintHelper.CenterPoint(rect1); Point ptd = PaintHelper.CenterPoint(rect2); rect1.Inflate(2, 2); rect2.Inflate(2, 2); if (StartCap != LineAnchor.None) { rect1.Inflate(Layouter.LineAnchorSize, Layouter.LineAnchorSize); } if (EndCap != LineAnchor.None) { rect2.Inflate(Layouter.LineAnchorSize, Layouter.LineAnchorSize); } if (pts == ptd) { cp1 = pts; cp2 = ptd; layout.Bounds = Rectangle.Empty; layout.Region = null; } else { cp1 = BezierHelper.GetControlPoint(pts, controlPoint1); cp2 = BezierHelper.GetControlPoint(ptd, controlPoint2); //Point[] controlPoints = GetControlPoints(pts, ptd); Shape sShape = Shape.GetShaper(From); pts = sShape.GetBorderPoint(rect1, cp1); Shape dShape = Shape.GetShaper(Target); ptd = sShape.GetBorderPoint(rect2, cp2); GraphicsPath gp = new GraphicsPath(); gp.AddBezier(pts, cp1, cp2, ptd); Pen penWiden = new Pen(Color.Black, LineWidth + 5); gp.Widen(penWiden); var rect = gp.GetBounds(); rect.Inflate(LineWidth, LineWidth); layout.Bounds = rect; layout.Region = new Region(gp); } Point ptCenter = BezierHelper.GetPoint(pts, cp1, cp2, ptd, 0.5f); Rectangle textBounds = layout.TextBounds; textBounds.X = ptCenter.X - layout.TextBounds.Width / 2; textBounds.Y = ptCenter.Y - layout.TextBounds.Height / 2; // cache layout info layout.StartBounds = rect1; layout.EndBounds = rect2; layout.StartPoint = pts; layout.EndPoint = ptd; layout.ControlPoint1 = cp1; layout.ControlPoint2 = cp2; layout.TextBounds = textBounds; return(layout); }