Select to view content in your preferred language

callout leader line

1068
4
Jump to solution
07-17-2022 05:29 PM
AndrewAlexander1
New Contributor II

Hello,

I'm trying to place a point, have a text "label" and a leader line going from the point, to the label.

I can get the point and the text, but no leader line shows.  I have looked everywhere, for a long time, tried every sample I can find, and I cannot get the leader line to show.  I have seen the community examples, and have tried everything that is even remotely pertinent.  And they definitely have balloons and/or callouts defined in the definitions.

I also don't even know what the "best practice" is for this sort of thing. CIMTextGraphic, CIMTextSymbol, labels? 

Does anyone have a really basic, "put a dot here, label it with a callout and leader line and actually make it display" example?  One that doesn't have numerous other methods being called that are not in the example?

Thanks

Andy

 

0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Below is a sample snippet and the method you're looking for is: CreateCIMCalloutTextGraphic(cityName, geometry) which takes a string followed by a geometry (where the leader line ends).  The sample is taken from a 2022 Palm Springs Dev Summit tech session, which you can get here: https://github.com/esri/arcgis-pro-sdk/wiki/tech-sessions  and then click on "Using Graphic Elements with Maps and Layouts" under 2022 Palm Springs.  Note that this sample in 2.x so you would have to convert this to 3.0.

internal class AddCalloutText : Button
  {
    private List<IDisposable> _graphics = new List<IDisposable>();

    protected override void OnClick()
    {
      try
      {
        if (_graphics.Count() > 0)
        {
          // clear existing graphic
          foreach (var graphic in _graphics)
            graphic.Dispose();
          _graphics.Clear();
          return;
        }
        QueuedTask.Run(() =>
        {
          Envelope zoomExtent;

          var cityName = "Redlands";
          var geometry = Module1.GetGeometry("U.S. Cities", $@"city_name = '{cityName}'"); // USHighways, route_num = 'I10'  States, state_name = 'California'  
                  var cimGraphic = CreateCIMCalloutTextGraphic(cityName, geometry);
          var graphic = MapView.Active.AddOverlay(cimGraphic);
          _graphics.Add(graphic);
          zoomExtent = geometry.Extent;

          cityName = "Palm Springs";
          geometry = Module1.GetGeometry("U.S. Cities", $@"city_name = '{cityName}'");  
                  cimGraphic = CreateCIMCalloutTextGraphic(cityName, geometry);
          graphic = MapView.Active.AddOverlay(cimGraphic);
          _graphics.Add(graphic);
          zoomExtent = zoomExtent.Union(geometry.Extent);

          MapView.Active.ZoomTo(zoomExtent.Expand(1.5, 1.5, true), new TimeSpan(0, 0, 1));
        });
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.ToString());
      }
    }

    private static CIMTextGraphic CreateCIMCalloutTextGraphic(string text, Geometry geometry)
    {
      var textSymbolRef = SymbolFactory.Instance.ConstructTextSymbol(
          ColorFactory.Instance.BlackRGB, 10, "Tahoma", "Bold").MakeSymbolReference();

      //now set text and location for the CIMGraphic
      var textGraphic = new CIMTextGraphic
      {
        Symbol = textSymbolRef,
        Text = text,
        Shape = geometry
      };
      textGraphic.Placement = Anchor.BottomLeftCorner;

      //Create a call out
      var backgroundCalloutSymbol = new CIMBackgroundCallout();

      // set callout colors and leader line
      #region callout colors and leader line
      //colors used by bounding callout box
      CIMColor accentColor = CIMColor.CreateRGBColor(0, 255, 0);
      CIMColor backgroundColor = ColorFactory.Instance.CreateRGBColor(190, 255, 190, 50);

      //Leader line
      //Get a line symbol
      var lineSymbol = SymbolFactory.Instance.ConstructLineSymbol(accentColor, 2, SimpleLineStyle.Solid);
      //Create a solid fill polygon symbol for the callout.
      var polySymbol = SymbolFactory.Instance.ConstructPolygonSymbol(backgroundColor, SimpleFillStyle.Solid);
      //accent symbol
      var accentSymbol = SymbolFactory.Instance.ConstructLineSymbol(accentColor, 2, SimpleLineStyle.Solid);

      //assign the leader line to the callout
      backgroundCalloutSymbol.LeaderLineSymbol = lineSymbol;
      backgroundCalloutSymbol.LineStyle = LeaderLineStyle.Base;
      backgroundCalloutSymbol.LeaderOffset = 2;

      //Assign the polygon to the background callout
      backgroundCalloutSymbol.BackgroundSymbol = polySymbol;

      //Set margins for the callout to center the text
      backgroundCalloutSymbol.Margin = new CIMTextMargin
      {
        Left = 5,
        Right = 5,
        Top = 5,
        Bottom = 5
      };

      //define the Accent bar
      backgroundCalloutSymbol.AccentBarSymbol = accentSymbol;
      #endregion callout colors and leader line

      //change the Offset for the textbox ... move 20 right and 20 high
      var textSym = textGraphic.Symbol.Symbol as CIMTextSymbol;
      textSym.OffsetX = 20;
      textSym.OffsetY = -40;

      //assign the callout to the textSymbol
      textSym.Callout = backgroundCalloutSymbol;

      if (geometry.GeometryType == GeometryType.Point)
      {
        // create a leader point
        CIMLeaderPoint leaderPt = new CIMLeaderPoint
        {
          Point = geometry as MapPoint
        };
        // assign to the textGraphic
        textGraphic.Leaders = new List<CIMLeader>() { leaderPt }.ToArray();
      }

      return textGraphic;
    }
  }

 

