简体   繁体   English

我可以用d3附加一个文字SVG元素吗?

[英]Can I append a literal SVG element with d3?

I'd like to append a literal SVG element with d3. 我想用d3附加一个文字SVG元素。

So instead of writing 所以不要写作

svg.selectAll("circle")            
    .data(data)                    
    .enter()                       
    .append("circle")    // etc etc

I'd like to do: 我想这样做:

svg.selectAll("circle")            
    .data(data)                    
    .enter()                       
    .append('<circle cx="158.9344262295082" cy="200" r="16" fill="red"></circle>')   

so that I could create a complex template elsewhere (for example with handlebars), and then compile it with data and append it. 这样我就可以在别处创建一个复杂的模板(例如用把手),然后用数据编译并附加它。

You can do this, although not via the selection.append() function. 你可以这样做,虽然不是通过selection.append()函数。 Instead you'd need to use the selection.html() function. 相反,您需要使用selection.html()函数。

This would make it quite difficult to use in the context of data-joins, but not impossible. 这将使得在数据连接的上下文中使用非常困难,但并非不可能。 This is probably the best you could do, which involves adding an additional svg group to the DOM which may not be a bad thing anyway: 这可能是你可以做的最好的,这涉及到DOM添加一个额外的svg组,这可能不是一件坏事:

 var svg = d3.selectAll("svg"); svg.selectAll("circle") .data([50, 100, 150]) .enter() .append("g") .attr("transform", function(d) { return "translate(" + [d, d] + ")"; }) .html('<circle r="16" fill="red"></circle>'); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <svg width="500" height="500"></svg> 

I guess taking this answer a bit further, you could actually embed the result that you wish to render directly into your data object. 我想更进一步地回答这个问题,你实际上可以将想要直接渲染的结果嵌入到data对象中。 So you've add some code that looked like: 所以你添加了一些看起来像的代码:

.html(function(d) { return d.templatedHTML; });

At this point however stop and ask yourself the question: "What am I using D3 for?". 然而,此时停下来问自己一个问题:“我用D3做什么?”。 D3 is described as D3被描述为

Data Driven Documents 数据驱动文档

If you're using something like handlebars, then you're taking away one of the core responsibilities that D3 was designed for (building some DOM from some data) and giving it to some other library. 如果您正在使用像把手这样的东西,那么您将剥夺D3为其设计的核心职责之一(从某些数据构建一些DOM)并将其交给其他库。

I'm not stating you shouldn't do that (as you did mention complex templates) but do just ask yourself the question to make sure that it's a path you wish to go down. 我并没有说你不应该这样做(因为你提到了复杂的模板)但是只要问问自己这个问题,以确保它是你希望失败的道路。

No, you can't. 不,你不能。 Don't believe me? 不相信我? Check their docs HERE 这里查看他们的文档

What you must do is call .append() , followed by several calls of .attr(attr_name, attr_value) to set each attribute's value. 你必须做的是调用.append() ,然后调用几次.attr(attr_name, attr_value)来设置每个属性的值。 D3 does not work like jQuery. D3不像jQuery那样工作。

D3 doesn't provide this functionality, and it does not make much sense (when you think about manipulating elements based on data). D3不提供此功能,并且它没有多大意义(当您考虑基于数据操作元素时)。

But, as a side note, you can implement your own function to append a literal SVG element. 但是,作为旁注,您可以实现自己的函数来附加文字SVG元素。

This is a function created by Chris Viau , named appendSVG : 这是由Chris Viau创建的函数,名为appendSVG

d3.selection.prototype.appendSVG = 
    d3.selection.enter.prototype.appendSVG = function(SVGString) {
        return this.select(function() {
            return this.appendChild(document.importNode(new DOMParser()
                .parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' + SVGString + 
            '</svg>', 'application/xml').documentElement.firstChild, true));
        });
    };

After extending the prototype, you can use it: 扩展原型后,您可以使用它:

selection.appendSVG("<some literal SVG element>");  

Here is a demo. 这是一个演示。 First, we set the data: 首先,我们设置数据:

var data = [{x:30,y:50},{x:420,y:100},{x:160,y:150},{x:260,y:30}];

Then, we append our literal SVG element in the usual way: 然后,我们以通常的方式附加我们的文字SVG元素:

var myLiteral = svg.selectAll(".literal")
    .data(data)
    .enter()
    .appendSVG("<literal SVG here>");

And finally we set the positions using translate : 最后我们使用translate设置位置:

.attr("transform", function(d){ 
    return "translate(" + d.x + "," + d.y + ")";
});

Check the snippet: 检查代码段:

 d3.selection.prototype.appendSVG = d3.selection.enter.prototype.appendSVG = function(SVGString) {return this.select(function() { return this.appendChild(document.importNode(new DOMParser().parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' + SVGString + '</svg>', 'application/xml').documentElement.firstChild, true));});}; var svg = d3.select("body").append("svg").attr("width", 500).attr("height", 300); var data = [{x:30,y:50},{x:420,y:100},{x:160,y:150},{x:260,y:30}]; var myLiteral = svg.selectAll(".literal") .data(data) .enter() .appendSVG("<path d='M 22.889471,25.607172 C 22.589713,24.605127 24.092318,24.708731 24.554936,25.108955 C 25.808602,26.193538 25.053398,28.14136 23.885905,28.938102 C 21.797533,30.363287 19.018523,29.16303 17.893076,27.101823 C 16.241437,24.076919 17.936475,20.36976 20.896603,18.945312 C 24.841988,17.046747 29.504523,19.25402 31.216796,23.116087 C 33.371517,27.976105 30.644503,33.605344 25.878773,35.599962 C 20.106834,38.015712 13.505062,34.765112 11.231216,29.094691 C 8.551568,22.412295 12.327973,14.834577 18.903736,12.283452 C 26.495714,9.3380778 35.051552,13.641683 37.878656,21.12322 C 41.09099,29.624218 36.259254,39.159651 27.87164,42.261821 C 18.462006,45.741988 7.9459296,40.381466 4.5693566,31.087558 C 0.82072068,20.769559 6.7105029,9.2720694 16.910868,5.6215926' style='fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1'/>") .attr("transform", function(d){ return "translate(" + dx + "," + dy + ")"}); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM