Server Side d3 – Encodage de SVG sous forme d’image Base64

J’essaie de coder un graphique D3 en tant qu’image base64 pour une utilisation dans des courriers électroniques HTML

Jusqu’à présent j’ai:

var express = require('express'); var app = express(); var jsdom = require('jsdom'); app.get('/chart', function (request, response) { try { jsdom.env( "", ['http://d3js.org/d3.v3.min.js'], function (err, window) { var svg = window.d3.select("svg") .attr("width", 100) .attr("height", 100); svg.append("rect") .attr("x", 10) .attr("y", 10) .attr("width", 80) .attr("height", 80) .style("fill", "orange"); var encoded = ...; // How do I now encode this? response.send({ "html": window.d3.select("body").html(), "encoded": encoded }); } ); } catch (err) { console.error(err); } }); // Run Server var port = process.env.PORT || 8305; var server = app.listen(port, function () { var host = server.address().address; console.log('App listening at http://%s:%s', host, port); }); 

Ceci produit le html SVG, ce qui est utile, mais je voudrais aussi un deuxième champ de réponse encoded qui devrait contenir quelque chose comme ci-dessous que je peux utiliser dans mon email HTML:

 "encoded": "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...etc" 

Comment puis-je encoder ce SVG? J’aimerais éviter toute écriture de fichier si possible et aller directement de SVG à une image encodée. De plus, je suis conscient que vous pouvez utiliser des SVG dans les courriels, mais je préférerais que ce soit au format d’image codée. Merci!

Définissez l’atsortingbut "xmlns" noeud racine sur "http://www.w3.org/2000/svg" sur le noeud document ou avec .attr() .

Le schéma d’ data URI consiste en

 data:[][;base64], 

Puisque nous soaps que le sera image/svg+xml et que nous voulons une représentation en base64 des données résultantes, nous pouvons définir une variable à laquelle nous concaténerons la représentation en base64 de .

 let data = "data:image/svg+xml;base64,"; 

Ensuite, nous obtenons le .outerHTML de l’élément

 // optionally preceded by `XML` declaration `` let svgSsortingng = svg[0][0].outerHTML; 

Appelez btoa() avec svgSsortingng tant que paramètre

La btoa(data ) doit émettre une exception DOMException ” InvalidCharacterError ” si la donnée contient un caractère dont le sharepoint code est supérieur à U + 00FF. Sinon, l’agent d’utilisateur doit convertir les données en une séquence d’octets dont le nième octet est la représentation sur huit bits du sharepoint code du nième caractère de données , puis appliquer l’algorithme base64 à cette séquence d’octets et renvoyer le résultat. [RFC4648]

 let base64 = window.btoa(svgSsortingng); // concatenate `data` and `base64` let dataURI = data + base64; response.send({ "html": window.d3.select("body").html(), "encoded": dataURI }); 
 let svg = window.d3.select("svg") .attr("xmlns", "http://www.w3.org/2000/svg") .attr("width", 100) .attr("height", 100); svg.append("rect") .attr("x", 10) .attr("y", 10) .attr("width", 80) .attr("height", 80) .style("fill", "orange"); let data = "data:image/svg+xml;base64,"; let svgSsortingng = svg[0][0].outerHTML; let base64 = window.btoa(svgSsortingng); let dataURI = data + base64; console.log(dataURI); document.querySelector("iframe").src = dataURI; 
    

Solution complète qui construit un graphique d3 à l’aide de NodeJS et le convertit en un fichier PNG codé sans utiliser le stockage de fichiers (nécessaire pour la plupart des hébergements en nuage)

 let express = require('express'); let app = express(); let jsdom = require('jsdom'); let Buffer = require('buffer').Buffer; let svg2png = require('svg2png'); app.post('/chart', function (request, response) { try { jsdom.env( "", ['http://d3js.org/d3.v3.min.js'], function (err, window) { let svg = window.d3.select("svg") .attr("width", 100) .attr("height", 100) .attr("xmlns", "http://www.w3.org/2000/svg"); svg.append("rect") .attr("x", 10) .attr("y", 10) .attr("width", 80) .attr("height", 80) .style("fill", "orange"); let data = "data:image/png;base64,"; let svgSsortingng = svg[0][0].outerHTML; let buffer = new Buffer("" + svgSsortingng); let promise = svg2png(buffer, {width: 300, height: 400}); // This options block is optional but height and width should be specified on the SVG HTML otherwise promise.then(buffer => { let dataURI = data + buffer.toSsortingng('base64'); response.set('Content-Type', 'application/json'); response.send({ "html": svgSsortingng, "encoded": dataURI }); }); } ); } catch (err) { console.warn(err); } }); // Run Server let port = process.env.PORT || 8305; let server = app.listen(port, function () { let host = server.address().address || 'localhost'; console.log('Example app listening at http://%s:%s', host, port); }); 

Le champ encoded dans la réponse peut être utilisé dans un email HTML en utilisant:

  

par exemple

  

Afin de l’envoyer sous forme d’image png, vous devez d’abord rastériser le svg, qui est le problème actuel. Cela a été répondu à plusieurs endroits, mais celui-ci contient un certain nombre de bonnes solutions. Vous devriez probablement utiliser imagemagick pour la conversion. Puisque vous voulez éviter d’écrire dans un fichier intermédiaire, cette réponse suggère que vous pouvez diriger le contenu de svg vers le stdin du convertisseur.

Le tampon reçu pourrait probablement être directement encodé en base64 .