(嵌入和)通过 D3 和/或 javascript 引用外部 SVG [英] (Embed and) Refer to an external SVG via D3 and/or javascript

查看:40
本文介绍了(嵌入和)通过 D3 和/或 javascript 引用外部 SVG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .svg 文件,想将它嵌入到我的 d3-graphic 的 svg 结构中.

我还需要通过特定 g 元素的 id 引用附加到 g 元素的所有路径/多边形.

我尝试了不同的方法来嵌入和引用 svg (g's),但由于某些原因没有奏效:

(1) 第一次尝试

//Firefox 显示我的 svg 但当我用 Chrome 打开它时 svg//不显示(只是默认占位符图标)//我无法使用 d3.select 函数引用 svg-g id.main_chart_svg.append("svg:image").attr("xlink:href", "mySVGpicture.svg").attr("x", "50").attr("y", "50").attr("宽度", "500").attr("高度", "500");main_chart_svg.select("#anIdWhichIsInTheSvgFile").remove();////这不起作用

(2) 第二次尝试

//这在我的主图表 svg 中显示 svg 但 - 不是 - .我想保留图形//事物与html-stuff分开.d3.xml("mySVGpicture.svg", "image/svg+xml", function(xml) {document.body.appendChild(xml.documentElement);});//-  -  -  -  - 或者 -  -  -  -  -//d3.select("body").append("对象").attr("数据", "mySVGpicture.svg").attr("宽度", 500).attr("高度", 500).attr("type", "image/svg+xml");d3.select("#anIdThatIsInTheSvgFile").remove();//不起作用.

(3) svg 文件看起来像这样:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 宽度="400px"height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve"><g id="anIdWhichIsInTheSvgFile"><g id="DE"><path fill="#FEDCBD" d="M215.958,160.554c0,0-0.082, ... ,1.145l0.865,0.656L215.958,160.554z"/><path fill="#FEDCBD" d="M208.682,155.88l1.246,1.031c0,0,0.191,0.283, ... ,0.572L208.682,155.88z"/><polygon fill="#FEDCBD" points="190.76,153.007 190.678, ... ,153.938191.427,152.906"/><polygon fill="#FEDCBD" points="170.088,151.015 169.888,150.067 169.125,150.075 168.846,150.836 169.521,151.588"/><polygon fill="#FEDCBD" points="168.953,152.067 168.188,151.505 168.674,152.639"/><polygon fill="#FEDCBD" points="170.105,153.099 170.666,152.052 170.002,152.248"/></g><g id="anIdThatIsInTheSvgFile">...</g></svg>

解决方案

有更好的解决方案.

我没有意识到 d3.xml() 函数返回一个读入的 xml 文件作为 文档片段(而不是将其转换为 JSON).换句话说,它返回一个现成的 DOM 树,可以在您需要的任何位置插入主文档的 DOM.

知道(并且知道独立的 SVG 文件也是 XML 文件),这可能是将外部 SVG 内容添加到您的网页的最可靠方法:

d3.xml("http://upload.wikimedia.org/wikipedia/commons/a/a0/Circle_-_black_simple.svg",功能(错误,文档片段){如果(错误){console.log(错误);返回;}var svgNode = 文档片段.getElementsByTagName("svg")[0];//使用纯Javascript提取节点main_chart_svg.node().appendChild(svgNode);//d3 的 selection.node() 返回的是 DOM 节点,所以我们//可以使用普通的Javascript来追加内容var innerSVG = main_chart_svg.select("svg");innerSVG.transition().duration(1000).delay(1000).select("圆").attr("r", 100);});

在这里摆弄:http://jsfiddle.net/J8sp3/4/

请特别注意 (a) 我将内容添加到现有 SVG,并且 (b) 我不会删除该 SVG 的任何当前内容.

当然,您也可以将 SVG 添加到

或任何其他可以包含它的元素:http://jsfiddle.net/J8sp3/3/

此方法应该适用于任何支持 SVG 的浏览器.我什至在IE8中试过,即使IE8不会画圆和矩形,DOM结构也是正确的!

@Seb,请在选择此答案作为已接受的答案时取消选择上一个答案.

I have an .svg file and want to embed it in the svg strucure of my d3-graphic.

I also need to reference all paths/polygons attached to g-elements via an id of certain g elements.

I tried different ways to to embed and reference the svg (g's), but it didn't work for some reasons:

(1) first attempt

// Firefox displays my svg but when i open it with Chrome the svg     
//is not displayed (just default placeholder icon)
// I can't reference the svg-g id's with d3.select functions. 
main_chart_svg
        .append("svg:image")
        .attr("xlink:href", "mySVGpicture.svg")
        .attr("x", "50")
        .attr("y", "50")
        .attr("width", "500")
        .attr("height", "500");  

main_chart_svg.select("#anIdWhichIsInTheSvgFile").remove(); //// This doesn't work

(2) second attempt

// This displays the svg but -not- inside my main-chart-svg. I want to keep the graphic   
//things seperate to html-stuff.
d3.xml("mySVGpicture.svg", "image/svg+xml", function(xml) {
        document.body.appendChild(xml.documentElement);
    });
//----------or----------//
    d3.select("body")
        .append("object")
        .attr("data", "mySVGpicture.svg")
        .attr("width", 500)
        .attr("height", 500)
        .attr("type", "image/svg+xml");

d3.select("#anIdThatIsInTheSvgFile").remove(); //does not work.

(3) The svg-file looks something like that:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="400px"
     height="400px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve">
    <g id="anIdWhichIsInTheSvgFile">
        <g id="DE">
            <path fill="#FEDCBD" d="M215.958,160.554c0,0-0.082, ... ,1.145
                l0.865,0.656L215.958,160.554z"/>
            <path fill="#FEDCBD" d="M208.682,155.88l1.246,1.031c0,0,0.191,0.283, ... ,0.572L208.682,155.88z"/>
            <polygon fill="#FEDCBD" points="190.76,153.007 190.678, ... ,153.938 
                191.427,152.906"/>
            <polygon fill="#FEDCBD" points="170.088,151.015 169.888,150.067 169.125,150.075 168.846,150.836 169.521,151.588"/>
            <polygon fill="#FEDCBD" points="168.953,152.067 168.188,151.505 168.674,152.639"/>
            <polygon fill="#FEDCBD" points="170.105,153.099 170.666,152.052 170.002,152.248"/>
    </g>
    <g id="anIdThatIsInTheSvgFile">
    ...
    </g>
</svg>

解决方案

There's a better solution.

I hadn't realized that the d3.xml() function returns a read-in xml file as a document fragment (as opposed to converting it to JSON). In other words, it returns a ready-made DOM tree that can be inserted within you main document's DOM wherever you need it.

Knowing that (and knowing that stand-alone SVG files are also XML files), this is likely the most reliable approach for adding external SVG content to your webpage:

d3.xml("http://upload.wikimedia.org/wikipedia/commons/a/a0/Circle_-_black_simple.svg", 
        function(error, documentFragment) {

    if (error) {console.log(error); return;}

    var svgNode = documentFragment
                .getElementsByTagName("svg")[0];
    //use plain Javascript to extract the node

    main_chart_svg.node().appendChild(svgNode);
    //d3's selection.node() returns the DOM node, so we
    //can use plain Javascript to append content

    var innerSVG = main_chart_svg.select("svg");

    innerSVG.transition().duration(1000).delay(1000)
          .select("circle")
          .attr("r", 100);

});

Fiddle here: http://jsfiddle.net/J8sp3/4/

Notice in particular that (a) I am adding the content to an existing SVG, and (b) I am not deleting any of that SVG's current content.

Of course, you can also add the SVG to a <div> or any other element that can contain it: http://jsfiddle.net/J8sp3/3/

This method should work in any browser that supports SVG. I even tried it in IE8, and the DOM structure is correct even if IE8 doesn't know how to draw circles and rectangles!

@Seb, please unselect the previous answer at pick this one as the accepted answer.

这篇关于(嵌入和)通过 D3 和/或 javascript 引用外部 SVG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