2013-04-17 11 views
26

Ich arbeite an einer Client-Seite/Javascript-Funktion zum Speichern oder Konvertieren eines vorhandenen D3-SVG-Diagramm in eine Datei. Ich habe viel gesucht und einige Empfehlungen gefunden, hauptsächlich mit canvas.toDataURL().Wie zu konvertieren/speichern d3.js Grafik zu pdf/JPEG

Ich habe keine <canvas> in meine Seite, und statt mit: d3.select("body").append("svg").... Ich habe auch versucht, die SVG zum <canvas> aber es passiert nichts anhängen.

Könnten Sie mir bitte helfen, diese Ausnahme zu beheben:

Uncaught TypeError: Object #<SVGSVGElement> has no method 'toDataURL' 

Danke

+0

Für In-Browser-Konvertierung zu PNG, überprüfen Sie http://StackOverflow.com/Questions/3975499/Convert-Svg-To-image-jpeg-png-etc-in-the-browser – widged

+0

Wenn nicht müssen zur Laufzeit sein, Werkzeuge wie Casperjs können Sie einen Screenshot von einem beliebigen Element auf der Seite http://casperjs.org/api.html#casper.captureSelector – widged

+0

machen Für den PDF-Export, siehe http://stackoverflow.com/questions/3360641/How-to-Ein-svg-Datei-in-einem-PDF-Dokument einfügen. – widged

Antwort

19

Ihr svg, innerhalb einer Leinwand anzuzeigen, müssen Sie zunächst einen Parser/Renderer Dienstprogramm konvertieren mit wie http://code.google.com/p/canvg/

(Code adaptiert aus: Convert SVG to image (JPEG, PNG, etc.) in the browser, nicht getestet)

// the canvg call that takes the svg xml and converts it to a canvas 
canvg('canvas', $("#my-svg").html()); 

// the canvas calls to output a png 
var canvas = document.getElementById("canvas"); 
var img = canvas.toDataURL("image/png"); 
+1

Die erste Zeile wird nicht funktionieren, weil 1. canvg auf die URL wartet, nicht die eigentlichen XML-Daten und 2. $ ('svg'). Html() würde auch nicht funktionieren - Sie benötigen innerSVG JS-Bibliothek, um Zugriff zu bekommen Inneres SVG XML. – WASD42

+0

'canvg (document.getElementById ('drawingArea'), ' ...') wird als Verwendung https://github.com/gabelerner/canvg angegeben. Changed '$ ('svg') .html()' in '$ (" # my-svg ") .html()'. – widged

+1

Sobald Sie img haben, wie lösen Sie einen Download davon aus? – rjurney

3

Wie bereits von @Premasagar in diesem Kommentar zu dieser Frage aus Convert SVG to image (JPEG, PNG, etc.) in the browser

Wenn die borwser sowohl SVG und Canvas unterstützen Sie diese Technik https://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/index.html

function importSVG(sourceSVG, targetCanvas) { 
    // https://developer.mozilla.org/en/XMLSerializer 
    svg_xml = (new XMLSerializer()).serializeToString(sourceSVG); 
    var ctx = targetCanvas.getContext('2d'); 

    // this is just a JavaScript (HTML) image 
    var img = new Image(); 
    // http://en.wikipedia.org/wiki/SVG#Native_support 
    // https://developer.mozilla.org/en/DOM/window.btoa 
    img.src = "data:image/svg+xml;base64," + btoa(svg_xml); 

    img.onload = function() { 
     // after this, Canvas’ origin-clean is DIRTY 
     ctx.drawImage(img, 0, 0); 
    } 
} 
6

Nur ein Heads-up, dass ich dieses Konzept einge verwenden können in eine kleine JavaScript-Bibliothek: https://github.com/krunkosaurus/simg

Es konvertiert einfach jedes SVG in ein Bild, um einen Download auszulösen oder auszulösen. Idee von hier: http://techslides.com/save-svg-as-an-image/

+0

Ich versuche Sie js Bibliothek, aber funktioniert nicht. Der Code von techslides funktioniert, obwohl nicht in Firefox 33.0 Eine Sache, die ich bemerke, ist, dass Ihr Code die a.href auf die img src, anstelle der Canvas-Daten URL verweist. Irgendwelche Ideen? – Sebastian

+0

Auch wenn ich ein LineChart von DC.js verwende und die PNG-Datei sieht aus wie CSS-Stile wurden nicht angewendet, obwohl ich alle dc.css in den HTML-Code eingefügt. – Sebastian

+0

@sebastian: Nur ein Heads-Up, nachdem ich ein paar Pull-Anforderung erhalten habe, ging ich voran und aktualisierte die Codebasis mit Dokumentation und mehr Funktionen. –

1

Die Simg-Bibliothek erstellt und vorgeschlagen von Mauvis Ledford oben funktioniert hervorragend für die Erlaubnis, meine Svg-Charts mit Dimple erstellt heruntergeladen werden.

Ich musste jedoch einen Aspekt des Codes ändern, damit es funktioniert. Innerhalb des toString() - Prototyps, innerhalb der forEach-Schleife (Zeile 37), wird, wenn Sie "svg.setAttribute (..)" in "svg [0] .setAttribute" ändern, das "setAttribute (..) is not" verringert eine Funktion "Fehler. Gleichermaßen muss das Gleiche in der return-Anweisung direkt unten gemacht werden, indem "[0]" nach svg (Zeile 39) angefügt wird.

Ich musste auch manuell die "canvas.width" - und "canvas.height" -Zeilen im toCanvas() - Prototyp bearbeiten, um das heruntergeladene Bild zu einer korrekten Größe zu machen (das war es) zuvor nur ein statisches 300x150 Quadrat in der oberen linken Ecke des Diagramms herunterladen).