2014-04-08 14 views
38

Tôi có một biểu đồ histogram D3, lên mà tôi đã gắn một 'onclick' sự kiện để các thanh:Gắn 'onclick' sự kiện để D3 nền biểu đồ

... 
var bar = svg.selectAll(".bar") 
     .data(data) 
     .enter().append("g") 
     .attr("class", "bar") 
     .attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; }) 
     .on('mouseover', tip.show) 
     .on('mouseout', tip.hide) 
     .on('click', function(d,i){ //do stuff }); 
... 

này hoạt động chính xác như mong đợi. Tôi cũng muốn đính kèm một sự kiện 'onclick' vào nền của biểu đồ (nghĩa là ở mọi nơi trong biểu đồ không phải là một thanh), nhưng tôi đang gặp vấn đề với điều này. Tôi đã cố gắng gắn sự kiện này trong một vài cách khác nhau, nhưng trong mọi trường hợp, sự kiện mới này dường như để ghi đè lên tôi thanh-click:

Một số nỗ lực:

$("svg:not('.bar')").on("click", function(){ //do stuff }); 

$("g:not('.bar')").on("click", function(){ //do stuff }); 

var svg = d3.select("#histogram_block").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom) 
     .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
     .on("click", function(d,i){ 
      if (d) { //do stuff} 
      else { //do stuff } 
     }; 

Tôi giả sử có một cách để thêm xử lý sự kiện đối tượng SVG khi nó được khởi tạo, nhưng tôi không biết cách chính xác để làm điều này.

+2

Chỉ cần nhắc nhở. '$ (" svg: not ('. bar') ")' có nghĩa là nhận được tất cả 'svg' không có lớp 'bar'. Nó không có nghĩa là lấy phần 'svg' bên ngoài các phần tử với lớp 'bar'. –

Trả lời

46

Sự kiện không thực sự bị ghi đè, nhưng cả hai đều được kích hoạt - trình xử lý onclick cho SVG và cho thanh. Để ngăn chặn điều này, hãy sử dụng phương thức .stopPropagation() (xem the documentation). Mã trông giống như sau:

rect.on("click", function() { 
    console.log("rect"); 
    d3.event.stopPropagation(); 
}); 

Ví dụ hoàn chỉnh here. So sánh với hành vi dừng việc tuyên truyền sự kiện here.

+0

Ví dụ tuyệt vời, cảm ơn. Bạn nên thêm nó vào câu trả lời vì nó quá ngắn. Vậy điều gì quyết định thứ tự của các sự kiện khi tôi nhấp? Giả định ở đây có vẻ là sự kiện nhấp chuột của hình chữ nhật kích hoạt trước, nhưng điều đó luôn luôn xảy ra? – woemler

+0

Sự kiện "bong bóng" DOM. 'Rect' là một con của' svg', vì vậy nó truyền sự kiện đến 'svg'. Đây là lý do tại sao '.stopPropagation()' hoạt động. Vì vậy, có, trình xử lý nhấp chuột 'rect's phải luôn kích hoạt trước. –

+0

Cảm ơn, nhưng điều gì sẽ xảy ra nếu có yếu tố biểu đồ chồng chéo, cả trẻ em của SVG? Điều gì sẽ kích hoạt sự kiện nhấp đầu tiên của họ? – woemler

2

Trong ví dụ này (dòng 246: http://tributary.io/inlet/8361294) Tôi nối một đường thẳng mới với chiều rộng & chiều cao bằng tổng diện tích biểu đồ, sau đó đính kèm các sự kiện chuột (hoặc nhấp).

svg.append("rect") 
     .attr({"class": "overlay" , "width": width , "height": height}) 
     .on({ 
      "mouseover": function() { /* do stuff */ }, 
      "mouseout": function() { /* do stuff */ }, 
      "click": function() { /* do stuff */ }, 
     }); 
+0

Điều này dường như không trả lời câu hỏi, vì điều này không nhấp vào nền của biểu đồ so với phần tử tiền cảnh. – rjurney

Các vấn đề liên quan