簡體   English   中英

我可以用d3附加一個文字SVG元素嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM