programing

D3.js(IE, Safari 및 chrome)로 SVG를 만든 후 SVG 파일을 저장/내보내는 방법은 무엇입니까?

closeapi 2023. 10. 8. 09:52
반응형

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를 출력할 때 이 방법을 자주 사용합니다.

  1. inline svg 요소를 출력합니다.
  2. XML Serializer에서 svg 소스를 가져옵니다.
  3. svg와 xlink의 이름 공간을 추가합니다.
  4. 인코딩을 통해 svg의 url 데이터 스킴 구성URI 컴포넌트 방식.
  5. 이 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

반응형