如何使用D3/JavaScript降低拖拽绘制点的频率?
解决D3.js拖拽绘制点速率过高的问题
要降低mousemove事件中绘制点的频率,核心思路是限制绘制动作的触发次数,常见的两种实现方式如下:
方式一:时间间隔节流
通过记录上次绘制的时间,仅当当前时间与上次绘制时间的间隔达到设定阈值时,才执行绘制操作。比如要降到原速率的1/10,可设置间隔为100ms(mousemove通常每秒触发约100次左右)。
修改后的代码如下:
// 定义变量记录上次绘制时间 let lastDrawTime = 0; svg.on("mousedown", mousedown) .on("mouseup", mouseup); function mousedown() { // 鼠标按下时立即绘制点,并重置时间 const new_x = xScale.invert(d3.pointer(event)[0]); const new_y = yScale.invert(d3.pointer(event)[1]); svg.append("circle") .data([{x: new_x, y: new_y}]) .attr("cx", d => xScale(d.x)) .attr("cy", d => yScale(d.y)) .attr("r", "3"); lastDrawTime = Date.now(); svg.on("mousemove", mousemove); } function mousemove() { const now = Date.now(); // 100ms间隔对应原速率的1/10,改成50ms就是1/5速率 if (now - lastDrawTime < 100) return; const new_x = xScale.invert(d3.pointer(event)[0]); const new_y = yScale.invert(d3.pointer(event)[1]); svg.append("circle") .data([{x: new_x, y: new_y}]) .attr("cx", d => xScale(d.x)) .attr("cy", d => yScale(d.y)) .attr("r", "3"); lastDrawTime = now; } function mouseup() { svg.on("mousemove", null); }
方式二:计数节流
通过计数器记录mousemove触发次数,仅当计数器达到指定倍数时才绘制点,之后重置计数器。比如要降到原速率的1/10,就每10次触发绘制一次。
修改后的代码如下:
// 定义变量记录触发次数 let moveCounter = 0; svg.on("mousedown", mousedown) .on("mouseup", mouseup); function mousedown() { const new_x = xScale.invert(d3.pointer(event)[0]); const new_y = yScale.invert(d3.pointer(event)[1]); svg.append("circle") .data([{x: new_x, y: new_y}]) .attr("cx", d => xScale(d.x)) .attr("cy", d => yScale(d.y)) .attr("r", "3"); moveCounter = 0; svg.on("mousemove", mousemove); } function mousemove() { moveCounter++; // 每10次触发绘制一次,改成5就是1/5速率 if (moveCounter % 10 !== 0) return; const new_x = xScale.invert(d3.pointer(event)[0]); const new_y = yScale.invert(d3.pointer(event)[1]); svg.append("circle") .data([{x: new_x, y: new_y}]) .attr("cx", d => xScale(d.x)) .attr("cy", d => yScale(d.y)) .attr("r", "3"); } function mouseup() { svg.on("mousemove", null); }
说明:两种方式各有优劣——时间间隔节流能保证绘制的均匀性,不受mousemove触发频率波动影响;计数节流则严格按照原触发次数的比例降低频率,适合对比例精度要求高的场景。
内容的提问来源于stack exchange,提问作者jtr13
相关产品推荐
相关产品推荐

