Search code examples
svgrenderingshape-rendering

Adjacent svg:polygon edges do not meet


I am drawing a bar chart using polygons next to each other like this:

If you look closely, there are white spaces between each polygon (zoomed):

I am trying to prevent this from happening. I found out SVG shape-rendering attribute and set it to geometricPrecision. This solved the problem but gave me very crisp edges:

I do not want that either. I tried other possible values for shape-rendering but none worked well. (I tried these on WebKit.) I am looking for a solution.

For those interested, jsFiddle of the chart here.


Solution

  • Really the problem is that you should be rendering the graph as a single polygon rather than one polygon for each bar, but I'm assuming there is a reason you are doing it this way.

    One possible solution is to set the stroke properties, so the outline of the polygons are drawn, causing them to slightly overlap. You can set those properties on the group element to apply them to all the enclosed polygons.

    <g stroke-width="0.5" stroke="black" stroke-linejoin="round">
    

    Updated jsFiddle link

    Note that this makes the graph look slightly biggger than it should be, but I don't think that's a significant problem.

    As for the reason why it is happening, that is because the offsets of your polygons aren't exactly aligned on pixel boundaries (at least most of the time). If you fixed the svg width at a multiple of 300px (thus aligning everything on pixel boundaries) the gaps should go away.

    Consider a 4x4 pixel area, where you are trying to render a square from (0,0) to (2.5,2.5) like this:

    enter image description here

    You can paint the pixels from (0,0) to (1,1) in solid black, but how do you handle the edges - they're neither completely black nor completely white. The anti-aliasing solution is to use a shade of grey proportional to how much of the pixel is covered.

    enter image description here

    But then when you try and render another polygon right next to the first one (i.e. starting at an offset of 2.5), you are going to have the same issue anti-aliasing the left hand edge. Only it'll be slightly darker this time since the background is grey rather than white.

    enter image description here

    As you have found, you can disable this effect by setting a different shape-rendering option, but then you lose the benefit of the anti-aliasing on sloped lines, making those edges look jagged.