I reckon that GeoServer layer label style has excellent feature of TextSymbolizer where text label can be positioned relatively on centroid of VISIBLE PART of polygon, as oppose to a geographically fixed position. The GeoServer website states that <sld:Graphic> can be specified in a <sld:TextSymbolizer>.

With this kind of placement i also need to visualise piechart. This is where i found difficulties.

Here is my SLD, within the <sld:TextSymbolizer> there's a piechart <sld:ExternalGraphic> and a <sld:Label>.

<?xml version="1.0" encoding="UTF-8"?>
<sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld"
                  xlink:href="http://chart?cht=p&amp;chd=t:${100 * revenue_percentage},${100 * (1 - revenue_percentage)}&amp;chf=bg,s,FFFFFF00" />
              <ogc:Literal>PIECHART GRAPHIC</ogc:Literal>
              <sld:CssParameter name="font-family">SansSerif</sld:CssParameter>
              <sld:CssParameter name="font-size">14</sld:CssParameter>
              <sld:CssParameter name="font-style">normal</sld:CssParameter>
              <sld:CssParameter name="font-weight">bold</sld:CssParameter>
              <CssParameter name="fill-opacity">1</CssParameter>

I found that:

  1. In order a graphic to show, <sld:Label> text must be present in a <sld:TextSymbolizer>. And the <sld:Label> must not be empty. If <sld:Label> is not wanted then the only getaway is to hide it with <CssParameter name="fill-opacity">0</CssParameter>
  2. If <sld:Label> is not wanted it is good to put a shortest possible string in the <sld:Label><ogc:Literal> (for example a point ".") to make sure that <sld:Graphic> element of the same <sld:Rule> are drawn.
  3. With <sld:Label> in <sld:TextSymbolizer>, GeoServer GUI complaints when i click the "Validate" button in Style Editor. The Style Editor says enter image description here while i believe <Priority> and <VendorOption> are optional. However, the style can be submitted and can be use with a WMS Layer without error.
  4. The piechart <sld:ExternalGraphic> never showed up in WMS, and not even an error message from GeoServer (this is observed using FireBug, the request is fine and nothing is wrong).enter image description hereBy the way the expected piechart is below

enter image description here

  1. If I replace the piechart in <sld:ExternalGraphic> with a PNG image then the PNG Images are drawn nicely in WMS response, off course with <sld:Label> in the <sld:TextSymbolizer>. The expected placement works. The <sld:Size> also works, depending on value of a field. enter image description here Screenshot below is when i panned slightly to the west.enter image description here
  2. If I replace the <sld:TextSymbolizer> with <sld:PointSymbolizer>, the piechart shows. Surely if i panned the map, the piechart stay at the same geographic location. Unfortunately the extent in the above images do not cover centroid of polygon, hence the below screenshot uses different extent. Here's the screenshot:enter image description here

My questions:

  1. How to make the piechart <sld:ExternalGraphic> in <sld:TextSymbolizer> drawn in WMS response?
  2. Is this because <sld:TextSymbolizer> doesn't like piechart <sld:ExternalGraphic> ?

My environment:

  • GeoServer 2.5 (+Chart Extension) on Apache Tomcat 6.0.35
  • OpenLayers 2.12
  • PostgreSQL 9.2.4-1 + PostGIS 2.0.3-2
  • Windows Server 2003 32-bit

2 Answers 2


So you raise a number of issues:

  1. If there is no label to draw then the renderer will skip the entire rule as a speed up. Since the external graphic is designed to back the label it also gets skipped.

  2. The validation fails because <Label> should be the first element of the <TextSymbolizer>.

  3. It is entirely possible that you can not use a TextSymbolizer's graphic element to display a pie chart (it is not what it is designed for).

So this seems to come down to where the <PointSymbolizer> will place the pie chart. In normal use it will place it on the centroid of the polygon which seems like a good plan. However you can control that using the <Geometry> element.

To acheive the effect you want you will need something like the following to intersect your geometry and the current bounding box:

  <ogc:Function name="intersection">
    <ogc:Function name="env">

Please note that there is no guarantee that the above will work with really old versions of geoserver like 2.5, please upgrade to at least 2.11.x.

  • It works! I tried the <Geometry> part in Geoserver 2.14 style and it works as expected with US states map included as sample in Geoserver. Unfortunately it does not work with my map. And for this I posted another question, please kindly review it.
    – Rino
    May 31, 2019 at 7:55

(1 - revenue_percentage)}&chf=bg,s,FFFFFF00" />

Your problem is ()} see

(1 - revenue_percentage)}


{1 - revenue_percentage}
  • Apologize for the above comment :) The CHD represents the chart data. It specifies that the chart has 2 portions (separated by comma). You are right that each is computed within ${ }. But am sure that it has to be ${100 * (1 - revenue_percentage)}.
    – Rino
    May 18, 2017 at 1:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.