Does anyone know how to replace graphics in a FeatureLayer with a D3.js object. I'm not interested in simply using an SVG path, but actually replacing the node in which the graphic is rendered with a node from a d3 object. I have little experience with d3, but from looking at Esri's documentation and digging into the console, I figure this shouldn't be too difficult. I've included a simple example I would like to get working, but ideally I would eventually use a more complicated d3 object, constructed from feature attributes.
require(["esri/map", "esri/layers/FeatureLayer", "dojo/domReady!"], function(Map, FeatureLayer) {
map = new Map("map", {
basemap: "topo",
center: [-97, 38],
zoom: 5
});
var svg = createD3Circle();
console.log(svg);
var featureLayer = new FeatureLayer("myfeatureserviceurl");
featureLayer.on('graphic-draw', function(graphic) {
console.log(graphic);
graphic.node = svg;
console.log(graphic);
//is there anything I can do here to replace each graphic with my svg object.
//or possibly before the graphic even draws
});
map.addLayer(featureLayer);
featureLayer.on('load', function() {
var sType = featureLayer.surfaceType;
console.log(sType);
});
function createD3Circle() {
var svgContainer = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200);
var circle = svgContainer.append("circle")
.attr("cx", 30)
.attr("cy", 30)
.attr("r", 20);
return circle;
}
});
It's been a little while since I looked at d3. Is a d3 object an SVG? You can use a Picture Marker Symbol whose URL points to an SVG, you aren't just limited to passing in a path. For example (click the map to add a graphic whose symbol is taken from an SVG): JS Bin - Collaborative JavaScript Debugging
The easiest way to do this sort of thing with a feature layer is to make your own SimpleRenderer and override the getSymbol method. getSymbol takes a graphic as an argument and should return a symbol. You can use d3 to create an SVG and then create a PictureMarkerSymbol from that SVG inside getSymbol.
Here's another sample showing how you might do this with d3 and a simple renderer: JS Bin - Collaborative JavaScript Debugging
Thanks! This was very helpful. The library I'm using ends up creating an svg dom node that I would like to use as the symbol. Unfortunately referencing innerHTML of the dom node isn't sufficient, as not all svg properties are captured (although I have no idea why). Do you know, more generally, if there is a way to set a symbol to be a simple dom element in any of Esri's JS symbol classes?
Do you know, more generally, if there is a way to set a symbol to be a simple dom element in any of Esri's JS symbol classes?
I don't think so, I believe the closest thing you can get here is an SVG. I'm not sure the best way to stringify an SVG, using innerHTML seems a little hacky.
Using google, I came across this which might be useful:
var xml = new XMLSerializer().serializeToString(mySVGElement);
You could probably create one XMLSerializer and perform all the "serializeToString" operations you need using it.