通过小提琴示例

时间:2016-09-15 02:16:27

标签: d3.js charts dc.js crossfilter

这是我的样本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

中的良好图表示例

EDIT1

请参阅此fiddle

如果我将此行.group(spendPerName)更改为此.group(spendPerYear),则使用第二个图表

我现在将在两个图表上按相同的分组进行分组。这改变了图表的交互性。

现在我可以在行图上选择2012,它将突出显示。我可以将其从突出显示切换到不突出显示。但是当它突出显示并且我在行图中选择了另一年时,它们都会崩溃(消失)。环形图上一直没有发生任何事情。

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

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

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

1 个答案:

答案 0 :(得分:4)

我只回答edit1,因为你原来的问题似乎很宽泛。

这里有两个重要的事实:

  1. 数据来自群组,过滤器通过维度应用。您可能会将组视为视图,将维度视为控制器,将crossfilter视为模型。 Crossfilter并不完全符合该模式,但这个概念确实适用于始终写入一种类型的对象,并从另一个反映变化的对象中读取。
  2. 小组不会观察其自身维度的变化。这支持常见用例,其中每个图表都有自己的维度,并从该维度上的组中读取数据。您通常不希望图表过滤自己。
  3. 因此,您的论坛几乎总是符合您的尺寸。具有显示年份的图表的名称维度在其表面上没有意义,并且将发生的是它将尝试按维度中不存在的值进行过滤。

    我不知道为什么它适用于第一次点击,但是在第二次点击时它将注册一个过滤功能,它将从名称维度中排除除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/

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