private void AddAnnotations(Graphics g) { foreach (GraphObj obj in _pointAnnotations) { TextObj text = obj as TextObj; if (text != null) { if (text.Location.CoordinateFrame == CoordType.ChartFraction && text.Location.AlignH == AlignH.Left && text.Location.AlignV == AlignV.Top) { GraphObjList.Add(text); continue; } if (isXChartFractionObject(text) && (text.Location.X < XAxis.Scale.Min || text.Location.X > XAxis.Scale.Max)) { continue; } var textRect = _labelBoundsCache.GetLabelBounds(text, this, g); if (_overlapDetector == null || !_overlapDetector.Overlaps(textRect)) { _manualLabels[text] = textRect; } } else if (!GraphObjList.Contains(obj)) // always add non-text annotations { GraphObjList.Add(obj); } } }
private void drawLabels(Graphics g) { foreach (GraphObj pa in _pointAnnotations) { GraphObjList.Remove(pa); } _pointAnnotations.Clear(); Axis xAxis = XAxis; Axis yAxis = YAxis; yAxis.Scale.MinAuto = false; yAxis.Scale.Min = 0; // setup axes scales to enable the Transform method xAxis.Scale.SetupScaleData(this, xAxis); yAxis.Scale.SetupScaleData(this, yAxis); if (Chart.Rect.Width < 1 || Chart.Rect.Height < 1) { return; } Region textBoundsRegion; Region chartRegion = new Region(Chart.Rect); Region clipRegion = new Region(); clipRegion.MakeEmpty(); g.SetClip(Rect, CombineMode.Replace); g.SetClip(chartRegion, CombineMode.Exclude); /*Bitmap clipBmp = new Bitmap(Convert.ToInt32(Chart.Rect.Width), Convert.ToInt32(Chart.Rect.Height)); * Graphics clipG = Graphics.FromImage(clipBmp); * clipG.Clear(Color.White); * clipG.FillRegion(new SolidBrush(Color.Black), g.Clip); * clipBmp.Save("C:\\clip.bmp");*/ // some dummy labels for very fast clipping string baseLabel = "0"; foreach (CurveItem item in CurveList) { IMSGraphItemInfo info = item.Tag as IMSGraphItemInfo; if (info != null) { PointAnnotation annotation = info.AnnotatePoint(new PointPair(0, 0)); if (annotation != null && annotation.Label != null && annotation.Label.Length > baseLabel.Length) { baseLabel = annotation.Label; } } } TextObj baseTextObj = new TextObj(baseLabel, 0, 0); baseTextObj.FontSpec.Border.IsVisible = false; baseTextObj.FontSpec.Fill.IsVisible = false; PointF[] pts = baseTextObj.FontSpec.GetBox(g, baseLabel, 0, 0, AlignH.Center, AlignV.Bottom, 1.0f, new SizeF()); float baseLabelWidth = (float)Math.Round(pts[1].X - pts[0].X); float baseLabelHeight = (float)Math.Round(pts[2].Y - pts[0].Y); baseLabelWidth = (float)xAxis.Scale.ReverseTransform(xAxis.Scale.Transform(0) + baseLabelWidth); baseLabelHeight = (float)yAxis.Scale.ReverseTransform(yAxis.Scale.Transform(0) - baseLabelHeight); float labelLengthToWidthRatio = baseLabelWidth / baseLabel.Length; float xAxisPixel = yAxis.Scale.Transform(0); double xMin = xAxis.Scale.Min; double xMax = xAxis.Scale.Max; double yMin = yAxis.Scale.Min; double yMax = yAxis.Scale.Max; // add automatic labels for MSGraphItems foreach (CurveItem item in CurveList) { IMSGraphItemInfo info = item.Tag as IMSGraphItemInfo; MSPointList points = item.Points as MSPointList; if (info == null || points == null) { continue; } if (info.ToString().Length == 0) { continue; } PointPairList fullList = points.FullList; List <int> maxIndexList = points.ScaledMaxIndexList; for (int i = 0; i < maxIndexList.Count; ++i) { if (maxIndexList[i] < 0) { continue; } PointPair pt = fullList[maxIndexList[i]]; if (pt.X < xMin || pt.Y > yMax || pt.Y < yMin) { continue; } if (pt.X > xMax) { break; } float yPixel = yAxis.Scale.Transform(pt.Y); // labelled points must be at least 3 pixels off the X axis if (xAxisPixel - yPixel < 3) { continue; } PointAnnotation annotation = info.AnnotatePoint(pt); if (annotation == null) { continue; } if (annotation.ExtraAnnotation != null) { GraphObjList.Add(annotation.ExtraAnnotation); _pointAnnotations.Add(annotation.ExtraAnnotation); } if (string.IsNullOrEmpty(annotation.Label)) { continue; } float pointLabelWidth = labelLengthToWidthRatio * annotation.Label.Length; double labelY = yAxis.Scale.ReverseTransform(yPixel - 5); if (!AllowCurveOverlap) { // do fast check for overlap against all MSGraphItems bool overlap = false; foreach (CurveItem item2 in CurveList) { MSPointList points2 = item2.Points as MSPointList; if (points2 != null) { int nearestMaxIndex = points2.GetNearestMaxIndexToBin(i); if (nearestMaxIndex < 0) { continue; } RectangleF r = new RectangleF((float)pt.X - pointLabelWidth / 2, (float)labelY - baseLabelHeight, pointLabelWidth, baseLabelHeight); overlap = detectLabelCurveOverlap(this, points2.FullList, nearestMaxIndex, item2 is StickItem, r); if (overlap) { break; } } } if (overlap) { continue; } } TextObj text = new TextObj(annotation.Label, pt.X, labelY, CoordType.AxisXYScale, AlignH.Center, AlignV.Bottom) { ZOrder = ZOrder.A_InFront, FontSpec = annotation.FontSpec }; //text.IsClippedToChartRect = true; if (!detectLabelOverlap(this, g, text, out textBoundsRegion, item.Points, maxIndexList[i], item is StickItem)) { GraphObjList.Add(text); _pointAnnotations.Add(text); clipRegion.Union(textBoundsRegion); g.SetClip(clipRegion, CombineMode.Replace); } } } // add manual annotations foreach (CurveItem item in CurveList) { IMSGraphItemInfo info = item.Tag as IMSGraphItemInfo; MSPointList points = item.Points as MSPointList; if (info == null || points == null) { continue; } info.AddAnnotations(this, g, points, _pointAnnotations); foreach (GraphObj obj in _pointAnnotations) { if (!GraphObjList.Contains(obj)) { TextObj text = obj as TextObj; if (text != null) { if (detectLabelOverlap(this, g, text, out textBoundsRegion, item.Points, -1, item is StickItem)) { continue; } clipRegion.Union(textBoundsRegion); g.SetClip(clipRegion, CombineMode.Replace); } GraphObjList.Add(obj); } } /*GraphObjList objsToRemove = new GraphObjList(); * foreach( GraphObj obj in GraphObjList ) * if( !pointAnnotations_.Contains( obj ) ) * objsToRemove.Add( obj ); * foreach( GraphObj obj in objsToRemove ) * GraphObjList.Remove( obj );*/ } }