dc.js-过滤掉后,rangeChart条消失 [英] dc.js - rangeChart bars disappearing when filtered out

查看:93
本文介绍了dc.js-过滤掉后,rangeChart条消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是dc.js的新手,它试图在演示中实现 https://dc-js.github.io上的文档源/dc.js/docs/stock.html ).

I'm new to dc.js and trying to implement a something like the "Monthly Index Abs Move" graph in the demo at https://dc-js.github.io/dc.js/ (see document source at https://dc-js.github.io/dc.js/docs/stock.html).

即.我正在尝试为放大"视图实现折线图,并为放大"视图(rangeChart)实现条形图.

ie. I'm trying to implement a line chart for "zoom in" view with a bar chart for the "zoomed out" view (rangeChart).

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

My problem is that when I filter a date range (eg. by using the "brushOn" the bar chart) then the bars that are filtered out disappear

该演示正常运行-日期范围以外的条形为灰色,日期范围内的条形为蓝色-请参见屏幕截图.

The demo has this working correctly - the bars outside the date range are gray and those within the date range are blue - see screenshots.

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

I'm using the css file used in the demo, and I'm using very similar code (see code below), so I'm not sure why this difference.

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);

推荐答案

dc.js和交叉过滤器通常支持此功能的方式是

The way dc.js and crossfilter ordinarily support this functionality is that a crossfilter group does not observe its own dimension's filters.

库存示例中的范围图示例对两个图表使用相同的尺寸(moveMonths).因此,当焦点图放大到范围图中的选定范围时,它会过滤所有其他图表(您想要的)的数据,但不会过滤范围图.

The range chart example in the stock example uses the same dimension for both charts (moveMonths). So, when the focus chart is zoomed to the selected range in the range chart, it does filter the data for all the other charts (which you want), but it does not filter the range chart.

如果您想对两个图表使用不同的尺寸,我可以看到几种解决方法.

If you want to use different dimensions for the two charts, I can see a couple ways to get around this.

也许最简单的方法是使用

Perhaps the easiest thing to do is snapshot the data and disconnect the range chart from later filters, using a 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))

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

However, the range chart also won't respond to filters on other charts, and you probably want it to.

因此可以说,更正确的做法是对焦点图和范围图都只使用一个时间维度,尽管这会终止您试图对分箱进行的优化.组可以选择使用其自己的访问器,该访问器使用维度键并产生其自己的键,该键必须保留顺序.

So arguably the more correct thing is to use only one time dimension for both the focus and range charts, although it kills the optimization you were trying to do on binning. A group optionally takes its own accessor, which takes the dimension key and produces its own key, which must preserve the ordering.

似乎正是出于这个目的而设计的:

Seems like it was probably designed for exactly this purpose:

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方面的任何东西.

I don't know if you'll notice a slowdown. Yes, JavaScript date objects are slow, but this shouldn't be an issue unless you are converting tens or hundreds of thousands of dates. It's usually DOM elements that are the bottleneck in d3/dc, not anything on the JavaScript side.

这篇关于dc.js-过滤掉后,rangeChart条消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