Search code examples
jquerygoogle-mapsd3.jshtml2canvas

The ability to download an d3.js overlay on a google map using html2canvas


For this one project, I have a user bringing up a Google map with a d3.js overlay on top of it. Then the user should have the ability to download the map with the overlay as a .png file for their use. The problem is that the d3.js overlay is not appearing on the download. Note I have modified another fiddle with a Google map overlay since I am not permitted to show the actual data and map, but I have added the call to html2canvas to demonstrate my problem

JSFiddle

     $("#btnClickHere").on("click", function() {
            //get transform value
            var transform = $(".gm-style>div:first>div").css("transform");
            var comp = transform.split(","); //split up the transform matrix
            var mapleft = parseFloat(comp[4]); //get left value
            var maptop = parseFloat(comp[5]); //get top value
            $(".gm-style>div:first>div").css({
                //get the map container. not sure if stable
                "transform": "none",
                    "left": mapleft,
                    "top": maptop,
            });
            html2canvas($("#map")[0], {
                useCORS: true,
                background: "#E8F0F6",
                onrendered: function(canvas) {

                    $(".gm-style>div:first>div").css({
                        left: 0,
                        top: 0,
                            "transform": transform
                    });

                    //     $this.appendChild(canvas);

                    var a = document.createElement('a');
                    a.download = name;
                    a.href = canvas.toDataURL('image/png');
                    document.body.appendChild(a);
                    a.click();


                },
                width: 800,
                height: 500,
            });
        });

Solution

  • Your SVG positioning is very strange:

    .SvgOverlay svg {
      position: absolute;
      top: -4000px;
      left: -4000px;
      width: 8000px;
      height: 8000px;
    }
    

    My initial thought that it's just off the page. Sure enough when you move it:

    .SvgOverlay svg {
       position: absolute;
       top: 0px;
       left: 0px;
     }
    

    Give it appropriate size:

    var svg = layer.append("svg").attr("width",500).attr("height",500);
    

    And remove the strange re-positioning:

    return [pixelCoordinates.x, pixelCoordinates.y];
    

    It overlays in the png, updated fiddle here.

    EDITS

    Oh and one more thing, looks like you need to set the styles explicitly on the element to get them carried into the resulting canvas. Update link above.

    .attr("d", path)
    .style("fill", "orange").style("stroke-width", 2).style("fill-opacity",0.3).style("stroke","orange");