Symbol object to image (svg)

5081
6
Jump to solution
02-24-2016 03:24 PM
JosephRogan
New Contributor III

I have a custom Legend widget which I made some time ago and have been using.  It normally works by doing an esriRequest to get the Legend info for that layer. 

What I've encountered though is some layers do not have this info, example: http://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/World_UTM_Grid/FeatureServer/0

What I would like to do is use the Symbol object which I can get from the Renderer to create an image that I can use for the legend.  I'm not particular on the format, but I've tried using the standard Legend widget with a layer like this and it creates an SVG path.

How does the default Legend widget do this? Symbol -> SVG path.

The markup for the service above would some create this:

<path transform="matrix(1.00000000,0.00000000,0.00000000,1.00000000,15.00000000,15.00000000)" dojoGfxStrokeStyle="solid" stroke-dasharray="none" fill-rule="evenodd" d="M-10-10L 10 0L 10 10L-10 10L-10-10" path="M -10,-10 L 10,0 L 10,10 L -10,10 L -10,-10 E" stroke-miterlimit="4" stroke-linejoin="miter" stroke-linecap="butt" stroke-width="1" stroke-opacity="1" stroke="rgb(105, 105, 105)" fill-opacity="0.5019607843137255" fill="rgb(211, 211, 211)"></path>

Thanks in advance!

0 Kudos
1 Solution
6 Replies
JosephRogan
New Contributor III

Thanks for the quick reply!  While I havn't fully implemented this yet into my widget, I was able to do a quick test with that sample server and it worked perfectly!

                
                var symbol = this.layers.layer.renderer.getSymbol();
                
                var testDiv = dojo.create("div", { id: "testDiv", style: "width:20px; height:20px; border: 0px solid black;" }, this.legendDiv);
                
                var mySurface = gfx.createSurface(dom.byId("testDiv"), 20, 20);
                var descriptors = jsonUtils.getShapeDescriptors(symbol);
                var shape = mySurface.createShape(descriptors.defaultShape).setFill(descriptors.fill).setStroke(descriptors.stroke);
                shape.applyTransform({ dx: 10, dy: 10 });
0 Kudos
GregRieck
Occasional Contributor III

The link no longer works. Can you please provide detailed information or a working link?

ThomasSolow
Occasional Contributor III

I don't know the best way to do this in 3.XX, however the 4.XX API has a a symbolPreview module (esri/symbols/support/symbolPreview) with a renderPreviewHTML function, for example:

symbolPreview.renderPreviewHTML(<symbol>,{
      node: <HTMLElement>, //svg will be a child of this node
      opacity: 1,
      size: 10
});

This will resolve to an HTMLElement containing the SVG, so you can add it manually if you prefer instead of providing a node.

JordanBaumgardner
Occasional Contributor III

Does this help?

// My config, passed to getSymbol()

location: {
   path: 'M28,0.074 28,10.87 14,42 0,56 14,42 28,36.826 42,42 56,56 42,42 28,10.657z',
   size: 35,
   startAngle: 0,
   color: {r: 36,g: 117,b: 255,a: 1,color: ''}
}

me.getSymbol = function (path, color, size, angle) {
   var markerSymbol;
   require(["esri/symbols/SimpleMarkerSymbol"], function (SimpleMarkerSymbol) {
   markerSymbol = new SimpleMarkerSymbol();
   markerSymbol.setPath(path);
   markerSymbol.setColor(color);
   markerSymbol.setOutline();
   markerSymbol.setSize(size);
   markerSymbol.setAngle(angle);
});
return markerSymbol;
};

0 Kudos
JordanBaumgardner
Occasional Contributor III

Here is how I convert the SVG from the legend to the DIV. (Ported 3.x digit TOC code)

_getLegendIconUrl: function(legend) {
var src = legend.url;
if (src == null) {
src = "data:image/png;base64," +
this.rootLayerTOC._legendResponse.layers[this.rootLayer.layerId].legend[0].imageData;
} else if (src != null && src.indexOf('data') == -1) {
// in some cases NULL value may cause #legend != #of renderer entry.
if (!has('ie') && legend.imageData && legend.imageData.length > 0) {
src = "data:image/png;base64," + legend.imageData;
} else {
if (src.indexOf('http') !== 0) {
// resolve relative url
src = this.rootLayer.url + '/' + this.serviceLayer.id + '/images/' + src;
}
if (this.rootLayer.credential && this.rootLayer.credential.token) {
src = src + "?token=" + this.rootLayer.credential.token;
} else if (esriConfig.defaults.io.alwaysUseProxy) {
src = esriConfig.defaults.io.proxyUrl + "?" + src;
}
}
}
return src;
},

0 Kudos