Using a TextSymbol doesn't work because then they all stack on top of each other making it impossible to see which features are actually at the location.
The tutorial from four years ago about how to cluster the graphics is OK, but I would rather not cluster them. I would prefer that the labels/text symbols move slightly in order to accommodate the other labels around them.
I tried using deconflictionStrategy: static and none and the output is same for both properties which is stacked on top of each other.
P.S: I am not using Portal and using only ArcGIS Server manager Feature Layer URL only and here is the code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>
Add labels to a FeatureLayer | Sample | ArcGIS API for JavaScript 4.18
</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.18/esri/themes/light-green/main.css"
/>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
background-color: black;
}
</style>
<script src="https://js.arcgis.com/4.18/"></script>
<script>
require([
"esri/WebMap",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/widgets/Search",
"esri/widgets/ScaleBar",
"esri/Map"
], function (WebMap, MapView, FeatureLayer, Search, ScaleBar, Map) {
const labelClass = {
// autocasts as new LabelClass()
symbol: {
type: "text", // autocasts as new TextSymbol()
color: "black",
//haloColor: "blue",
haloSize: 1,
font: {
// autocast as new Font()
family: "Arial Unicode MS, Arial",
size: 15,
weight: "bold"
}
},
labelPlacement: "above-right",
labelExpressionInfo: {
expression:
"$feature.SAPEQUIPID + ' '+ $feature.JPNUMBER + ' ' +$feature.JPSEQUENCE"
},
maxScale: 0,
minScale: 4514,
deconflictionStrategy: "none"
//where: "Conference = 'AFC'"
};
let featurelayer = new FeatureLayer({
url:
"xxxxxx/MapServer/1",
title: "Support Structure"
});
featurelayer.labelingInfo = [labelClass];
let map = new Map({
basemap: "streets"
});
let view = new MapView({
map: map,
container: "viewDiv",
center: [-122.379403, 37.793683], // Sets the center point of the view at a specified lon/lat
zoom: 13 // Sets the zoom LOD to 13
// center: [-122.4226616669898,37.750262026866835], // Sets the center point of the view at a specified lon/lat
// zoom: 20 // Sets the zoom LOD to 13
});
map.add(featurelayer);
// Adds the search widget to the top right corner of the view
view.ui.add(
new Search({
view: view
}),
"top-right"
);
var scaleBar = new ScaleBar({
view: view,
unit: "dual"
});
view.ui.add(scaleBar, "bottom-left");
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Solved! Go to Solution.
This is not a bug just a limitation. JS API is not designed to do labeling with complex label conflict detection like ArcGIS Desktop is. If you need better conflict avoidance then you need to do the labeling in the map service in Desktop and consume that labeled map service in your JS API app.
Robert is correct. The API is limited by the web resources. For better labeling performance and visualization, you can try playing around with minScale and maxScale values so that only specific labels appear at specific scale ranges.
This is not a bug just a limitation. JS API is not designed to do labeling with complex label conflict detection like ArcGIS Desktop is. If you need better conflict avoidance then you need to do the labeling in the map service in Desktop and consume that labeled map service in your JS API app.
Is there a way to do a carriage return using this method?
Robert is correct. The API is limited by the web resources. For better labeling performance and visualization, you can try playing around with minScale and maxScale values so that only specific labels appear at specific scale ranges.
Thank you @Noah-Sager and @RobertScheitlin__GISP