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?
Es gibt 5 Schritte. Ich verwende diese Methode häufig zur Ausgabe von Inline-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.
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);
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')
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);
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");
};
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!