D3.js(IE, Safari 및 chrome)로 SVG를 만든 후 SVG 파일을 저장/내보내는 방법은 무엇입니까?
저는 현재 D3를 사용하는 웹사이트를 가지고 있는데 사용자가 SVG를 SVG 파일로 저장할 수 있는 옵션을 갖고 싶습니다.crowbar.js를 사용하여 이 작업을 수행하고 있지만 크롬에서만 작동합니다.사파리는 아무 일도 일어나지 않으며 IE는 에 대한 액세스를 거부합니다.click()
crowbar.js에서 파일을 다운로드하는 데 사용되는 메서드입니다.
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);
사파리, IE 및 크롬에서 웹 사이트의 SVG 요소를 기반으로 하는 SVG 파일을 다운로드하려면 어떻게 해야 합니까?
5단계가 있습니다.저는 인라인 svg를 출력할 때 이 방법을 자주 사용합니다.
- inline svg 요소를 출력합니다.
- XML Serializer에서 svg 소스를 가져옵니다.
- svg와 xlink의 이름 공간을 추가합니다.
- 인코딩을 통해 svg의 url 데이터 스킴 구성URI 컴포넌트 방식.
- 이 URL을 "a" 요소의 href 속성으로 설정하고 이 링크를 마우스 오른쪽 버튼으로 클릭하여 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.
이것은 이미 답변이 완료되었고, 대부분의 경우 그 답변이 잘 작동한다는 것을 알고 있습니다.그러나 svg 이미지가 큰(약 1MB) 경우 Chrome(Firefox는 아님)에서 실패한 것을 발견했습니다.사용할 때 다시 A를 사용하면 효과가 있습니다.Blob
여기와 여기에 설명된 바와 같이 구성합니다.유일한 차이점은 유형 인수입니다.내 코드에서 나는 사용자를 위해 svg를 다운로드할 수 있는 버튼을 한 번 눌러야 했습니다.
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);
2019년 10월 편집:이 코드는 추가하지 않아도 작동한다는 의견이 있습니다.downloadLink
로.document.body
그리고 그 후에 그것을 제거합니다.click()
. 예전에는 Firefox에서 작동했지만 지금은 작동하지 않습니다(Firefox에서는 추가 후 제거해야 함).downloadLink
). 이 코드는 Chrome에서 어느 쪽이든 작동합니다.
Dave와 defghi 1977의 답변을 합하면 됩니다.다음은 재사용 가능한 기능입니다.
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);
}
호출 예제:
saveSvg(svg, 'test.svg')
이 토막글이 작동하려면 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");
};
저는 여기서 모든 해결책을 시도했지만 아무것도 효과가 없었습니다.내 사진은 항상 내 d3.js 캔버스보다 작았습니다.
나는 캔버스를 세팅해야만 했습니다.width
,height
그다음에.clearRect
에서context
효과가 있습니다.여기 제 작업 버전이 있습니다.
내보내기 기능:
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;
FileSaver.js를 사용하여 파일을 저장합니다.
이것은 나의 캔버스 창작물입니다. 여기서 네임스페이스 문제를 해결한다는 것을 주목하십시오.
d3.js 캔버스 작성:
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);
이 질문에 답하는 동안 외부 스타일시트 또는 외부 정의 파일(사용)을 사용하는 D3.js 생성 SVG를 저장하는 데 도움을 줄 수 있는 SaveSVG라는 작은 라이브러리를 만들었습니다.<use>
그리고.def
를 지정합니다 태그.
@vasyl-vaskivskyi의 대답에 근거합니다.
<script src="../../assets/FileSaver.js"></script>
<script>
function save_as_svg(){
fetch('path/../assets/chart.css')
.then(response => response.text())
.then(text => {
var svg_data = document.getElementById("svg").innerHTML
var head = '<svg title="graph" version="1.1" xmlns="http://www.w3.org/2000/svg">'
var style = "<style>" + text + "</style>"
var full_svg = head + style + svg_data + "</svg>"
var blob = new Blob([full_svg], {type: "image/svg+xml"});
saveAs(blob, "graph.svg");
})
};
save_as_svg();
</script>
위 코드는 당신의 chart.css를 읽고 svg 파일에 css 코드를 내장합니다.
나는 이것을 시도하고 나를 위해 일했습니다.
function downloadSvg() {
var svg = document.getElementById("svg");
var serializer = new XMLSerializer();
var source = serializer.serializeToString(svg);
source = source.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink='); // Fix root xlink without namespace
source = source.replace(/ns\d+:href/g, 'xlink:href'); // Safari NS namespace fix.
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"');
}
var preface = '<?xml version="1.0" standalone="no"?>\r\n';
var svgBlob = new Blob([preface, source], { 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);
}
제 시나리오에서는 다른 프로젝트에서 D3.js를 사용하여 만든 svg 이미지를 사용해야 했습니다.그래서 dev 툴을 열고 그 svg를 검사하고 내용을 복사했습니다.그런 다음 빈 svg 파일을 새로 만들어 복사한 내용을 거기에 붙여 넣습니다.그런 다음 다른 지역의 새로운 svg 파일을 사용했습니다.
그리고 프로그래밍 방식으로 하려면 document.getElementById('svgId')를 사용할 수 있습니다.
이것이 기본적인 접근법이라는 것을 알고 있지만 누군가 유용하다고 생각할 경우가 있습니다.
언급URL : https://stackoverflow.com/questions/23218174/how-do-i-save-export-an-svg-file-after-creating-an-svg-with-d3-js-ie-safari-an
'programing' 카테고리의 다른 글
jQuery를 사용하여 링크에서 클릭을 프로그래밍적으로 트리거하는 방법은? (0) | 2023.10.08 |
---|---|
반응 네이티브에서 전체 화면 배경 이미지를 추가하는 가장 좋은 방법은 무엇입니까? (0) | 2023.10.08 |
첫번째를 제외한 모든 'tr'을 선택합니다. (0) | 2023.10.08 |
Django URLs TypeError: 보기는 include()인 경우 호출 가능 또는 목록/튜플이어야 합니다. (0) | 2023.10.03 |
작동하지 않는 자바스크립트 규칙은 무엇입니까? (0) | 2023.10.03 |