You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅按住B键时启用D3 Brush,默认使用D3 Zoom?

解决D3中B键切换Zoom和Brush功能的问题

问题根源

brush和zoom的filter函数接收的是鼠标事件对象,而非键盘事件对象。鼠标事件对象仅包含修饰键(Shift/Ctrl/Alt等)的状态属性(如shiftKey),但不会携带普通按键(如B)的keyCode或code信息。这就是为什么Shift键的方案可行,而直接判断B键的keyCode无效的原因。

解决方案

通过单独监听键盘事件维护B键的按压状态,再在brush和zoom的filter中检查该状态:

1. 定义状态变量

let isBKeyPressed = false;

2. 监听键盘事件

在全局(document)上监听keydown和keyup事件,更新B键状态:

document.addEventListener('keydown', (event) => {
  if ((event.key === 'b' || event.key === 'B') && !isBKeyPressed) {
    isBKeyPressed = true;
    event.preventDefault(); // 阻止B键输入字符的默认行为
  }
});

document.addEventListener('keyup', (event) => {
  if (event.key === 'b' || event.key === 'B') {
    isBKeyPressed = false;
  }
});

3. 修改Brush和Zoom的Filter函数

// Brush配置:仅当B键按下时启用
var time_brush = d3.brushX()
  .filter(() => isBKeyPressed)
  .keyModifiers(false)
  .extent([[0, 0],[time_line_chart_params.w, time_line_chart_params.h]])  
  .on("end", setTimeRange);

// Zoom配置:仅当B键未按下时启用
var zoom = d3.zoom()
  .scaleExtent([1,2])
  .extent([[0, 0], [w, h]])
  .translateExtent([[0, 0], [w, h]])
  .filter(() => !isBKeyPressed)
  .on("zoom", updateChart);

关键说明

  • Shift键的shiftKey是鼠标事件对象的原生属性,按住Shift触发鼠标事件时该属性会自动设为true,因此原方案可行。
  • 普通按键的状态不会被包含在鼠标事件对象中,必须通过独立的键盘事件监听来维护状态,再在filter函数中判断该状态。

内容的提问来源于stack exchange,提问作者Ameya Patil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:07:45