【问题标题】:understanding dc.js charts interactivity better with fiddle example使用小提琴示例更好地理解 dc.js 图表交互性
【发布时间】:2017-01-22 22:57:12
【问题描述】:

这是我的示例fiddle

这是 2 个基本图表 dc.js 图表。我想了解的是图表如何相互作用。例如:

如果我在行图(右侧图表)上选择Aziz,则此图表中的其他值将显示为灰色,并且在环形图表(左侧图表)中2012 会填满整个环形图表。然后,如果我再次选择Aziz,两个图表都会重置。

如果我在环形图(左侧图表)上选择2012,则此图表中的其他值显示为灰色,而在行图中(右侧图表)Aziz 是行图中显示的唯一值(右图)。然后,如果我再次选择2012,两个图表都会重置。

基本上这种交互是如何运作的?

传递给这些图表的四个变量是 yearDim spendDim spendPerYear spendPerName 但这里唯一的共同点是 xfilter 也许就是这样,但这并不能完全解释它。谁能建议帮助我更好地理解这一点?

var xfilter = crossfilter(data1),
    yearDim  = xfilter.dimension(function(d) {return +d.Year;}),
    spendDim = xfilter.dimension(function(d) {return Math.floor(d.Spent/10);}),
    nameDim  = xfilter.dimension(function(d) {return d.Name;}),

    spendPerYear = yearDim.group().reduceSum(function(d) {return +d.Spent;}),
    spendPerName = nameDim.group().reduceSum(function(d) {return +d.Spent;});
function render_plots(){
    yearRingChart
        .width(200).height(200)
        .dimension(yearDim)
        .group(spendPerYear)
        .innerRadius(50);
    spenderRowChart
        .width(250).height(200)
        .dimension(nameDim)
        .group(spendPerName)
        .elasticX(true);
    dc.renderAll();
}

注意 herehere 可能相关,它在图表交互性上或未链接。
答案中的好图表示例here


编辑1

看到这个fiddle

如果我将这条线 .group(spendPerName) 更改为 .group(spendPerYear),则使用第二个图表,我现在将在两个图表上按相同的分组进行分组。这会改变图表的交互性。

现在我可以在行图上选择 2012 年,它将突出显示。我可以将其从突出显示切换为未突出显示。但是当它被突出显示并且我在行图中选择另一年时,它们都会崩溃(消失)。一直以来,环形图上什么都没有发生。

使用环形图,我可以选择一年,它会突出显示,切换它会突出显示年份,然后是整个戒指。但是一直以来,行图表上都没有发生任何事情。

因此它实际上已经失去了交互性。这可能是一个愚蠢的例子,但它可能会帮助我更好地理解它。 为什么它失去了交互性? 或者换句话说,我怎样才能在图表中以相同的方式呈现数据而不失去交互性?因此,如果我在行图上选择 2012,这将在环形图上突出显示(或显示为整个环)?也许这与我的数据集有关。

可能有用: Why are some of my charts not filtering?

【问题讨论】:

  • Crossfilter 库负责协调数据上的过滤器并更新在过滤维度后创建的所有维度和组。 dc.js 库负责协调图表,因此在图表应用过滤器后,dc.js 会向图表组中的所有其他图表发出信号,通过重新查询它们使用的 Crossfilter 维度/组来更新自身。
  • @EthanJewett tks 如果我可以在 edit1 中以另一种方式提出问题,也许您可​​以帮助我更好地理解它?

标签: d3.js charts dc.js crossfilter


【解决方案1】:

我将只回答edit1,因为您最初的问题似乎很广泛。

这里有两个重要的事实:

  1. 数据来自组,过滤器通过维度应用。您可能会将组视为视图,将维度视为控制器,将交叉过滤器视为模型。 Crossfilter 并不完全符合这种模式,但这个概念确实适用于始终写入一种类型的对象,并从反映变化的另一种对象中读取。
  2. 一个组不会观察到其自身维度的变化。这支持每个图表都有自己的维度并从该维度上的组中读取数据的常见用例。您通常不希望图表自行过滤。

因此,您的组应该几乎总是与您的尺寸相匹配。为显示年份的图表设置名称维度从表面上看是没有意义的,而且会发生的情况是它会尝试按维度中没有的值进行过滤。

我不知道为什么它适用于第一次点击,但在第二次点击时,它会注册一个过滤功能,该功能将从名称维度中排除除 2012 和 2014 之外的所有内容 - 所以不会匹配任何内容。

另外,由于第 2 点,行图的组正在观察行图的维度,导致它消失。您通常不希望图表观察自己的过滤器。

两个图表相互过滤

如果您希望两个图表相互过滤,请复制维度和组,以便它们相互观察:

    yearDim  = xfilter.dimension(function(d) {return +d.Year;}),
    yearDim2 = xfilter.dimension(function(d) {return +d.Year;}),
    spendPerYear = yearDim.group().reduceSum(function(d) {return +d.Spent;}),
    spendPerYear2 = yearDim2.group().reduceSum(function(d) {return +d.Spent;}),

    yearRingChart
        .width(200).height(200)
        .dimension(yearDim)
        .group(spendPerYear)
        .innerRadius(50);
    spenderRowChart
        .width(250).height(200)
        .dimension(yearDim2)
        .group(spendPerYear2)
        .elasticX(true);

https://jsfiddle.net/gordonwoodhull/yodzpnsL/1/

两个带有“链接刷”的图表

如果您希望这两个图表应用于同一维度,而不是相互过滤,而是使它们的亮点同步,那么 dc.js 不直接支持这一点。 dc.js 无法知道哪些图表正在共享一个维度,以及可以在哪里共享亮点。

我已经使用“过滤器组”进行了一些实验,以明确设置多个图表以使用相同的过滤器。您仍然需要告诉 dc.js 要链接哪些图表。增强请求是https://github.com/dc-js/dc.js/issues/681

这还没有准备好,但你现在可以模拟它。这是一个构建事件监听器的函数,它将过滤器状态反映到其他指定的图表:

    function reflect_filters(targets) {
        var recursionGuard = false; // don't recurse forever
        if(!Array.isArray(targets))
            targets = [targets];
        return function(chart) {
            if(recursionGuard)
                return;
            recursionGuard = true;
            targets.forEach(function(target) {
                target.replaceFilter(chart.filters() ? [chart.filters()] : null);
            });
            recursionGuard = false;
        }
    }

为此,我们希望图表共享相同的维度和组:

    yearRingChart
        .width(200).height(200)
        .dimension(yearDim)
        .group(spendPerYear)
        .innerRadius(50);
    spenderRowChart
        .width(250).height(200)
        .dimension(yearDim)
        .group(spendPerYear)
        .elasticX(true);

像这样申请reflect_filters

    yearRingChart.on('filtered', reflect_filters(spenderRowChart));
    spenderRowChart.on('filtered', reflect_filters(yearRingChart));

(如果要链接的图表超过两个,则传递一组图表。)

另一个分叉:https://jsfiddle.net/gordonwoodhull/yodzpnsL/10/

汪。所以这个狭隘的问题有两个答案。宽泛的问题,一个人可以写一本书!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 2020-07-20
    • 2011-12-29
    • 2011-05-04
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多