How to draw curved labels on a circle circumference in arcgis for Javascript

269
2
Jump to solution
02-19-2024 10:39 PM
ManasDas
New Contributor II

I am new to arcgis for javascript. I have a requirement to draw circles and then have curved labels on the circumference. Also, we have zoom in/out functionality , which means the 'curvature' of the labels should also align with the curvature of the circumference. I have tried many classes such as labelpoint, labelclass etc, but all of them seem to draw the label at the center and not at the circumference. I googled a lot but could not find any information. Any help will be appreciated.

I have attached a screenshot of the requirement, please note that I cannot add the full view due to company confidentiality requirements.

0 Kudos
1 Solution

Accepted Solutions
JoelBennett
MVP Regular Contributor

There isn't native support for this in the SDK since polygon graphics only support horizontal labeling (see the LabelClass.labelPlacement property).  That's not to say you can't pull this off with a little extra work though.  One idea would be to maintain a separate polyline layer where the polygons have been converted to polylines, and those polylines labeled instead, since the SDK does support drawing labels alone lines.  If you make those polylines transparent, it will appear as if the polygon edge is labeled.

Below is a basic example:

<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Sketch widget | Sample | ArcGIS Maps SDK for JavaScript 4.28</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.28/"></script>

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  <script>
      require([
        "esri/Color",
        "esri/Graphic",
        "esri/Map",
        "esri/geometry/Polygon",
        "esri/geometry/Polyline",
        "esri/layers/FeatureLayer",
        "esri/renderers/SimpleRenderer",
        "esri/symbols/Font",
        "esri/symbols/SimpleFillSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/TextSymbol",
        "esri/views/MapView"
      ], (
        Color,
        Graphic,
        Map,
        Polygon,
        Polyline,
        FeatureLayer,
        SimpleRenderer,
        Font,
        SimpleFillSymbol,
        SimpleLineSymbol,
        TextSymbol,
        MapView
      ) => {
        const map = new Map({
          basemap: "topo-vector"
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          zoom: 5,
          center: [90, 45]
        });

        view.when(() => {
          var polygon = Polygon.fromJSON({
            spatialReference: { latestWkid: 3857, wkid: 102100 },
            rings: [
              [
                [9201708.294980831, 6103380.512501691],
                [9199505.916630479, 6061356.630160495],
                [9192922.9112975, 6019793.170268292],
                [9182031.40376591, 5979145.510789373],
                [9166950.723671414, 5939858.9959870605],
                [9147846.098100968, 5902364.05713876],
                [9124926.841330219, 5867071.496640812],
                [9098444.06153251, 5834367.987171478],
                [9068687.909585183, 5804611.835224151],
                [9035984.400115848, 5778129.055426442],
                [9000691.8396179, 5755209.7986556925],
                [8963196.9007696, 5736105.173085245],
                [8923910.385967288, 5721024.492990751],
                [8883262.726488369, 5710132.98545916],
                [8841699.266596166, 5703549.980126182],
                [8799675.38425497, 5701347.601775828],
                [8757651.501913773, 5703549.980126182],
                [8716088.04202157, 5710132.98545916],
                [8675440.382542651, 5721024.492990751],
                [8636153.867740339, 5736105.173085245],
                [8598658.928892039, 5755209.7986556925],
                [8563366.368394092, 5778129.055426442],
                [8530662.858924756, 5804611.835224151],
                [8500906.70697743, 5834367.987171478],
                [8474423.92717972, 5867071.496640812],
                [8451504.670408972, 5902364.057138759],
                [8432400.044838525, 5939858.9959870605],
                [8417319.36474403, 5979145.510789373],
                [8406427.85721244, 6019793.170268291],
                [8399844.85187946, 6061356.630160495],
                [8397642.473529108, 6103380.512501691],
                [8399844.85187946, 6145404.394842886],
                [8406427.85721244, 6186967.8547350895],
                [8417319.36474403, 6227615.514214008],
                [8432400.044838525, 6266902.029016321],
                [8451504.670408972, 6304396.967864621],
                [8474423.92717972, 6339689.5283625685],
                [8500906.706977429, 6372393.037831903],
                [8530662.858924756, 6402149.18977923],
                [8563366.368394092, 6428631.969576939],
                [8598658.928892039, 6451551.226347689],
                [8636153.867740339, 6470655.851918136],
                [8675440.382542651, 6485736.53201263],
                [8716088.04202157, 6496628.039544221],
                [8757651.501913773, 6503211.044877199],
                [8799675.38425497, 6505413.423227553],
                [8841699.266596166, 6503211.044877199],
                [8883262.726488369, 6496628.039544221],
                [8923910.385967286, 6485736.53201263],
                [8963196.900769599, 6470655.851918136],
                [9000691.8396179, 6451551.226347689],
                [9035984.400115848, 6428631.96957694],
                [9068687.909585183, 6402149.18977923],
                [9098444.061532509, 6372393.037831904],
                [9124926.841330219, 6339689.528362569],
                [9147846.098100968, 6304396.967864622],
                [9166950.723671414, 6266902.029016321],
                [9182031.40376591, 6227615.514214008],
                [9192922.9112975, 6186967.85473509],
                [9199505.916630479, 6145404.394842887],
                [9201708.294980831, 6103380.512501691]
              ]
            ]
          });

          var polygonGraphic = new Graphic({
            geometry: polygon,
            symbol: new SimpleFillSymbol({
              color: new Color([192, 192, 192, 0.5]),
              outline: new SimpleLineSymbol({
                color: new Color([255, 0, 0, 1]),
                style: "solid",
                width: "2px"
              }),
              style: "solid"
            })
          });

          view.graphics.add(polygonGraphic);

          var polylineJson = polygon.toJSON();
          polylineJson.paths = polylineJson.rings;

          delete polylineJson.rings;

          var polyline = Polyline.fromJSON(polylineJson);

          var polylineGraphic = new Graphic({
            geometry: polyline,
            attributes: { OBJECTID: 1, LABELFIELD: "My Label Text" }
          });

          var layer = new FeatureLayer({
            source: [polylineGraphic],
            objectIdField: "OBJECTID",
            fields: [
              {
                name: "OBJECTID",
                type: "oid"
              },
              {
                name: "LABELFIELD",
                type: "string"
              }
            ],
            renderer: new SimpleRenderer({
              symbol: new SimpleLineSymbol({
                color: new Color([0, 0, 0, 0]),
                style: "solid",
                width: "2px"
              })
            }),
            labelingInfo: [
              {
                labelExpressionInfo: { expression: "$feature.LABELFIELD" },
                labelPlacement: "center-along",
                repeatLabel: false,
                symbol: new TextSymbol({
                  color: new Color([255, 255, 255, 1]),
                  font: new Font({
                    family: "Arial",
                    size: "12pt",
                    style: "normal",
                    weight: "bold"
                  }),
                  haloColor: new Color([0, 0, 0, 1]),
                  haloSize: 2
                })
              }
            ]
          });

          view.map.add(layer);
        });
      });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>
