2013-06-27 86 views
1

我想弄清楚如何使由d3筆刷(特別是事件矩形)創建的矩形響應單擊事件。最後,我想單擊這個對象來調出一個菜單,但我似乎無法得到rect元素來捕捉事件。將事件偵聽器添加到d3筆刷

我試過下面的代碼:

var selector = d3.svg.brush(); 

var x = d3.scale.linear() 
    .range([0,500]) 
    .domain([0,500]); 

var y = d3.scale.linear() 
    .range([0,500]) 
    .domain([0,500]); 

d3.select('#myDiv') 
    .append('svg') 
    .attr('id','mySVG') 
    .attr('height',500) 
    .attr('width',500) 
    .call(selector.x(x).y(y).on('brushend',bindSelect)) 

function bindSelect(){ 
    d3.select('#mySVG rect.extent') 
     .on('click',function(){alert('hi mom!')}) 
} 

bindSelect似乎火得很好,且成功地選擇.extent矩形,但我沒有收到上單擊矩形任何迴應。

問題似乎是,當矩形被點擊時,d3觸發​​事件,我猜測停止事件傳播的地方?

有誰知道如何解決這個問題?我唯一的想法是在​​事件的擴展區域之上創建另一個矩形,然後使用該矩形處理點擊行爲,但這似乎是一種凌亂的做事方式。

此外,here is a fiddle of the code.

回答

3

得到你想要的可能是一個有點毛茸茸的,需要更改D3源代碼的事件。但是,您可以使用​​事件以及爲畫筆提供的方法來確定是否有人點擊了畫筆矩形。

var extent = selector.extent(); 

function bindSelect(){ 
    if(!selector.empty() && !(extent < selector.extent() || extent > selector.extent())) { 
    console.log("foo"); 
    } 
    extent = selector.extent(); 
} 

的想法是,如果選擇不爲空並且所選擇的程度,因爲它是在最後​​事件相同,則用戶點擊選擇代替操縱它的。

+0

這裏需要注意的兩件事: 1.如果拖動畫筆並將其返回到原來的確切位置,則會觸發該事件。 2.如果將畫筆拖過容器的末端,畫筆將不會在光標移動的同時移動,同時也會觸發事件。 –

0

這是拉斯的回答略有改進版,處理兩個邊緣情況:

  1. 如果拖動刷並將它返回到它的確切原來的位置,這將觸發事件。
  2. 如果將畫筆拖過容器的末端,畫筆將不會在光標移動的同時移動,同時也會觸發事件。

首先,設置你的畫筆是這樣的:

selector.x(x).y(y).on('brushstart', saveCursorPos) 
        .on('brushend', checkIfMoved)) 

然後,

var clickPos = [-1,-1]; 

function saveCursorPos() { 
    var e = d3.event.sourceEvent; 
    clickPos = [e.clientX,e.clientY]; 
} 

function checkIfMoved() { 
    var e = d3.event.sourceEvent; 
    if(!selector.empty() && clickPos[0] === e.clientX && clickPos[1] === e.clientY) { 
     alert("foo"); 
    } 
} 

的想法是保存鼠標的位置,而不是刷的程度,當你開始拖動,並檢查按鈕釋放時是否更改。

相關問題