wake-up-neo.net

Wie kann ich eine SVG-Datei nach dem Erstellen einer SVG-Datei mit D3.js (IE, Safari und Chrome) speichern/exportieren?

Ich habe derzeit eine Website, die D3 verwendet, und ich möchte, dass der Benutzer die Option hat, die SVG-Datei als SVG-Datei zu speichern. Ich verwende dazu crowbar.js, aber es funktioniert nur auf Chrom. Bei safari geschieht nichts, und IE gewährt Zugriff auf die in crowbar.js verwendete click()-Methode, um die Datei herunterzuladen.

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);

Wie lade ich eine SVG-Datei auf Basis des SVG-Elements auf meiner Website in Safari, IE und Chrome herunter?

40
Vanquiza

Es gibt 5 Schritte. Ich verwende diese Methode häufig zur Ausgabe von Inline-SVG.

  1. holen Sie sich das Inline-Svg-Element zur Ausgabe.
  2. svg-source mit XMLSerializer abrufen.
  3. fügen Sie Namensräume von SVG und Xlink hinzu.
  4. erstellen Sie das URL-Datenschema von svg mit der encodeURIComponent-Methode.
  5. setzen Sie diese URL auf das href-Attribut eines "a" -Elements und klicken Sie mit der rechten Maustaste auf diesen Link, um die svg-Datei herunterzuladen.

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

Ich weiß, dass dies bereits beantwortet wurde, und diese Antwort funktioniert meistens gut. Ich habe jedoch festgestellt, dass es auf Chrome fehlgeschlagen ist (aber nicht Firefox), wenn das svg-Abbild großformatig war (etwa 1 MB). Es funktioniert, wenn Sie ein Blob-Konstrukt verwenden, wie in hier und hier beschrieben. Der einzige Unterschied ist das Typargument. In meinem Code wollte ich eine einzelne Taste drücken, um die svg für den Benutzer herunterzuladen, was ich mit folgendem erreicht habe:

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

Dave's und defghi1977 Antworten kombinieren. Hier ist eine wiederverwendbare Funktion:

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);
}

Aufrufbeispiel:

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

Ich habe hier jede Lösung ausprobiert und nichts hat bei mir funktioniert. Mein Bild war immer kleiner als meine d3.js Leinwand.

Ich musste die Zeichenfläche width, height einstellen und dann ein clearRect auf dem context ausführen, damit es funktioniert. Hier ist meine Arbeitsversion

Exportfunktion:

var svgHtml = document.getElementById("d3-canvas"),
    svgData = new XMLSerializer().serializeToString(svgHtml),
    svgBlob = new Blob([svgData], {type:"image/svg+xml;charset=utf-8"}),
    bounding = svgHtml.getBoundingClientRect(),
    width = bounding.width * 2,
    height = bounding.height * 2,
    canvas = document.createElement("canvas"),
    context = canvas.getContext("2d"),
    exportFileName = 'd3-graph-image.png';

//Set the canvas width and height before loading the new Image
canvas.width = width;
canvas.height = height;

var image = new Image();
image.onload = function() {
    //Clear the context
    context.clearRect(0, 0, width, height);
    context.drawImage(image, 0, 0, width, height);

    //Create blob and save if with FileSaver.js
    canvas.toBlob(function(blob) {
        saveAs(blob, exportFileName);
    });     
};
var svgUrl = URL.createObjectURL(svgBlob);
image.src = svgUrl;

Es benutzt FileSaver.js um die Datei zu speichern.

Dies ist meine Canvas-Erstellung. Beachten Sie, dass ich das Namespace-Problem hier löse

d3.js Canvas-Erstellung:

var canvas = d3.select("body")
    .insert("svg")
    .attr('id', 'd3-canvas')
    //Solve the namespace issue (xmlns and xlink)
    .attr("xmlns", "http://www.w3.org/2000/svg")
    .attr("xmlns:xlink", "http://www.w3.org/1999/xlink")
    .attr("width", width)
    .attr("height", height);
0
Ludovic Feltz

Damit dieses Snippet funktioniert, benötigen Sie 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

Verwenden Sie nebenbei keine RGB-Inline-Farben. # FFF000

Es scheint, dass das # in xml ungültig ist. Es muss in eine HTML-Entität codiert werden.

Verwenden Sie am besten hsl oder hsla

0
Cryptopat