</html>

 

View solution in original post

2 Replies
JoelBennett
MVP Regular Contributor

There isn't native support for this in the SDK since polygon graphics only support horizontal labeling (see the LabelClass.labelPlacement property).  That's not to say you can't pull this off with a little extra work though.  One idea would be to maintain a separate polyline layer where the polygons have been converted to polylines, and those polylines labeled instead, since the SDK does support drawing labels alone lines.  If you make those polylines transparent, it will appear as if the polygon edge is labeled.

Below is a basic example:

<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Sketch widget | Sample | ArcGIS Maps SDK for JavaScript 4.28</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.28/"></script>

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  <script>
      require([
        "esri/Color",
        "esri/Graphic",
        "esri/Map",
        "esri/geometry/Polygon",
        "esri/geometry/Polyline",
        "esri/layers/FeatureLayer",
        "esri/renderers/SimpleRenderer",
        "esri/symbols/Font",
        "esri/symbols/SimpleFillSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/TextSymbol",
        "esri/views/MapView"
      ], (
        Color,
        Graphic,
        Map,
        Polygon,
        Polyline,
        FeatureLayer,
        SimpleRenderer,
        Font,
        SimpleFillSymbol,
        SimpleLineSymbol,
        TextSymbol,
        MapView
      ) => {
        const map = new Map({
          basemap: "topo-vector"
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          zoom: 5,
          center: [90, 45]
        });

        view.when(() => {
          var polygon = Polygon.fromJSON({
            spatialReference: { latestWkid: 3857, wkid: 102100 },
            rings: [
              [
                [9201708.294980831, 6103380.512501691],
                [9199505.916630479, 6061356.630160495],
                [9192922.9112975, 6019793.170268292],
                [9182031.40376591, 5979145.510789373],
                [9166950.723671414, 5939858.9959870605],
                [9147846.098100968, 5902364.05713876],
                [9124926.841330219, 5867071.496640812],
                [9098444.06153251, 5834367.987171478],
                [9068687.909585183, 5804611.835224151],
                [9035984.400115848, 5778129.055426442],
                [9000691.8396179, 5755209.7986556925],
                [8963196.9007696, 5736105.173085245],
                [8923910.385967288, 5721024.492990751],
                [8883262.726488369, 5710132.98545916],
                [8841699.266596166, 5703549.980126182],
                [8799675.38425497, 5701347.601775828],
                [8757651.501913773, 5703549.980126182],
                [8716088.04202157, 5710132.98545916],
                [8675440.382542651, 5721024.492990751],
                [8636153.867740339, 5736105.173085245],
                [8598658.928892039, 5755209.7986556925],
                [8563366.368394092, 5778129.055426442],
                [8530662.858924756, 5804611.835224151],
                [8500906.70697743, 5834367.987171478],
                [8474423.92717972, 5867071.496640812],
                [8451504.670408972, 5902364.057138759],
                [8432400.044838525, 5939858.9959870605],
                [8417319.36474403, 5979145.510789373],
                [8406427.85721244, 6019793.170268291],
                [8399844.85187946, 6061356.630160495],
                [8397642.473529108, 6103380.512501691],
                [8399844.85187946, 6145404.394842886],
                [8406427.85721244, 6186967.8547350895],
                [8417319.36474403, 6227615.514214008],
                [8432400.044838525, 6266902.029016321],
                [8451504.670408972, 6304396.967864621],
                [8474423.92717972, 6339689.5283625685],
                [8500906.706977429, 6372393.037831903],
                [8530662.858924756, 6402149.18977923],
                [8563366.368394092, 6428631.969576939],
                [8598658.928892039, 6451551.226347689],
                [8636153.867740339, 6470655.851918136],
                [8675440.382542651, 6485736.53201263],
                [8716088.04202157, 6496628.039544221],
                [8757651.501913773, 6503211.044877199],
                [8799675.38425497, 6505413.423227553],
                [8841699.266596166, 6503211.044877199],
                [8883262.726488369, 6496628.039544221],
                [8923910.385967286, 6485736.53201263],
                [8963196.900769599, 6470655.851918136],
                [9000691.8396179, 6451551.226347689],
                [9035984.400115848, 6428631.96957694],
                [9068687.909585183, 6402149.18977923],
                [9098444.061532509, 6372393.037831904],
                [9124926.841330219, 6339689.528362569],
                [9147846.098100968, 6304396.967864622],
                [9166950.723671414, 6266902.029016321],
                [9182031.40376591, 6227615.514214008],
                [9192922.9112975, 6186967.85473509],
                [9199505.916630479, 6145404.394842887],
                [9201708.294980831, 6103380.512501691]
              ]
            ]
          });

          var polygonGraphic = new Graphic({
            geometry: polygon,
            symbol: new SimpleFillSymbol({
              color: new Color([192, 192, 192, 0.5]),
              outline: new SimpleLineSymbol({
                color: new Color([255, 0, 0, 1]),
                style: "solid",
                width: "2px"
              }),
              style: "solid"
            })
          });

          view.graphics.add(polygonGraphic);

          var polylineJson = polygon.toJSON();
          polylineJson.paths = polylineJson.rings;

          delete polylineJson.rings;

          var polyline = Polyline.fromJSON(polylineJson);

          var polylineGraphic = new Graphic({
            geometry: polyline,
            attributes: { OBJECTID: 1, LABELFIELD: "My Label Text" }
          });

          var layer = new FeatureLayer({
            source: [polylineGraphic],
            objectIdField: "OBJECTID",
            fields: [
              {
                name: "OBJECTID",
                type: "oid"
              },
              {
                name: "LABELFIELD",
                type: "string"
              }
            ],
            renderer: new SimpleRenderer({
              symbol: new SimpleLineSymbol({
                color: new Color([0, 0, 0, 0]),
                style: "solid",
                width: "2px"
              })
            }),
            labelingInfo: [
              {
                labelExpressionInfo: { expression: "$feature.LABELFIELD" },
                labelPlacement: "center-along",
                repeatLabel: false,
                symbol: new TextSymbol({
                  color: new Color([255, 255, 255, 1]),
                  font: new Font({
                    family: "Arial",
                    size: "12pt",
                    style: "normal",
                    weight: "bold"
                  }),
                  haloColor: new Color([0, 0, 0, 1]),
                  haloSize: 2
                })
              }
            ]
          });

          view.map.add(layer);
        });
      });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>
</html>

 

ManasDas
New Contributor II

I do appreciate you taking the time to read through the issue and providing a solution. I did try your solution and it does seem to do what it says. Thanks a lot. I will try to tweak it further.

0 Kudos