View solution in original post

0 Kudos
4 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Below is a sample snippet and the method you're looking for is: CreateCIMCalloutTextGraphic(cityName, geometry) which takes a string followed by a geometry (where the leader line ends).  The sample is taken from a 2022 Palm Springs Dev Summit tech session, which you can get here: https://github.com/esri/arcgis-pro-sdk/wiki/tech-sessions  and then click on "Using Graphic Elements with Maps and Layouts" under 2022 Palm Springs.  Note that this sample in 2.x so you would have to convert this to 3.0.

internal class AddCalloutText : Button
  {
    private List<IDisposable> _graphics = new List<IDisposable>();

    protected override void OnClick()
    {
      try
      {
        if (_graphics.Count() > 0)
        {
          // clear existing graphic
          foreach (var graphic in _graphics)
            graphic.Dispose();
          _graphics.Clear();
          return;
        }
        QueuedTask.Run(() =>
        {
          Envelope zoomExtent;

          var cityName = "Redlands";
          var geometry = Module1.GetGeometry("U.S. Cities", $@"city_name = '{cityName}'"); // USHighways, route_num = 'I10'  States, state_name = 'California'  
                  var cimGraphic = CreateCIMCalloutTextGraphic(cityName, geometry);
          var graphic = MapView.Active.AddOverlay(cimGraphic);
          _graphics.Add(graphic);
          zoomExtent = geometry.Extent;

          cityName = "Palm Springs";
          geometry = Module1.GetGeometry("U.S. Cities", $@"city_name = '{cityName}'");  
                  cimGraphic = CreateCIMCalloutTextGraphic(cityName, geometry);
          graphic = MapView.Active.AddOverlay(cimGraphic);
          _graphics.Add(graphic);
          zoomExtent = zoomExtent.Union(geometry.Extent);

          MapView.Active.ZoomTo(zoomExtent.Expand(1.5, 1.5, true), new TimeSpan(0, 0, 1));
        });
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.ToString());
      }
    }

    private static CIMTextGraphic CreateCIMCalloutTextGraphic(string text, Geometry geometry)
    {
      var textSymbolRef = SymbolFactory.Instance.ConstructTextSymbol(
          ColorFactory.Instance.BlackRGB, 10, "Tahoma", "Bold").MakeSymbolReference();

      //now set text and location for the CIMGraphic
      var textGraphic = new CIMTextGraphic
      {
        Symbol = textSymbolRef,
        Text = text,
        Shape = geometry
      };
      textGraphic.Placement = Anchor.BottomLeftCorner;

      //Create a call out
      var backgroundCalloutSymbol = new CIMBackgroundCallout();

      // set callout colors and leader line
      #region callout colors and leader line
      //colors used by bounding callout box
      CIMColor accentColor = CIMColor.CreateRGBColor(0, 255, 0);
      CIMColor backgroundColor = ColorFactory.Instance.CreateRGBColor(190, 255, 190, 50);

      //Leader line
      //Get a line symbol
      var lineSymbol = SymbolFactory.Instance.ConstructLineSymbol(accentColor, 2, SimpleLineStyle.Solid);
      //Create a solid fill polygon symbol for the callout.
      var polySymbol = SymbolFactory.Instance.ConstructPolygonSymbol(backgroundColor, SimpleFillStyle.Solid);
      //accent symbol
      var accentSymbol = SymbolFactory.Instance.ConstructLineSymbol(accentColor, 2, SimpleLineStyle.Solid);

      //assign the leader line to the callout
      backgroundCalloutSymbol.LeaderLineSymbol = lineSymbol;
      backgroundCalloutSymbol.LineStyle = LeaderLineStyle.Base;
      backgroundCalloutSymbol.LeaderOffset = 2;

      //Assign the polygon to the background callout
      backgroundCalloutSymbol.BackgroundSymbol = polySymbol;

      //Set margins for the callout to center the text
      backgroundCalloutSymbol.Margin = new CIMTextMargin
      {
        Left = 5,
        Right = 5,
        Top = 5,
        Bottom = 5
      };

      //define the Accent bar
      backgroundCalloutSymbol.AccentBarSymbol = accentSymbol;
      #endregion callout colors and leader line

      //change the Offset for the textbox ... move 20 right and 20 high
      var textSym = textGraphic.Symbol.Symbol as CIMTextSymbol;
      textSym.OffsetX = 20;
      textSym.OffsetY = -40;

      //assign the callout to the textSymbol
      textSym.Callout = backgroundCalloutSymbol;

      if (geometry.GeometryType == GeometryType.Point)
      {
        // create a leader point
        CIMLeaderPoint leaderPt = new CIMLeaderPoint
        {
          Point = geometry as MapPoint
        };
        // assign to the textGraphic
        textGraphic.Leaders = new List<CIMLeader>() { leaderPt }.ToArray();
      }

      return textGraphic;
    }
  }

 

0 Kudos
AndrewAlexander1
New Contributor II

Thank you so much for that.  With just a few tweaks for my situation, it worked!

Seems like I had all these elements, but something wasn't quite right, apparently.

Andy

 

 

0 Kudos
AndrewAlexander1
New Contributor II

A follow up question for these CIMgraphics.  Is it possible to have these (the callout boxes) where we can click and drag them around?  And have the leader still attached to the point?

Thanks
Andy

 

0 Kudos
UmaHarano
Esri Regular Contributor

Please also refer to the following snippet in the ArcGIS Pro SDK wiki:

Creates a background callout text symbol 

0 Kudos