3D callout line doesn't work with client-side graphics:

984
8
Jump to solution
12-04-2017 08:47 AM
mingleidi
New Contributor II

Does anyone try to use callout line with client-side graphics?

I followed this example: https://developers.arcgis.com/javascript/latest/sample-code/visualization-point-styles/index.html

this example use a feature layer from url: "http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/LyonPointsOfInterest/FeatureServer".

but it doesn't work with a feature layer which creates client-side graphics based on data returned from a web service.

Is there a limitation on 3d callout line?

here's my code snippet:

1. create a feature layer based on layer definition:
featureLayer = new FeatureLayer({
fields: this.layerDefinition.fields,
objectIdField: this.layerDefinition.objectIdField,
geometryType: this.layerDefinition.geometryType,
id: this.layerId
});

2. set elevation and feature reduction and renderer:
featureLayer.elevationInfo = {
// elevation mode that will place points on top of the buildings or other SceneLayer 3D objects
mode: "relative-to-scene"
};
// feature reduction is set to selection because our scene contains too many points and they overlap
featureLayer.featureReduction = {
type: "selection"
};

featureLayer.renderer = this._getUniqueValueRenderer() as any as Renderer// callout render

3. here the renderer code:
_getUniqueValueRenderer() {
let verticalOffset = { // verticalOffset shifts the symbol vertically
screenLength: 150, // callout line length
maxWorldLength: 200,
minWorldLength: 35
},
uniqueValueRenderer = {
type: "unique-value", // autocasts as new UniqueValueRenderer()
field: "AQHI",
uniqueValueInfos: [{
value: 1,
symbol: this._get3DCallOutSymbol(verticalOffset, "Museum.png", "#D13470")
}, {
value: 2,
symbol: this._get3DCallOutSymbol(verticalOffset, "Restaurant.png", "#F97C5A")
}, {
value: 3,
symbol: this._get3DCallOutSymbol(verticalOffset, "Church.png", "#884614")
}, {
value: 4,
symbol: this._get3DCallOutSymbol(verticalOffset, "Hotel.png", "#56B2D6")
}, {
value: 5,
symbol: this._get3DCallOutSymbol(verticalOffset, "Park.png", "#40C2B4")
}, {
value: 6,
symbol: this._get3DCallOutSymbol(verticalOffset, "Museum.png", "#D13470")
}, {
value: 7,
symbol: this._get3DCallOutSymbol(verticalOffset, "beer.png", "#F97C5A")
}, {
value: 8,
symbol: this._get3DCallOutSymbol(verticalOffset, "senate.png", "#884614")
}, {
value: 9,
symbol: this._get3DCallOutSymbol(verticalOffset, "Hotel.png", "#56B2D6")
}, {
value: 10,
symbol: this._get3DCallOutSymbol(verticalOffset, "Park.png", "#40C2B4")
}]
};
return uniqueValueRenderer;
}

_get3DCallOutSymbol(verticalOffset: any, iconName: string, color: string) {
return {
type: "point-3d", // autocasts as new PointSymbol3D()
symbolLayers: [{
type: "icon", // autocasts as new IconSymbol3DLayer()
resource: {
href: this.iconPath + iconName
},
size: 20,
outline: {
color: "white",
size: 2
}
}],
verticalOffset: verticalOffset,
callout: {
type: "line", // autocasts as new LineCallout3D()
color: "white",
size: 2,
border: {
color: color
}
}
};
}
4.set source to an array of graphics, generated based web service data
featureLayer.source = graphics;

Thanks.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
ThomasSolow
Occasional Contributor III

My sample uses a renderer to assign a symbol to each graphic.  I can change it so that the symbols are set manually on each graphic and it still works:

https://codepen.io/solowt/pen/LOadjd?editors=1000#0 

View solution in original post

0 Kudos
8 Replies
ThomasSolow
Occasional Contributor III

I've successfully used callouts with client-side graphics.

Can you post a simple code sample?

0 Kudos
mingleidi
New Contributor II

Thanks Thomas, here's my code snippet:

1. create a feature layer based on layer definition:

featureLayer = new FeatureLayer({
fields: this.layerDefinition.fields,
objectIdField: this.layerDefinition.objectIdField,
geometryType: this.layerDefinition.geometryType,
id: this.layerId
});

