[英]Can I append a literal SVG element with d3?
我想用d3附加一個文字SVG元素。
所以不要寫作
svg.selectAll("circle")
.data(data)
.enter()
.append("circle") // etc etc
我想這樣做:
svg.selectAll("circle")
.data(data)
.enter()
.append('<circle cx="158.9344262295082" cy="200" r="16" fill="red"></circle>')
這樣我就可以在別處創建一個復雜的模板(例如用把手),然后用數據編譯並附加它。
你可以這樣做,雖然不是通過selection.append()
函數。 相反,您需要使用selection.html()函數。
這將使得在數據連接的上下文中使用非常困難,但並非不可能。 這可能是你可以做的最好的,這涉及到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>
我想更進一步地回答這個問題,你實際上可以將想要直接渲染的結果嵌入到data
對象中。 所以你添加了一些看起來像的代碼:
.html(function(d) { return d.templatedHTML; });
然而,此時停下來問自己一個問題:“我用D3做什么?”。 D3被描述為
數據驅動文檔
如果您正在使用像把手這樣的東西,那么您將剝奪D3為其設計的核心職責之一(從某些數據構建一些DOM)並將其交給其他庫。
我並沒有說你不應該這樣做(因為你提到了復雜的模板)但是只要問問自己這個問題,以確保它是你希望失敗的道路。
不,你不能。 不相信我? 在這里查看他們的文檔
你必須做的是調用.append()
,然后調用幾次.attr(attr_name, attr_value)
來設置每個屬性的值。 D3不像jQuery那樣工作。
D3不提供此功能,並且它沒有多大意義(當您考慮基於數據操作元素時)。
但是,作為旁注,您可以實現自己的函數來附加文字SVG元素。
這是由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));
});
};
擴展原型后,您可以使用它:
selection.appendSVG("<some literal SVG element>");
這是一個演示。 首先,我們設置數據:
var data = [{x:30,y:50},{x:420,y:100},{x:160,y:150},{x:260,y:30}];
然后,我們以通常的方式附加我們的文字SVG元素:
var myLiteral = svg.selectAll(".literal")
.data(data)
.enter()
.appendSVG("<literal SVG here>");
最后我們使用translate
設置位置:
.attr("transform", function(d){
return "translate(" + d.x + "," + d.y + ")";
});
檢查代碼段:
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.