2013-04-17 10 views
26

Sto lavorando su una funzione client/javascript per salvare o convertire un grafico D3-SVG esistente in un file. Ho cercato molto e ho trovato alcuni consigli, principalmente usando canvas.toDataURL().Come convertire/salvare il grafico d3.js in pdf/jpeg

ho alcuna <canvas> nella mia pagina, e invece utilizzando: d3.select("body").append("svg").... Ho anche provato ad aggiungere lo SVG al <canvas>, ma non succede nulla.

La prego di aiutarmi a risolvere questa eccezione:

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

Grazie

+0

Per la conversione nel browser in png, consultare http://stackoverflow.com/questions/3975499/convert-svg-to-image-jpeg-png-etc-in-thebrowser – widged

+0

Se non lo fa devi essere in fase di esecuzione, strumenti come casperjs ti permettono di fare uno screenshot di qualsiasi elemento nella pagina http://casperjs.org/api.html#casper.captureSelector – widged

+0

Per l'esportazione in pdf, vedi http://stackoverflow.com/questions/3360641/how-to-insert-a-svg-file-in-a-pdf-documento. – widged

risposta

19

Per visualizzare il formato SVG all'interno di una tela, bisogna prima convertirlo mediante un'utilità parser/renderer come http://code.google.com/p/canvg/

(codice adattato da: Convert SVG to image (JPEG, PNG, etc.) in the browser, non testato)

// 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

La prima riga non funzionerà perché 1. canvg attende l'URL, non i dati XML effettivi e 2. $ ('svg'). Html() non funzionerebbe - avrete bisogno della libreria JS innerSVG per accedere a XML interno SVG. – WASD42

+0

'canvg (document.getElementById ('drawingArea'), ' ...')' viene fornito come utilizzo https://github.com/gabelerner/canvg. Cambiato '$ ('svg'). Html()' a '$ (" # my-svg "). Html()'. – widged

+1

Una volta che hai img, come fai a far scattare un download? – rjurney

3

Come sottolineato dal @Premasagar in questo commento su questa questione Convert SVG to image (JPEG, PNG, etc.) in the browser

Se il borwser supporta sia SVG e tela è possibile utilizzare questa tecnica 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

Solo un testa a testa che ho girato questo concetto in una piccola libreria JavaScript: https://github.com/krunkosaurus/simg

converte semplicemente qualsiasi SVG ad un'immagine per scambiare o innescare un download. Idea presa da qui: http://techslides.com/save-svg-as-an-image/

+0

sto provando js library ma non funziona. Il codice di techslides funziona, anche se non in Firefox 33.0 Una cosa che noto è che il codice fa riferimento a a.href a img src, invece dell'URL di dati su tela. Qualche idea? – Sebastian

+0

Inoltre, sto usando un linechart da DC.js e il file png sembra che gli stili css non siano stati applicati, anche se ho incollato tutti i file dc.css nell'html. – Sebastian

+0

@sebastian: basti pensare che dopo aver ricevuto qualche richiesta di pull sono andato avanti e aggiornato il codebase con la documentazione e altre funzionalità. –

1

La libreria Simg creata e suggerita da Mauvis Ledford ha funzionato molto bene per consentire il download dei miei grafici svg creati con Dimple.

Avevo tuttavia bisogno di cambiare un aspetto del codice per farlo funzionare. All'interno del prototipo toString(), all'interno del ciclo forEach (riga 37), se si modifica "svg.setAttribute (..)" in "svg [0] .setAttribute" si allevierà "setAttribute (..) non è una funzione "errore. Allo stesso modo lo stesso deve essere fatto subito sotto nell'istruzione return, aggiungendo "[0]" dopo svg (riga 39).

Ho anche dovuto modificare manualmente le assegnazioni "canvas.width" e "canvas.height" (righe 48 & 49) nel prototipo toCanvas(), in modo da rendere l'immagine scaricata una dimensione più corretta (era in precedenza scarica semplicemente un quadrato statico 300x150 nell'angolo in alto a sinistra del grafico).