Hi, I'm trying to display graphics on a client side feature layer using class-breaks renderer and picture-marker symbol. Symbols (or images) are getting chopped. Does anyone know why?
Thanks!
Following is the sample code:
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Add or remove graphics from a FeatureLayer | Sample | ArcGIS API for JavaScript 4.19</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.19/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.19/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#add {
margin-bottom: 5px;
}
#actions {
padding: 5px;
}
button:disabled {
opacity: 0.4;
-moz-opacity: 0.4; /* Firefox and Mozilla browsers */
-webkit-opacity: 0.4; /* Safari */
cursor: default;
}
</style>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/Basemap",
"esri/layers/VectorTileLayer",
"esri/layers/FeatureLayer",
"esri/Graphic",
"esri/widgets/Legend"
], function(
Map,
MapView,
Basemap,
VectorTileLayer,
FeatureLayer,
Graphic,
Legend
) {
// create map using custom basemap from ArcGIS Online
const map = new Map({
basemap: new Basemap({
baseLayers: [
new VectorTileLayer({
portalItem: {id: "474f0cb226884dd68f707ab0f2f1aa10"}
})
],
referenceLayers: [
new VectorTileLayer({
portalItem: {id: "1768e8369a214dfab4e2167d5c5f2454"}
})
]
})
});
const view = new MapView({
container: "viewDiv",
map: map,
zoom: 3,
center: [-122.18, 37.49] // longitude, latitude
});
// create empty FeatureLayer
const monumentLayer = new FeatureLayer({
// create an instance of esri/layers/support/Field for each field object
title: "National Monuments",
fields: [
{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
},
{
name: "Name",
alias: "Name",
type: "string"
},
{
name: "Type",
alias: "Type",
type: "string"
},
{
name: "Count",
alias: "Count",
type: "integer"
}
],
objectIdField: "ObjectID",
geometryType: "point",
spatialReference: { wkid: 4326 },
source: [], // adding an empty feature collection
renderer:
{
type: "class-breaks", // autocasts as new ClassBreaksRenderer()
field: "count",
// other properties set in step number 2
classBreakInfos: [
{
minValue: 0,
maxValue: 100,
symbol: {
type: "picture-marker", // autocasts as new SimpleFillSymbol()
url: "https://static.arcgis.com/images/Symbols/Shapes/BlackStarLargeB.png",
height: "30px",
width: "30px"
},
label: "< 35%" // label for symbol in legend
},
{
minValue: 101,
maxValue: 200,
symbol: {
type: "picture-marker", // autocasts as new SimpleFillSymbol()
url: "https://static.arcgis.com/images/Symbols/Shapes/BlackStarLargeB.png",
height: "40px",
width: "40px"
},
label: "35 - 50%" // label for symbol in legend
},
{
minValue: 201,
maxValue: 500,
symbol: {
type: "picture-marker", // autocasts as new SimpleFillSymbol()
url: "https://static.arcgis.com/images/Symbols/Shapes/BlackStarLargeB.png",
height: "50px",
width: "50px"
},
label: "50 - 75%" // label for symbol in legend
},
{
minValue: 501,
maxValue: 1000,
symbol: {
type: "picture-marker", // autocasts as new SimpleFillSymbol()
url: "https://static.arcgis.com/images/Symbols/Shapes/BlackStarLargeB.png",
height: "60px",
width: "60px"
},
label: "> 75%" // label for symbol in legend
}
]
}
,
popupTemplate: {
title: "{Name}:{Count}"
}
});
map.add(monumentLayer);
// add legend
const legend = new Legend({
view: view
});
view.ui.add(legend, "bottom-left");
// add buttons to the mapView
view.ui.add(document.getElementById("actions"), "top-right");
const addBtn = document.getElementById("add");
const removeBtn = document.getElementById("remove");
addBtn.addEventListener("click", addFeatures);
removeBtn.addEventListener("click", removeFeatures);
// check if features have already been added to determine disabled state of buttons
monumentLayer.queryFeatures().then(function(results){
if (results.features.length === 0){
addBtn.disabled = false;
removeBtn.disabled = true;
}
else {
addBtn.disabled = true;
removeBtn.disabled = false;
}
});
// fires when "Add Features" button is clicked
function addFeatures(){
// data to be added to the map
const data = [
{
LATITUDE: 32.6735,
LONGITUDE: -117.2425,
TYPE: "National Monument",
NAME: "Cabrillo National Monument",
COUNT: 100
},
{
LATITUDE: 32.6935,
LONGITUDE: -117.2925,
TYPE: "National Monument",
NAME: "Cabrillo National Monument",
COUNT: 110
},
{
LATITUDE: 35.2234,
LONGITUDE: -118.5590,
TYPE: "National Monument",
NAME: "Cesar E. Chavez National Monument",
COUNT: 200
},
{
LATITUDE: 35.9234,
LONGITUDE: -118.9590,
TYPE: "National Monument",
NAME: "Cesar E. Chavez National Monument",
COUNT: 200
},
{
LATITUDE: 37.6251,
LONGITUDE: -119.0850,
TYPE: "National Monument",
NAME: "Devils Postpile National Monument",
COUNT: 300
},
{
LATITUDE: 35.2915,
LONGITUDE: -115.0935,
TYPE: "National Monument",
NAME: "Castle Mountains National Monument",
COUNT: 400
},
{
LATITUDE: 41.7588,
LONGITUDE: -121.5267,
TYPE: "National Monument",
NAME: "Lava Beds National Monument",
COUNT: 500
},
{
LATITUDE: 37.8970,
LONGITUDE: -122.5811,
TYPE: "National Monument",
NAME: "Muir Woods National Monument",
COUNT: 600
},
{
LATITUDE: 41.8868,
LONGITUDE: -121.3717,
TYPE: "National Monument",
NAME: "Tule Lake National Monument",
COUNT: 700
}
];
// create an array of graphics based on the data above
var graphics = [];
var graphic;
for (var i=0; i<data.length; i++){
graphic = new Graphic({
geometry: {
type: "point",
latitude: data[i].LATITUDE,
longitude: data[i].LONGITUDE
},
attributes: data[i]
});
graphics.push(graphic);
}
// addEdits object tells applyEdits that you want to add the features
const addEdits = {
addFeatures: graphics
};
// apply the edits to the layer
applyEditsToLayer(addEdits);
}
// fires when "Remove Features" button clicked
function removeFeatures(){
// query for the features you want to remove
monumentLayer.queryFeatures().then(function(results){
// edits object tells apply edits that you want to delete the features
const deleteEdits = {
deleteFeatures: results.features
};
// apply edits to the layer
applyEditsToLayer(deleteEdits);
});
}
function applyEditsToLayer(edits) {
monumentLayer
.applyEdits(edits)
.then(function(results) {
// if edits were removed
if (results.deleteFeatureResults.length > 0){
console.log(
results.deleteFeatureResults.length,
"features have been removed"
);
addBtn.disabled = false;
removeBtn.disabled = true;
}
// if features were added - call queryFeatures to return
// newly added graphics
if (results.addFeatureResults.length > 0){
var objectIds = [];
results.addFeatureResults.forEach(function(item) {
objectIds.push(item.objectId);
});
// query the newly added features from the layer
monumentLayer
.queryFeatures({
objectIds: objectIds
})
.then(function(results){
console.log(
results.features.length,
"features have been added."
);
addBtn.disabled = true;
removeBtn.disabled = false;
})
}
})
.catch(function(error) {
console.log(error);
});
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="actions" class="esri-widget">
<button class="esri-button" id="add">Add 7 Features</button>
<button class="esri-button" id="remove">Remove 7 Features</button>
</div>
</body>
</html>
Hi @AmarG1, can you describe the issue in more detail? I ran your app in Codepen, and when I add the 9 features, they seem to display fine:
https://codepen.io/noash/pen/LYxwKGP?editors=1000
Hi Noah, Please look at the screenshot that I'm sharing. Topmost symbol is chopped initially but gets better after zoom-in/zoom-out. Screenshot is the output from your codepen sample.
This is the same issue as FeatureLayer symbol cut off after change of attrib... - Esri Community
Ah ok Amar I can see it. Probably this is limited to applyEdits. Making an internal issue.
Thanks Noah!
We use this a lot.
When can we expect resolution to this?
Sure, thanks to @mgeorge!
Hi there,
This issue will be fixed at JS API version 4.20 which will be released end of June 2021.
-Undral
I'm seeing a similar issue in 4.20, this time involving graphics symbolized with TextSymbol in a client-side FeatureLayer getting clipped.
|
|
Can this be fixed in the next release?
Update: this issue with TextSymbol graphics being clipped was fixed in 4.21.