2. set elevation and feature reduction and renderer:

featureLayer.elevationInfo = {
// elevation mode that will place points on top of the buildings or other SceneLayer 3D objects
mode: "relative-to-scene"
};
// feature reduction is set to selection because our scene contains too many points and they overlap
featureLayer.featureReduction = {
type: "selection"
};

featureLayer.renderer = this._getUniqueValueRenderer() as any as Renderer// callout render

3. here the renderer code:

_getUniqueValueRenderer() {
let verticalOffset = { // verticalOffset shifts the symbol vertically
screenLength: 150, // callout line length
maxWorldLength: 200,
minWorldLength: 35
},
uniqueValueRenderer = {
type: "unique-value", // autocasts as new UniqueValueRenderer()
field: "AQHI",
uniqueValueInfos: [{
value: 1,
symbol: this._get3DCallOutSymbol(verticalOffset, "Museum.png", "#D13470")
}, {
value: 2,
symbol: this._get3DCallOutSymbol(verticalOffset, "Restaurant.png", "#F97C5A")
}, {
value: 3,
symbol: this._get3DCallOutSymbol(verticalOffset, "Church.png", "#884614")
}, {
value: 4,
symbol: this._get3DCallOutSymbol(verticalOffset, "Hotel.png", "#56B2D6")
}, {
value: 5,
symbol: this._get3DCallOutSymbol(verticalOffset, "Park.png", "#40C2B4")
}, {
value: 6,
symbol: this._get3DCallOutSymbol(verticalOffset, "Museum.png", "#D13470")
}, {
value: 7,
symbol: this._get3DCallOutSymbol(verticalOffset, "beer.png", "#F97C5A")
}, {
value: 8,
symbol: this._get3DCallOutSymbol(verticalOffset, "senate.png", "#884614")
}, {
value: 9,
symbol: this._get3DCallOutSymbol(verticalOffset, "Hotel.png", "#56B2D6")
}, {
value: 10,
symbol: this._get3DCallOutSymbol(verticalOffset, "Park.png", "#40C2B4")
}]
};
return uniqueValueRenderer;
}

_get3DCallOutSymbol(verticalOffset: any, iconName: string, color: string) {
return {
type: "point-3d", // autocasts as new PointSymbol3D()
symbolLayers: [{
type: "icon", // autocasts as new IconSymbol3DLayer()
resource: {
href: this.iconPath + iconName
},
size: 20,
outline: {
color: "white",
size: 2
}
}],
verticalOffset: verticalOffset,
callout: {
type: "line", // autocasts as new LineCallout3D()
color: "white",
size: 2,
border: {
color: color
}
}
};
}

4.set source to an array of graphics, generated based web service data

featureLayer.source = graphics;
0 Kudos
ThomasSolow
Occasional Contributor III

I'm not sure what's wrong here, but here's a simple sample that creates a feature layer in the client from an array of randomly generated graphics and symbolizes them with symbols that have callouts: https://codepen.io/solowt/pen/LOadjd?editors=1000#0 

One thing to take a look at is verticalOffset.  If you're zoomed out and have a maxWorldLength of 200, it's quite possible you won't be able to notice the callouts.  It may be better to just use screenLength sometimes.

0 Kudos
mingleidi
New Contributor II

Thank you Thomas, I will check that sample, and screenLength.

0 Kudos
mingleidi
New Contributor II

and Thomas, if possible, could you please post your code here too?

0 Kudos
mingleidi
New Contributor II

Hi Thomas, Based on your example I made callout showing now, the only issue is when assigning symbol to the graphic, the callout is disappeared. In your example the graphic doesn't have a symbol, can you try to assign a symbol to see if callout shows up?

Thanks,

Benjamin

0 Kudos
ThomasSolow
Occasional Contributor III

My sample uses a renderer to assign a symbol to each graphic.  I can change it so that the symbols are set manually on each graphic and it still works:

https://codepen.io/solowt/pen/LOadjd?editors=1000#0 

0 Kudos
mingleidi
New Contributor II

Thanks Thomas, it's resolved, I think I mess up with graphic symbol and render, should only need one, either graphic symbol or render, but not both.

0 Kudos