javascript – 辅助功能:d3笔刷/缩放可以获得焦点并通过键盘控制

有关如何使用键盘控制d3画笔/缩放的任何提示
1.能够专注于画笔控制
2.能够使用键盘更改画笔区域

是否支持开箱即用?

更新:显然没有开箱即用的解决方案(希望d3会在某个时候提供它).这意味着自定义解决方案将取决于可视化/方案.发布实际的用户体验和要求,并为此特定案例提供解决方案.

为了满足可访问性要求,任务是修改下面的图表控件,以便能够使用键盘进行缩放/刷新.这包括:1)能够设置焦点; 2)能够使用左右箭头键进行控制.

解决方法

我打算用这个 bl.ock作为参考.我相信它是你形象的源泉.

缩放和画笔功能比较

我们感兴趣的是这个块中的几个东西,缩放代码和刷牙代码

function brushed() {
  if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return; // ignore brush-by-zoom
  var s = d3.event.selection || x2.range();
  x.domain(s.map(x2.invert,x2));
  focus.select(".area").attr("d",area);
  focus.select(".axis--x").call(xAxis);
  svg.select(".zoom").call(zoom.transform,d3.zoomIdentity
      .scale(width / (s[1] - s[0]))
      .translate(-s[0],0));
}

function zoomed() {
  if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush
  var t = d3.event.transform;
  x.domain(t.rescaleX(x2).domain());
  focus.select(".area").attr("d",area);
  focus.select(".axis--x").call(xAxis);
  context.select(".brush").call(brush.move,x.range().map(t.invertX,t));

这两个功能

>检查是否应该执行函数的主体
>设置一个新的x比例域
>更新区域和轴

差异很重要:

刷子功能使用d3.zoomIdentity更新比例,它必须这样做,因为它需要更新缩放功能以反映当前缩放比例和变换.

缩放功能手动设置画笔,因为画笔需要更新.

放大并刷“没有事件”

要通过键盘控制它,可能更容易使用brushed()函数作为模板.这是因为当前缩放变换可能难以检索,而相对容易欺骗画笔中的变化.

在brushed函数中,d3.event.selection中的值是一个数组,包含画笔包含的值范围(范围中的值,而不是域).它是由画笔覆盖的参考/上下文比例x2中的最小和最大范围值的数组.这是我们唯一需要更新缩放和画笔的东西.

要放大,我们可以获取焦点x比例的域并找到域的最小值和最大值.然后我们可以重新设置焦点x比例的域稍微小一点,有效地放大.下面的代码将域转换为范围,并在将其转换回域之前缩小范围 – 这是不必要的,但更紧密地遵循brushed()函数并且意味着不必处理日期.

var xMin = x2(x.domain()[0]);
var xMax = x2(x.domain()[1]);

var currentDifference = Math.abs(xMin-xMax);

xMin += currentDifference / 2 / 3   // increase the minimum value of the domain
xMax -= currentDifference / 2 / 3   // decrease the maximum value of the domain
x.domain([xMin,xMax].map(x2.invert,x2));

我们也可以这样设置缩放比例:

var identity = d3.zoomIdentity
  .scale(width/ (xMax - xMin))

我们还想修改缩放的变换,以便我们放大到前一个更大域的中心.以下只是示例块中使用的代码的再现,但为了说明,名称更清晰:

var identity = d3.zoomIdentity
  .scale(width/ (xMax - xMin))
  .translate(-xMin,0);

如果我们使用brushed函数作为模板,我们最终可能会:

var xMin = x2(x.domain()[0]); // minimum value in x range currently
var xMax = x2(x.domain()[1]); // maximum value in x range currently

var currentDifference = Math.abs(xMax-xMin); // center point of range

xMin += currentDifference / 2 / 3  // reduce the distance between center point and end points
xMax -= currentDifference / 2 / 3

x.domain([xMin,x2));  // convert the range to a domain
focus.select(".area").attr("d",area); // redraw the chart
focus.select(".axis--x").call(xAxis);  // redraw the axis

var identity = d3.zoomIdentity
  .scale(width/ (xMax - xMin))
          .translate(-xMin,0);          // update the zoom factor

context.select(".brush").call(brush.move,x.range().map(identity.invertX,identity)); // update the brush
svg.select(".zoom").call(zoom.transform,identity); // apply the zoom factor

这会将焦点区域缩放到以当前域中心为中心的区域.使用上面的代码,域将缩小三分之一,但可以根据您的需要进行更改.

与原始拉丝功能相比,唯一真正的区别是我们:

>手动计算画笔范围
>使用缩放功能中使用的方法更新画笔.

这就对了.

其他行动

您可以通过展开而不缩小域来缩小,只需在定义新终点时切换符号:

xMin -= currentDifference / 2 / 3  
xMax += currentDifference / 2 / 3

向左移动看起来像:

xMin -= currentDifference / 2 / 3  
xMax -= currentDifference / 2 / 3

而自然地向右移动将是相反的.

添加键盘

现在你所要做的就是设置一个监听器来监听击键:

d3.select("body")
  .on("keypress",function() {
    if (d3.event.key == "a") {
      // one of zoom in/out/pan
    }
    else if (d3.event.key == "b" {
      //...
    }
});

全部放在一起

我已经组装了一个显示所有内容的块,我使用asdw作为关键输入:

> a:潘左
> d:向右平移
> w:放大
> s:缩小.

最后一点:我已经包含了一项检查,以确保新域位于边界内:我们不想缩放超出数据域的范围.

Here’s的例子.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...