2013-01-20 19 views
68

Vì vậy, tôi có mã graph lực lượng bố trí tiếp theo để thiết lập các nút, liên kết và các yếu tố khác:Làm cách nào để xóa tất cả các phần tử con khỏi nút và sau đó áp dụng lại chúng với màu sắc và kích thước khác nhau?

var setLinks = function() 
{ 
    link = visualRoot.selectAll("line.link") 
     .data(graphData.links) 
     .enter().append("svg:line") 
     .attr("class", "link") 
     .style("stroke-width", function (d) { return nodeStrokeColorDefault; }) 
     .style("stroke", function (d) { return fill(d); }) 
     .attr("x1", function (d) { return d.source.x; }) 
     .attr("y1", function (d) { return d.source.y; }) 
     .attr("x2", function (d) { return d.target.x; }) 
     .attr("y2", function (d) { return d.target.y; }); 

    graphData.links.forEach(function (d) 
    { 
     linkedByIndex[d.source.index + "," + d.target.index] = 1; 
    }); 
}; 


var setNodes = function() 
{ 
    node = visualRoot.selectAll(".node") 
     .data(graphData.nodes) 
     .enter().append("g") 
     .attr("id", function (d) { return d.id; }) 
     .attr("title", function (d) { return d.name; }) 
     .attr("class", "node") 
     .on("click", function (d, i) { loadAdditionalData(d.userID, this); }) 
     .call(force.drag) 
     .on("mouseover", fadeNode(.1)).on("mouseout", fadeNode(1)); 
}; 

//append the visual element to the node 
var appendVisualElementsToNodes = function() 
{ 
    node.append("circle") 
     .attr("id", function (d) { return "circleid_" + d.id; }) 
     .attr("class", "circle") 
     .attr("cx", function (d) { return 0; }) 
     .attr("cy", function (d) { return 0; }) 
     .attr("r", function (d) { return getNodeSize(d); }) 
     .style("fill", function (d) { return getNodeColor(d); }) 
     .style("stroke", function (d) { return nodeStrokeColorDefault; }) 
     .style("stroke-width", function (d) { return nodeStrokeWidthDefault; }); 

    //context menu: 
    d3.selectAll(".circle").on("contextmenu", function (data, index) 
    { 
     d3.select('#my_custom_menu') 
      .style('position', 'absolute') 
      .style('left', d3.event.dx + "px") 
      .style('top', d3.event.dy + "px") 
      .style('display', 'block'); 

     d3.event.preventDefault(); 
    }); 
    //d3.select("svg").node().oncontextmenu = function(){return false;}; 

    node.append("image") 
     .attr("class", "image") 
     .attr("xlink:href", function (d) { return d.profile_image_url; })//"Images/twitterimage_2.png" 
     .attr("x", -12) 
     .attr("y", -12) 
     .attr("width", 24) 
     .attr("height", 24); 

    node.append("svg:title") 
     .text(function (d) { return d.name + "\n" + d.description; }); 
}; 

Bây giờ, màu sắc và phụ thuộc kích thước thay đổi và tôi cần phải vẽ lại các vòng tròn đồ thị (+ tất cả các yếu tố nối) với màu sắc và bán kính khác nhau. Có vấn đề với nó.

tôi có thể làm điều này:

visualRoot.selectAll(".circle").remove(); 

nhưng tôi có tất cả những hình ảnh mà tôi gắn liền với '.circles' vẫn còn đó.

Trong mọi trường hợp, mọi trợ giúp sẽ được đánh giá cao, hãy cho tôi biết nếu giải thích không đủ rõ ràng, tôi sẽ cố gắng khắc phục.

P.S. sự khác nhau giữa graphData.nodesd3.selectAll('.nodes') là gì?

Trả lời

90

câu trả lời của bạn sẽ làm việc, nhưng đối với hậu thế, những phương pháp mang tính tổng quát hơn.

Remove tất cả trẻ em từ HTML:

d3.select("div.parent").html(""); 

Hủy bỏ tất cả trẻ em từ SVG/HTML:

d3.select("g.parent").selectAll("*").remove(); 

Cuộc gọi .html("") làm việc với SVG của tôi, nhưng nó có thể là một tác dụng phụ của việc sử dụng innerSVG .

+2

Thật không may .html ("") không hoạt động trong Safari. Hoạt động tốt trong tất cả các trình duyệt khác. – glyph

+1

@glyph: xem http://stackoverflow.com/a/43661877/1587329 để biết cách chính thức để thực hiện việc này –

6

lời khuyên đầu tiên của tôi là bạn nên đọc d3.js API về các lựa chọn: https://github.com/mbostock/d3/wiki/Selections

