【问题标题】:dc.js - rangeChart bars disappearing when filtered outdc.js - rangeChart 条在过滤后消失
【发布时间】:2017-12-11 10:27:24
【问题描述】:

我是 dc.js 的新手,并尝试在 https://dc-js.github.io/dc.js/ 的演示中实现类似“每月指数绝对值移动”图的东西 (请参阅https://dc-js.github.io/dc.js/docs/stock.html 的文档来源)。

即。我正在尝试使用“缩小”视图(rangeChart)的条形图实现“放大”视图的折线图。

我的问题是,当我过滤日期范围时(例如,通过使用“brushOn”条形图),被过滤掉的条形消失

该演示可以正常工作 - 日期范围之外的条形为灰色,日期范围内的条形为蓝色 - 请参见屏幕截图。

我正在使用演示中使用的 css 文件,并且我使用的代码非常相似(请参见下面的代码),所以我不确定为什么会有这种差异。

var maxDate = new Date(1985, 0, 1);
var minDate = new Date(2200, 12, 31);
events.forEach(function (d) {
    d.created = new Date(d.created);
    //d.last_modified = new Date(d.last_modified);
    d.hour = d3.time.hour(d.created); // precaclculate for performance
    d.day = d3.time.day(d.created);
    if (d.created > maxDate) {
        maxDate = d.created;
    }
    if (d.created < minDate) {
        minDate = d.created;
    }
});

var ndx = crossfilter(events);

var dateDimension = ndx.dimension(dc.pluck('created'));
var chatHourDim = ndx.dimension(dc.pluck('hour'));
var chatDayDim = ndx.dimension(dc.pluck('day'));

var chatsPerHourGroup = chatHourDim.group().reduceCount();
var chatsPerDayGroup = chatDayDim.group().reduceCount();

visitorsPerHour   /* dc.lineChart('#visitors-count', 'chartGroup'); */
    .renderArea(true)
    .width(900)
    .height(200)
    .transitionDuration(10)
    .margins({top: 30, right: 40, bottom: 25, left: 40})
    .dimension(chatHourDim)
    .mouseZoomable(true)
    // Specify a “range chart” to link its brush extent with the zoom of the current “focus chart”.
    .rangeChart(visitorsPerDay)
    .x(d3.time.scale().domain([minDate, maxDate]))
    .round(d3.time.hour.round)
    .xUnits(d3.time.hours)
    .elasticY(true)
    .renderHorizontalGridLines(true)
    .legend(dc.legend().x(650).y(10).itemHeight(13).gap(5))
    .brushOn(false)
    .group(chatsPerHourGroup, 'Chat events per hour')
    .title(function (d) {
        var value = d.value;
        if (isNaN(value)) {
            value = 0;
        }
        return dateFormat(d.key) + '\n' + value + " chat events";
    });


// dc.barChart("visitors-count-per-day", 'chartGroup'); 
visitorsPerDay.width(900)
    .height(40)
    .margins({top: 0, right: 50, bottom: 20, left: 40})
    .dimension(chatDayDim)
    .group(chatsPerDayGroup)
    // .centerBar(true)
    .gap(1)
    .brushOn(true)
    .x(d3.time.scale().domain([minDate, maxDate]))
    .round(d3.time.day.round)
    .alwaysUseRounding(true)
    .xUnits(d3.time.days);

【问题讨论】:

    标签: javascript d3.js dc.js


    【解决方案1】:

    dc.js 和 crossfilter 通常支持此功能的方式是 a crossfilter group does not observe its own dimension's filters

    股票示例中的范围图示例对两个图表使用相同的维度 (moveMonths)。因此,当焦点图表缩放到范围图表中的选定范围时,它会过滤所有其他图表(您想要的)的数据,但不会过滤范围图表。

    如果您想为这两个图表使用不同的维度,我可以看到一些解决此问题的方法。

    使用假组

    也许最简单的做法是使用fake group 对数据进行快照并断开范围图与后续过滤器的连接:

    function snapshot_group(group) {
        // will get evaluated immediately when the charts are initializing
        var _all = group.all().map(function(kv) {
            // don't just copy the array, copy the objects inside, because they may change
            return {key: kv.key, value: kv.value};
        });
        return {
            all: function() { return _all; }
        };
    }
    
    visitorsPerDay
        .group(snapshot_group(chatsPerDayGroup))
    

    但是,范围图也不会响应其他图表上的过滤器,您可能希望它响应。

    相同的维度,不同的组

    因此可以说,更正确的做法是对焦点图和范围图只使用一个时间维度,尽管它会破坏您尝试对分箱进行的优化。一个组可选地采用它自己的访问器,它采用维度键并产生它自己的键,它必须保持顺序。

    似乎它可能正是为此目的而设计的:

    var dateDimension = ndx.dimension(dc.pluck('created'));
    
    var chatsPerHourGroup = dateDimension.group(function(d) {
        return d3.time.hour(d);
    }).reduceCount();
    var chatsPerDayGroup = dateDimension.group(function(d) {
        return d3.time.day(d);
    }).reduceCount();
    
    visitorsPerHour   /* dc.lineChart('#visitors-count', 'chartGroup'); */
        .dimension(dateDimension)
        .group(chatsPerHourGroup, 'Chat events per hour')
    
    visitorsPerDay.width(900)
        .dimension(dateDimension)
        .group(chatsPerDayGroup)
    

    我不知道您是否会注意到减速。是的,JavaScript 日期对象很慢,但这应该不是问题,除非您要转换数万或数十万个日期。 d3/dc 中的瓶颈通常是 DOM 元素,而不是 JavaScript 方面的任何东西。

    【讨论】:

    • 谢谢!我使用了您的第二个建议,根本没有注意到任何减速。现在它起作用了,更重要的是 - 我更了解发生了什么。
    • 太好了。是的,代替书籍或概念文档,我尝试将这些 SO 答案转化为可靠的解释。感谢您的欣赏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 2020-12-31
    相关资源
    最近更新 更多