Putting text on a marker symbol

910
0
05-04-2021 10:33 AM
TJ_Crowder
New Contributor

I'm having trouble putting text on a marker symbol (a simple circle) on maps using the @arcgis/core module from npm. What's a simple way to do that? What we used to do with v4.16 via ESRI loader isn't working reliably anymore with v4.19 and the npm module (old and new below). Sometimes the text shows up, other times it doesn't.

Here's our old code using the "ESRI loader" stuff and v4.16. To have text on top of a marker symbol (for instance, a circle), we were adding a circle then adding text:

// A worker function we had
function addGraphic(graphicsLayer, graphic, opacity) {
    graphicsLayer.graphics.add(graphic);
    graphic.symbol.color.a = opacity;
    return graphic;
}

// Using it to add a circle and then text
addGraphic(view, new Graphic({
    geometry, // A Point
    symbol: {
        type: "simple-marker",
        style: "circle",
        color: /*...*/,
        size: /*...*/,
        outline: {
            width: 0,
        },
    },
    popupTemplate,
}), 1);
addGraphic(view, new Graphic({
    geometry, // The same Point
    symbol: {
        text: /*...*/,
        type: "text",
        color: "white",
        horizontalAlignment: "center",
        verticalAlignment: "middle",
        font: {
            size: 12,
            weight: "bold",
        }
    },
    popupTemplate,
}), 1);

It felt a bit kludgy but worked reliably.

In our newer code using v4.19.1 from npm, we're using TypeScript and imported the constructors and updated the code (minimally) to look like this instead:

// The utility function
function addGraphic(graphicsLayer: MapView | GraphicsLayer, graphic: Graphic, opacity?: number) {
    graphicsLayer.graphics.add(graphic);
    if (typeof opacity !== "undefined") {
        graphic.symbol.color.a = opacity;
    }
    return graphic;
}

// Using it
addGraphic(this.view, new Graphic({
    geometry, // A Point
    symbol: new SimpleMarkerSymbol({
        style: "circle",
        color: /*...*/,
        size: /*...*/,
        outline: {
            width: 0,
        },
    }),
    popupTemplate,
}), 1);
addGraphic(this.view, new Graphic({
    geometry, // The same Point
    symbol: new TextSymbol({
        text: /*...*/,
        color: "white",
        horizontalAlignment: "center",
        verticalAlignment: "middle",
        font: {
            size: 12,
            weight: "bold",
        }
    }),
    popupTemplate,
}), 1);

As you can see, the only difference in the code is that we're using the constructors (and allowing for the opacity to be left off, but it's included in both of these calls). We switched to using the constructors because the TypeScript types didn't include the type property that autocasting (?) uses.

Using the constructors isn't the problem, though -- if I add make TypeScript ignore the error on the type property, we get exactly the same result we get with the constructors: The text sometimes appears, other times it doesn't.

It always seemed overcomplicated to add two graphics just to put some text in a circle. Is there a better way to do this, and if not, is there a way to make this more reliable?

Thanks,

-- T.J.

Tags (3)
0 Kudos
0 Replies