Bạn phải hiểu như thế nào enter() công trình lệnh (API). Thực tế là bạn phải sử dụng nó để xử lý các nút mới có ý nghĩa sẽ giúp bạn.

Dưới đây là quá trình cơ bản khi bạn đối phó với selection.data():

  • đầu tiên bạn muốn "đính kèm" một số dữ liệu để lựa chọn. Vì vậy, bạn có:

    var nodes = visualRoot.selectAll(".node") 
        .data(graphData.nodes) 
    
  • Sau đó, bạn có thể sửa đổi tất cả các nút mỗi lần dữ liệu được thay đổi (điều này sẽ làm chính xác những gì bạn muốn). Nếu ví dụ bạn thay đổi bán kính của các nút cũ, đều trong cùng tập dữ liệu mới, bạn nạp

    nodes.attr("r", function(d){return d.radius}) 
    
  • Sau đó, bạn phải xử lý các nút mới, cho điều này, bạn phải chọn các nút mới, đây là selection.enter() là gì thực hiện cho:

    var nodesEnter = nodes.enter() 
        .attr("fill", "red") 
        .attr("r", function(d){return d.radius}) 
    
  • Cuối cùng, bạn chắc chắn muốn loại bỏ các nút bạn không muốn dùng nữa, để làm điều này, bạn phải chọn chúng, đây là những gì selection.exit() được thực hiện cho.

    var nodesRemove = nodes.exit().remove() 
    

Một ví dụ điển hình của toàn bộ quá trình cũng có thể được tìm thấy trên wiki API: https://github.com/mbostock/d3/wiki/Selections#wiki-exit

+0

HI Chris, cảm ơn các đề xuất và điểm. Thực tế là, tôi không có dữ liệu mới .. Dữ liệu vẫn như cũ. Tất cả mọi thứ là như nhau. Tôi không muốn làm lại toàn bộ quá trình. Theo tôi hiểu (hãy sửa cho tôi nếu tôi sai). Tất cả tôi phải làm là để – HotFrost

+0

tất cả tôi phải làm là để tìm các yếu tố dom với '. Vòng tròn' lớp và con cái của họ. Loại bỏ chúng. Tìm các phần tử svg với lớp '.node' và áp dụng lại quy trình 'đính kèm' cho vòng tròn svg và các hình ảnh khác được mô tả trong hàm 'applyvisualelements', nhưng lần này khi bán kính sẽ được tính toán, nó sẽ được tính toán khác nhau. – HotFrost

+0

theo bất kỳ cách nào, tôi đã giải quyết nó rất dễ dàng, visualRoot.selectAll (". Circle"). Remove(); visualRoot.selectAll (". Image"). Remove(); – HotFrost

6

theo cách này, tôi đã giải quyết nó rất dễ dàng,

visualRoot.selectAll(".circle").remove(); 
visualRoot.selectAll(".image").remove(); 

và sau đó tôi chỉ thêm lại các yếu tố trực quan được hiển thị khác nhau vì mã để tính bán kính và màu sắc đã thay đổi các thuộc tính. Cảm ơn bạn.

3

Để loại bỏ tất cả các phần tử từ một nút:

var siblings = element.parentNode.childNodes; 
for (var i = 0; i < siblings.length; i++) { 
    for (var j = 0; j < siblings.length; j++) { 
     siblings[i].parentElement.removeChild(siblings[j]); 
    } 
}` 
+0

Bạn đường may để trích dẫn một cái gì đó, nguồn là gì? –

+0

Bạn có thực sự cần phải loại bỏ tất cả các nút đó khỏi các nút riêng của chúng. Chắc chắn phương pháp được đề xuất DOM sẽ đủ như các nút sẽ không được ra khỏi nút hiện tại không cần phải được tách ra quá. – Tatarize

+0

var element = document.getElementById ("trên cùng"); trong khi (element.firstChild) { element.removeChild (element.firstChild); } – Tatarize

3

Nếu bạn muốn xóa chính phần tử, chỉ cần sử dụng element.remove(), như bạn đã làm. Trong trường hợp bạn chỉ muốn xóa nội dung của phần tử, nhưng giữ nguyên tố, bạn có thể sử dụng f.ex.

visualRoot.selectAll(".circle").html(null); 
visualRoot.selectAll(".image").html(null); 

thay vì .html("") (Tôi không chắc chắn trẻ em của phần tử nào bạn muốn xóa). Điều này giữ nguyên tố, nhưng xóa tất cả nội dung được bao gồm. Nó the official way to do this, vì vậy nên làm việc qua trình duyệt.

PS: bạn muốn thay đổi kích thước vòng tròn. Bạn đã thử

d3.selectAll(".circle").attr("r", newValue); 
Các vấn đề liên quan