簡體   English   中英

將事件偵聽器添加到d3畫筆

[英]Adding an event listener to a d3 brush

我試圖弄清楚如何制作由d3畫筆創建的矩形(特別是事件矩形),響應點擊事件。 最后,我想在這個對象上單擊一下菜單,但我似乎無法獲取rect元素來捕獲事件。

我試過以下代碼:

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會觸發brushend事件,我猜這會阻止事件在某處傳播?

有誰知道怎么解決這個問題? 我唯一的想法是在brushend事件上的extents rect上創建另一個rect,然后使用那個來處理點擊行為,但這似乎是一種混亂的做事方式。

此外, 這里是代碼的小提琴。

獲得您想要的活動可能有點毛茸茸,需要更改D3源代碼。 但是,您可以將brushend事件與為畫筆提供的方法一起使用,以確定是否有人單擊了畫筆矩形。

var extent = selector.extent();

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

我們的想法是,如果選擇不為空且所選范圍與上次brushend事件相同,則用戶單擊選擇而不是操縱它。

這是Lars答案的略微改進版本,用於處理兩個邊緣情況:

  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");
    }
}

當您開始拖動時,想法是保存鼠標位置而不是畫筆范圍,並在釋放按鈕時檢查是否已更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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