I have upgraded the JavaScript API to 4.22 version from 4.5. The existing functionality of implementing classBreakRenderer using smart mapping is having performance issue.
I observed that there are extra 8-9 query requests sent to the server which my code has not created.
Here is step-wise implementation
API is integrated in ReactJS App
Here is the functionality implementation
I have put inline comment relevant to this post in blow code itself, starting with //** Note
const sellAccrualFeatureLayer = new FeatureLayer({
url: '........../MapServer/4',
id: 'sellAccrualFeatureLayer',
outFields: ['*'],
legendEnabled: true,
visible: false
})
sellAccrualFeatureLayer.opacity = 0.5
sellAccrualFeatureLayer.definitionExpression = '1=2'
esrijs.map.add(sellAccrualFeatureLayer)
esrijs.sellAccrualFeatureLayer = sellAccrualFeatureLayer
Saved in esrijs variable and added to map with visible false.
2) On click of feature I have identify request to another layer to get the attribute of that feature and this acts as input where clause for sellAccrualFeatureLayer created in step 1
And here is the first query for sellAccrualFeatureLayer layer
makeQuerys = () => {
const sellAccrualFeatureLayer = esrijs.sellAccrualFeatureLayer
const colorRendererCreator = window.require('esri/smartMapping/renderers/color')
const legendContainer = this.legendContainer
const map = esrijs.map
const dispatch = this.props.dispatch
const kauppapaikkaNro = this.props.selectedStore.feature.attributes.Kauppapaikkanro
const queryTimeStamps = sellAccrualFeatureLayer.createQuery()
queryTimeStamps.where = 'Kauppa=' + kauppapaikkaNro
queryTimeStamps.spatialRelationship = 'intersects'
queryTimeStamps.outFields = ['Aikaleima']
queryTimeStamps.returnDistinctValues = true
queryTimeStamps.returnGeometry = false
queryTimeStamps.orderByFields = ['Aikaleima DESC']
const colorSchemes = window.require('esri/smartMapping/symbology/color')
const schemes = colorSchemes.getSchemes({
basemap: map.basemap,
geometryType: sellAccrualFeatureLayer.geometryType,
theme: 'high-to-low'
})
// console.log(schemes)
// console.log(schemes.secondarySchemes.find(sc => sc.id === 'high-to-low/gray/seq-browns-bright'))
sellAccrualFeatureLayer.queryFeatures(queryTimeStamps)
.then(function (responseTimeStamps) {
if (responseTimeStamps.features.length > 0 && responseTimeStamps.features[0].attributes.Aikaleima) {
const params = {
layer: sellAccrualFeatureLayer,
field: 'Kertyma',
view: esrijs.view,
classificationMethod: 'natural-breaks',
numClasses: 4,
legendOptions: {
title: 'Kertymä'
},
// colorScheme: {...schemes.secondarySchemes.find(sc => sc.id === 'high-to-low/' + schemes.basemapId + '/seq-browns-bright'), ...{opacity: 0.95}}
colorScheme: {...schemes.secondarySchemes.find(sc => sc.id === 'high-to-low/gray/seq-browns-bright'), ...{opacity: 0.95}}
}
// generate the renderer and set it on the layer
// ** Note this create renderer request to layer is executed within 1 sec so no issue here
colorRendererCreator.createClassBreaksRenderer(params)
.then(function (response) {
const renderer = response.renderer
renderer.defaultSymbol = null
sellAccrualFeatureLayer.renderer = renderer
if (!esrijs.legend || esrijs.legend.destroyed) {
const Legend = window.require('esri/widgets/Legend')
esrijs.legend = new Legend({
view: esrijs.view,
container: legendContainer
})
}
}).catch(console.error)
const timeStamps = responseTimeStamps.features.map(x => x.attributes.Aikaleima)
const latestTimestamp = timeStamps[0]
const comparisonTimestamp = timeStamps.length > 1 ? timeStamps[1] : latestTimestamp
const zipcodeWhere = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + latestTimestamp + ' and Rank <=40'
sellAccrualFeatureLayer.definitionExpression = zipcodeWhere
const queryZipcodeSellAccrual = sellAccrualFeatureLayer.createQuery()
queryZipcodeSellAccrual.where = zipcodeWhere
queryZipcodeSellAccrual.spatialRelationship = 'intersects'
queryZipcodeSellAccrual.outFields = ['*']
queryZipcodeSellAccrual.returnGeometry = false
queryZipcodeSellAccrual.orderByFields = ['Rank']
// ** Note - observed from the Network tab, that when this below query is executed and req is sent, those extra query requests (PFA RankQueryreq.png are initiated and are in a pending state - and when these extra req are completed then only after that the req in the below Promise.All() are excuted, hence taking more time)
sellAccrualFeatureLayer.queryFeatures(queryZipcodeSellAccrual)
.then(function (responseZipcodeSellAccrual) {
esrijs.sellAccrualFeatureLayer.visible = true
const top40AccrualData = responseZipcodeSellAccrual.features.map(x => x.attributes).reduce((acc, curr) => {
acc[curr.Postinumero] = true
return acc
}, {})
const top40AccrualZipcodes = Object.keys(top40AccrualData)
const queryZipcodeSellAccrualOver40 = sellAccrualFeatureLayer.createQuery()
queryZipcodeSellAccrualOver40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + latestTimestamp + ' and Rank >40'
queryZipcodeSellAccrualOver40.spatialRelationship = 'intersects'
queryZipcodeSellAccrualOver40.outFields = ['*']
queryZipcodeSellAccrualOver40.returnGeometry = false
queryZipcodeSellAccrualOver40.outStatistics = statisticDefinitionOver40
const queryComparisonZipcodeSellAccrualTop40 = sellAccrualFeatureLayer.createQuery()
queryComparisonZipcodeSellAccrualTop40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + comparisonTimestamp + ' and Postinumero IN (\'' + top40AccrualZipcodes.join('\',\'') + '\')'
queryComparisonZipcodeSellAccrualTop40.spatialRelationship = 'intersects'
queryComparisonZipcodeSellAccrualTop40.outFields = ['*']
queryComparisonZipcodeSellAccrualTop40.returnGeometry = false
queryComparisonZipcodeSellAccrualTop40.orderByFields = ['Rank']
const queryComparisonZipcodeSellAccrualOver40 = sellAccrualFeatureLayer.createQuery()
queryComparisonZipcodeSellAccrualOver40.where = 'Kauppa=' + kauppapaikkaNro + ' and Aikaleima=' + comparisonTimestamp + ' and Postinumero NOT IN (\'' + top40AccrualZipcodes.join('\',\'') + '\')'
queryComparisonZipcodeSellAccrualOver40.spatialRelationship = 'intersects'
queryComparisonZipcodeSellAccrualOver40.outFields = ['*']
queryComparisonZipcodeSellAccrualOver40.returnGeometry = false
queryComparisonZipcodeSellAccrualOver40.outStatistics = statisticDefinitionOver40
//** Note - These are the 3 req that start only after the extra req are completed
Promise.all([
sellAccrualFeatureLayer.queryFeatures(queryZipcodeSellAccrualOver40),
sellAccrualFeatureLayer.queryFeatures(queryComparisonZipcodeSellAccrualTop40),
sellAccrualFeatureLayer.queryFeatures(queryComparisonZipcodeSellAccrualOver40)
]).then(([currentAccrualSumOver40, comparisonAccrualTop40, comparisonAccrualSumOver40]) => {
console.log("after promise");
const currentTop40Attributes = responseZipcodeSellAccrual.features.map(x => x.attributes)
const comparisonTop40Attributes = comparisonAccrualTop40.features.map(x => x.attributes)
const currentSumEurot = currentTop40Attributes.reduce((acc, curr) => acc + curr.Eurot, currentAccrualSumOver40.features[0].attributes.SUMMA_Eurot)
const comparisonSumEurot = comparisonTop40Attributes.reduce((acc, curr) => acc + curr.Eurot, comparisonAccrualSumOver40.features[0].attributes.SUMMA_Eurot)
const data = {
currentAccrualTop40: currentTop40Attributes.reduce((acc, curr) => {
acc[curr.Postinumero] = calculateAdditionalFields(curr, currentSumEurot)
return acc
}, {}),
currentAccrualSumOver40: calculateAdditionalFields({
...currentAccrualSumOver40.features[0].attributes,
usedTimestamp: latestTimestamp
}, currentSumEurot, true),
comparisonAccrualTop40: comparisonTop40Attributes.reduce((acc, curr) => {
acc[curr.Postinumero] = calculateAdditionalFields(curr, comparisonSumEurot)
return acc
}, {}),
comparisonAccrualSumOver40: calculateAdditionalFields({
...comparisonAccrualSumOver40.features[0].attributes,
usedTimestamp: comparisonTimestamp
}, comparisonSumEurot, true)
}
dispatch(setSellAccrualData(data))
})
}).catch(console.error)
}
Attachment info
1) extraquery.png - Showing the extra req and req from promises
2) extraquerydetail.png - Details of one of the extra req
3) queryreq.png
I tried sending a list of outFields in all queries in the code, including in FeatureLayer Constructor - issue persists.
The issue is why it is sending extra req and those too for "ID" fields as orderby and this field is OID of that layer.
Will be grateful if anyone can help.