Ejemplo n.º 1
0
        private void drawLabels(Graphics g)
        {
            foreach (GraphObj pa in _pointAnnotations)
            {
                GraphObjList.Remove(pa);
            }
            _pointAnnotations.Clear();
            _manualLabels.Clear();

            Axis xAxis = XAxis;
            Axis yAxis = YAxis;

            yAxis.Scale.MinAuto = false;
            if (LockYAxisAtZero)
            {
                yAxis.Scale.Min = 0;
            }

            // ensure that the chart rectangle is the right size
            AxisChange(g);
            // then 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;
            }

            _overlapDetector = AllowLabelOverlap ? null : new OverlapDetector();
            Region chartRegion = new Region(Chart.Rect);
            Region clipRegion  = new Region();

            clipRegion.MakeEmpty();
            var previousClip = g.Clip.Clone();

            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"; // Not L10N

            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  = pts[1].X - pts[0].X;
            float baseLabelHeight = 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 manual annotations with TextObj priority over curve annotations
            foreach (CurveItem item in CurveList)
            {
                var         info   = item.Tag as IMSGraphItemExtended;
                MSPointList points = item.Points as MSPointList;
                if (info == null || points == null)
                {
                    continue;
                }

                info.AddPreCurveAnnotations(this, g, points, _pointAnnotations);
                AddAnnotations(g);
            }

            // 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;
                var           annotationsPrioritized = new Dictionary <PointAnnotation, int>();
                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)
                    {
                        annotationsPrioritized.Add(annotation, i);
                    }
                }

                // Give the higher ranked point priority
                foreach (var annotation in annotationsPrioritized.Keys.OrderBy(a => a.ZOrder ?? int.MaxValue))
                {
                    if (annotation.ExtraAnnotation != null)
                    {
                        GraphObjList.Add(annotation.ExtraAnnotation);
                        _pointAnnotations.Add(annotation.ExtraAnnotation);
                    }

                    if (string.IsNullOrEmpty(annotation.Label))
                    {
                        continue;
                    }

                    float pointLabelWidth = labelLengthToWidthRatio * annotation.Label.Split('\n').Max(o => o.Length);

                    var       i      = annotationsPrioritized[annotation];
                    PointPair pt     = fullList[maxIndexList[i]];
                    float     yPixel = yAxis.Scale.Transform(pt.Y);
                    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,
                        IsClippedToChartRect = true
                    };

                    var  textRect = _labelBoundsCache.GetLabelBounds(text, this, g);
                    bool overlap2 = _overlapDetector != null && _overlapDetector.Overlaps(textRect);
                    _manualLabels[text] = textRect;
                    if (!overlap2)
                    {
                        _pointAnnotations.Add(text);
                        AddAnnotations(g);
                    }
                }
            }

            // 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);
                AddAnnotations(g);
            }

            autoScaleForManualLabels(g);
            g.Clip = previousClip;
        }
Ejemplo n.º 2
0
        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 );*/
            }
        }