鼠标缩放不适用于 dc.js 折线图

Mouse Zooming not Working for dc.js Line Chart

我正在为 dc.js library. I've been closely following the annotated source 创建一个 Angular 包装器以使一些示例起作用,并且我在饼图和行图方面取得了一些成功。我能够使折线图正常工作,并且我可以使用画笔 select 区域。但是,我无法缩放。我禁用了画笔并启用了鼠标缩放。

当我将鼠标悬停在图表上并移动滚轮时,页面上的其他图表会做出反应,因此过滤器 正在 生效。当我 select 一片馅饼时,它确实过滤了图表:

在文档中我注意到有一个 zoomed 事件。我在带注释的源代码中没有看到 .on('zoomed', ...) 的任何用法,但结果 line chart 非常清楚(干净利落地)支持缩放。我不确定是否需要实现一个侦听器来重新定义缩放时域可缩放图表的域。如果是这样,我不确定如何获得该新域的最低值和最大值。

编辑: Gordon Woodhull 已声明(在评论中)缩放功能源自 d3-zoom,因此无需监听 zoomed 事件并重新计算域。

还可以了解如何在我的包装器中创建图表。图表组件包含一个 <div>,它提供给 dc.js 以在其中放置图表。图表组件将 ChartSettings 模型作为输入,以在呈现图表之前配置图表。因此,显示图表的组件将执行以下操作:

<dc-chart [settings]="priceChart"></dc-chart>

图表组件本身使用设置(指定类型)来确定要实例化的正确 dc.js 图表对象。然后该组件使用实现交叉过滤器的服务来检索所需域和范围(在给定设置中指定)的维度和组。使用设置和服务的响应,组件配置图表:

let applicableMixins = {
  baseMixin: true, // The base mixin applies to all dc.js charts
  colorMixin: true, // The color mixin applies to all dc.js charts
  coordinateGridMixin: ["bar", "line", "bubble"].indexOf(cS.type) >= 0,
  marginMixin: ["row", "bar", "line", "bubble"].indexOf(cS.type) >= 0,
  // TODO: bubbleMixin
  // TODO: capMixin
  // TODO: stackMixin
}

let c = this.chart;
// Note: All chart settings are assigned default values in chart-settings.model, so there's no
// need to set default values here. All properties in a ChartSettings object are defined.
// Base Mixin
c.height( cS.height ); // fills parent when null
c.width( cS.width );
c.dimension(this.latestReceipt.dimension);
c.group(this.latestReceipt.group);

// Color Mixin
c.colors(d3.scaleOrdinal(d3.schemeCategory10));

// Coordinate Grid Mixin
if(applicableMixins.coordinateGridMixin) {
  c.brushOn(false);
  c.elasticX(cS.elasticX);
  c.x(cS.xScale); // d3.scaleTime().domain([new Date(1985, 1, 1), new Date(1986, 4, 1)])
  c.round(d3.timeMonth.round); // from example
  c.xUnits(d3.timeMonths); // from example
  c.renderArea(cS.renderArea); // true
  c.mouseZoomable(true);

  // Override for example.
  c.width(990);
  c.height(200);

  c.elasticY(cS.elasticY); // true
  c.renderHorizontalGridLines(true);
  c.renderVerticalGridLines(false);
  c.zoomScale([0, 100]);
  c.zoomOutRestrict(false);
  c.margins({
    top: 30, right: 50, bottom: 25, left: 40
  });
}

为了尝试进行缩放,我尽可能地模仿了带注释的来源。我使用的是模拟股票价值的生成数据,该数据比 dc.js 主页示例中使用的数据更详细。

[
    {
        "open": 110.47,
        "high": 115.16,
        "low": 104.79,
        "close": 117.0982,
        "date": "01/01/1985",
        "quarter": 1,
        "isGain": true,
        "dayOfWeek": "Tue"
    },
    {
        "open": "117.10",
        "high": 120.58,
        "low": 117.03,
        "close": 124.126,
        "date": "01/02/1985",
        "quarter": 1,
        "isGain": true,
        "dayOfWeek": "Wed"
    },
    {
        "open": "124.13",
        "high": 128.31,
        "low": 116.28,
        "close": 119.16479999999999,
        "date": "01/03/1985",
        "quarter": 1,
        "isGain": false,
        "dayOfWeek": "Thu"
    },
    ...
    {
        "date": "04/01/1986",
        ...
    }
]

经过一番折腾,我们发现问题很简单,就是 elasticXmouseZoomable 不兼容,因为它将 x 比例域永久锁定在数据。

为了允许 mouseZoomable(true),您需要确保 elasticX 为假。

当然,这也意味着您需要自己计算 X 比例域,这有点烦人。如果两个选项都设置了,也许 dc.js 应该只 "elast" X 域一次(在渲染时)。那会很方便,而且可能是预期的。