2012-07-31 8 views
13

Tôi đang làm việc với bố cục hướng lực d3 với nhãn nút HTML được triển khai với các phần tử SVG foreignObject. Tôi muốn chọn các phần tử này vào các thời điểm khác nhau để cập nhật vị trí và các thuộc tính khác (và theo dõi chúng khi chúng được tạo và định vị với enter()exit()), nhưng dường như tôi không thể chọn chúng như các phần tử SVG khác .Không thể chọn phần tử SVG foreignObject trong d3

Dưới đây là một ví dụ nhỏ gọn:

HTML:

<html> 
    <head> 
     <title>Cannot Select SVG Foreign Object</title> 
     <script src="http://d3js.org/d3.v2.js"></script> 
     <script src = "fo_select.js"></script> 
    </head> 
    <body> 
     <svg id="example_svg" width="600" height="600"> 
       <g> 
        <circle r="40" cx = "80" cy="80"></circle> 
        <foreignObject width = "100" height = "100" x = "200" y="200"> 
         <body>Hello, world</body> 
        </foreignObject> 
       </g> 
     </svg> 
     <script>run()</script> 
    </body> 
</html> 

Javascript:

function run() { 
    svg = d3.select("#example_svg"); 
    console.log(svg.selectAll("circle")); 
    console.log(svg.selectAll("foreignObject")); 
} 

Đây cũng là tại http://bl.ocks.org/3217448. Đầu ra của bàn điều khiển là:

[Array[1]] 
[Array[0]] 

trong đó mảng đầu tiên chứa phần tử circle trong khi ô thứ nhất chứa phần tử thứ hai trống. Tại sao đối tượng circle có thể chọn, nhưng foreignObject thì không? Tôi cho rằng nó phải liên quan đến bản chất bất thường của foreignObject. Làm cách nào để chọn nó để thao tác nó trong mã của tôi? Cảm ơn rất nhiều.

+0

(Đã cập nhật để xóa thêm dấu phẩy) –

Trả lời

19

Nói đúng, SVG phân biệt chữ hoa chữ thường nên bạn nên sử dụng <foreignObject> thay vì <foreignobject>.

Điều quan trọng hơn là, có một mở bug in WebKit ngăn các phần tử camelCase được chọn.

Một workaround có thể là sử dụng:

.selectAll(function() { return this.getElementsByTagName("foreignObject"); }) 

(Điều này có thể không hoạt động trong các phiên bản WebKit cũ mặc dù, thấy bây giờ đóng WebKit bug 46800.)

Ngoài ra, bạn có thể sử dụng các lớp CSS hoặc ID và chọn các yếu tố của bạn theo cách đó. Tôi muốn giới thiệu phương pháp này vào lúc này nếu có thể, được đưa ra bởi các lỗi khác nhau nói trên.

+2

Cảm ơn rất nhiều - biết rằng đó là lỗi khiến tôi cảm thấy tốt hơn. :-) Tôi sẽ chỉ sử dụng lựa chọn lớp làm cách giải quyết. –

+0

Tôi nhận được lỗi "Uncaught SyntaxError: Không thực hiện được truy vấn: '[object NodeList]' không phải là bộ chọn hợp lệ." khi sử dụng d3.selectAll (document.getElementsByTagName ("foreignObject")). Nhưng lựa chọn theo tên lớp hoạt động hoàn hảo. Cảm ơn. Nó vẫn có vẻ là một lỗi trong Chrome 31. –

+0

Thực ra, đã có một lỗi trong giải pháp được đề xuất của tôi. Tôi đã cập nhật nó để sử dụng một hàm được gọi cho mọi phần tử của vùng chọn. Đề nghị ban đầu của tôi chỉ làm việc cho d3.selectAll, chứ không phải selection.selectAll. –

-2

Bạn sẽ có thể d3.selectAll ("foreignObject") hoặc svg.selectAll ("foreignObject"). Nó có thể là dấu phẩy thừa trong thuộc tính externalObject của bạn (giữa x và y). Tôi đã chỉ chèn các phần tử externalObject sử dụng D3, vì vậy có lẽ có điều gì đó về việc nhúng chúng như thế này thì khác.