web-dev-qa-db-fra.com

Comment enregistrer/exporter un fichier SVG après avoir créé un fichier SVG avec D3.js (IE, Safari et Chrome)?

J'ai actuellement un site Web utilisant D3 et j'aimerais que l'utilisateur ait la possibilité d'enregistrer le SVG en tant que fichier SVG. J'utilise crowbar.js pour cela, mais cela ne fonctionne que sur chrome. Rien ne se passe de safari et IE donne un accès refusé sur la méthode click() utilisée dans crowbar.js pour télécharger le fichier.

var e = document.createElement('script'); 

if (window.location.protocol === 'https:') { 
    e.setAttribute('src', 'https://raw.github.com/NYTimes/svg-crowbar/gh-pages/svg-crowbar.js'); 
} else { 
    e.setAttribute('src', 'http://nytimes.github.com/svg-crowbar/svg-crowbar.js'); 
}

e.setAttribute('class', 'svg-crowbar'); 
document.body.appendChild(e);

Comment télécharger un fichier SVG basé sur l'élément SVG sur mon site Web dans safari, IE et chrome?

40
Vanquiza

Il y a 5 étapes. J'utilise souvent cette méthode pour générer des svg en ligne.

  1. récupère l'élément svg en sortie.
  2. obtenir svg source par XMLSerializer.
  3. ajoutez des espaces de noms de svg et xlink.
  4. construire un schéma de données url de svg avec la méthode encodeURIComponent.
  5. définissez cette URL sur l'attribut href d'un élément "a", puis cliquez avec le bouton droit sur ce lien pour télécharger le fichier svg.

//get svg element.
var svg = document.getElementById("svg");

//get svg source.
var serializer = new XMLSerializer();
var source = serializer.serializeToString(svg);

//add name spaces.
if(!source.match(/^<svg[^>]+xmlns="http\:\/\/www\.w3\.org\/2000\/svg"/)){
    source = source.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
}
if(!source.match(/^<svg[^>]+"http\:\/\/www\.w3\.org\/1999\/xlink"/)){
    source = source.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"');
}

//add xml declaration
source = '<?xml version="1.0" standalone="no"?>\r\n' + source;

//convert svg source to URI data scheme.
var url = "data:image/svg+xml;charset=utf-8,"+encodeURIComponent(source);

//set url value to a element's href attribute.
document.getElementById("link").href = url;
//you can download svg file by right click menu.
45
defghi1977

Je sais que cela a déjà été répondu, et cette réponse fonctionne bien la plupart du temps. Cependant, j'ai constaté qu'il échouait sur Chrome (mais pas Firefox) si l'image svg était de grande taille (environ 1 Mo). Cela fonctionne si vous recommencez à utiliser une construction Blob, comme décrit ici et ici . La seule différence est l'argument type. Dans mon code, je voulais appuyer sur un seul bouton pour télécharger le svg pour l'utilisateur, ce que j'ai accompli avec:

var svgData = $("#figureSvg")[0].outerHTML;
var svgBlob = new Blob([svgData], {type:"image/svg+xml;charset=utf-8"});
var svgUrl = URL.createObjectURL(svgBlob);
var downloadLink = document.createElement("a");
downloadLink.href = svgUrl;
downloadLink.download = "newesttree.svg";
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
33
DaveTheScientist

La combinaison des réponses de Dave et defghi1977. Voici une fonction réutilisable:

function saveSvg(svgEl, name) {
    svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
    var svgData = svgEl.outerHTML;
    var preface = '<?xml version="1.0" standalone="no"?>\r\n';
    var svgBlob = new Blob([preface, svgData], {type:"image/svg+xml;charset=utf-8"});
    var svgUrl = URL.createObjectURL(svgBlob);
    var downloadLink = document.createElement("a");
    downloadLink.href = svgUrl;
    downloadLink.download = name;
    document.body.appendChild(downloadLink);
    downloadLink.click();
    document.body.removeChild(downloadLink);
}

Exemple d'invocation:

saveSvg(svg, 'test.svg')
13
senz

Pour que cet extrait fonctionne, vous avez besoin de FileSaver.js.

function save_as_svg(){


        var svg_data = document.getElementById("svg").innerHTML //put id of your svg element here

        var head = '<svg title="graph" version="1.1" xmlns="http://www.w3.org/2000/svg">'

        //if you have some additional styling like graph edges put them inside <style> tag

        var style = '<style>circle {cursor: pointer;stroke-width: 1.5px;}text {font: 10px arial;}path {stroke: DimGrey;stroke-width: 1.5px;}</style>'

        var full_svg = head +  style + svg_data + "</svg>"
        var blob = new Blob([full_svg], {type: "image/svg+xml"});  
        saveAs(blob, "graph.svg");


};
0
Vasyl Vaskivskyi

Sur une note de côté, n'utilisez pas de couleurs inline RVB. # FFF000

Il semble que le # ne soit pas valide en xml, il doit être encodé dans une entité html.

Il vaut mieux utiliser hsl ou hsla à la place! 

0
Cryptopat