< meta name = "viewport" content = "width=device-width, initial-scale=1, shrink-to-fit=no" />
< title >Labels with callouts | Sample | ArcGIS Maps SDK for JavaScript</ title >
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
< script type = "module" src = "https://js.arcgis.com/5.2/" ></ script >
max-width: calc ( 100 vw - 32 px );
background: var ( --calcite-color-surface-2 );
box-shadow: 0 1 px 4 px rgb ( 0 0 0 / 20 % );
#callout-controls calcite-label {
< arcgis-map item-id = "0263c98aa8d344c6a427286ef7b95bd3" >
< arcgis-zoom slot = "top-left" ></ arcgis-zoom >
< div id = "callout-controls" slot = "top-right" >
< calcite-select id = "callout-style" label = "Callout style" disabled >
< calcite-option value = "background" selected >Background callout</ calcite-option >
< calcite-option value = "balloon" >Balloon callout</ calcite-option >
< calcite-option value = "point-symbol" >Point symbol callout</ calcite-option >
< calcite-option value = "simple-line" >Simple line callout</ calcite-option >
< arcgis-legend slot = "bottom-left" ></ arcgis-legend >
// Load the CIMSymbol class used to update the layer's label symbols.
const CIMSymbol = await $arcgis . import ( "@arcgis/core/symbols/CIMSymbol.js" );
const viewElement = document . querySelector ( "arcgis-map" );
const styleSelect = document . querySelector ( "calcite-select" );
// Defines the background callout style.
const backgroundCallout = {
type : "CIMBackgroundCallout" ,
// The symbol used for the leader line connecting the callout to the feature.
color : [ 230 , 76 , 0 , 255 ],
// The symbol used for the background color and outline of the callout.
type : "CIMPolygonSymbol" ,
{ type : "CIMSolidFill" , enable : true , color : [ 255 , 255 , 255 , 255 ] },
// The symbol used for the accent bar in the background callout.
color : [ 230 , 76 , 0 , 255 ],
// Defines the margin around the text within the callout.
margin : { type : "CIMTextMargin" , left : 5 , right : 5 , top : 5 , bottom : 5 },
// Defines the point symbol used for point symbol callouts.
const pointCalloutSymbol = {
frame : { xmin : - 20 , ymin : - 8 , xmax : 20 , ymax : 8 },
scaleSymbolsProportionally : true ,
type : "CIMMarkerGraphic" ,
type : "CIMPolygonSymbol" ,
{ type : "CIMSolidFill" , enable : true , color : [ 232 , 246 , 249 , 255 ] },
{ type : "CIMSolidStroke" , enable : true , width : 1 , color : [ 0 , 94 , 110 , 255 ] },
// Each option pairs a callout style with the symbol settings it needs.
"background" : backgroundCallout ,
type : "CIMBalloonCallout" ,
balloonStyle : "RoundedRectangle" ,
backgroundSymbol : backgroundCallout . backgroundSymbol ,
useFixedDartWidth : false ,
margin : { left : 5 , right : 5 , top : 5 , bottom : 5 },
type : "CIMPointSymbolCallout" ,
pointSymbol : pointCalloutSymbol ,
backgroundScale : "PropUniform" ,
leaderLineSymbol : backgroundCallout . leaderLineSymbol ,
type : "CIMSimpleLineCallout" ,
lineSymbol : backgroundCallout . leaderLineSymbol ,
// Defines the text symbol used for labels.
const labelTextSymbol = {
fontFamilyName : "Noto Serif" ,
fontStyleName : "Regular" ,
type : "CIMPolygonSymbol" ,
symbolLayers : [{ type : "CIMSolidFill" , enable : true , color : [ 255 , 255 , 255 , 255 ] }],
horizontalAlignment : "Left" ,
type : "CIMPolygonSymbol" ,
color : [ 255 , 255 , 255 , 255 ],
{ type : "CIMSolidFill" , enable : true , color : [ 255 , 85 , 0 , 255 ] },
await viewElement . viewOnReady ();
// Find the layer from the web map so its existing label rules stay in place.
const layer = viewElement . map . allLayers . find (( layer ) => layer && layer . title === "Mines with Callouts" );
const minesLayer = layer ;
const originalLabels = minesLayer . labelingInfo ;
function updateLabels () {
// Start from the map's label rules, then add the selected callout to each one.
const callout = calloutPresets [ styleSelect . value ];
for ( const originalLabel of originalLabels ) {
const label = originalLabel . clone ();
label . offsetDistance = 10 ; // adjust callout offset
label . symbol = new CIMSymbol ({
type : "CIMSymbolReference" ,
// Merge the text symbol with the selected callout
symbol : { ... labelTextSymbol , callout },
labelingInfo . push ( label );
minesLayer . labelingInfo = labelingInfo ;
// Enable the picker once the layer is ready to show the selected style.
styleSelect . addEventListener ( "calciteSelectChange" , updateLabels );
styleSelect . disabled = false ;