-->

crossfilter“双分组”,其中关键的是另一个减少的值(crossfilter “double

2019-09-28 04:05发布

下面是我对MAC地址的数据。 它每分钟记录。 对于每一分钟,我有许多独特的MAC地址。

mac_add,created_time
18:59:36:12:23:33,2016-12-07 00:00:00.000
1c:e1:92:34:d7:46,2016-12-07 00:00:00.000
2c:f0:ee:86:bd:51,2016-12-07 00:00:00.000
5c:cf:7f:d3:2e:ce,2016-12-07 00:00:00.000
...
18:59:36:12:23:33,2016-12-07 00:01:00.000
1c:cd:e5:1e:99:78,2016-12-07 00:01:00.000
1c:e1:92:34:d7:46,2016-12-07 00:01:00.000
5c:cf:7f:22:01:df,2016-12-07 00:01:00.000
5c:cf:7f:d3:2e:ce,2016-12-07 00:01:00.000
...

我想创建一个使用dc.js和crossfilter 2个条形图。 请参阅图像图表。

第一个柱状图是很容易的创建。 这是刷涂。 我创建了“CREATED_TIME”尺寸,并且创建一组和由reduceCount“mac_add”,如以下:

var moveTime = ndx.dimension(function (d) {
                    return d.dd; //# this is the created_time
                });
var timeGroup = moveTime.group().reduceCount(function (d) {
                    return d.mac_add;
                });
var visitorChart = dc.barChart('#visitor-no-bar');
visitorChart.width(990) 
                .height(350)
                .margins({ top: 0, right: 50, bottom: 20, left: 40 })
                .dimension(moveTime)
                .group(timeGroup)
                .centerBar(true)
                .gap(1)
                .elasticY(true)
                .x(d3.time.scale().domain([new Date(2016, 11, 7), new Date(2016, 11, 13)]))
                .round(d3.time.minute.round)
                .xUnits(d3.time.minute);

visitorChart.render();

问题是所述第二线图上。 这个想法是,数据的一行等于1分钟,这样我就可以,通过“mac_add”创建另一个维度汇总和总结各MAC地址的所有分钟,得到各MAC地址的时间长度和做reduceCount的“mac_add “得到的时间长度。 然后,目标是通过组30分钟时间长度。 因此,我们可以得到多少的MAC地址有30分钟少了,时间长了多少有30分钟和1小时,多少mac_add该播放1小时和1.5小时之间等时间的长短之间的时间长度mac_add ...

如果我错了请纠正我。 从逻辑上讲,我想在第二条形图的尺寸应的组的时间长度的(如<30,<1小时,<1.5小时等)。 但时间长组本身无法解决。 它取决于第一图表的刷选择。 也许它仅包含30分钟,也许它只包含1.5小时后,也许它包含1.5小时,2小时后,等...

所以,我真的糊涂到把什么参数到第二个条形图。 和方法来获得所需要的参数(如何组归组数据)。 请帮我解释一下解决方案。

问候,马文

Answer 1:

我认为我们已经把这种“双重分组”在过去,但我找不到以前的问题。

设置组

我与该MAC地址的规则crossfilter组开始,然后产生一个假组分钟数的总量,除以。

var minutesPerMacDim = ndx.dimension(function(d) { return d.mac_add; }),
    minutesPerMapGroup = minutesPerMacDim.group();

function bin_keys_by_value(group, bin_value) {
    var _bins;
    return {
        all: function() {
            var bins = {};
            group.all().forEach(function(kv) {
                var valk = bin_value(kv.value);
                bins[valk] = bins[valk] || [];
                bins[valk].push(kv.key);
            });
            _bins = bins;
            // note: Object.keys returning numerical order here might not
            // work everywhere, but I couldn't find a browser where it didn't
            return Object.keys(bins).map(function(bin) {
                return {key: bin, value: bins[bin].length};
            })
        },
        bins: function() {
            return _bins;
        }
    };
}

function bin_30_mins = function(v) {
    return 30 * Math.ceil(v/30);
}

var macsPerMinuteCount = bin_keys_by_value(minutesPerMacGroup);

这将保留该MAC地址的每个时间段,我们将在以后需要进行过滤。 这是罕见的非标准方法添加bins到一个虚假组,但我想不出一个有效的方式来保留这些信息,因为过滤界面只会给我们访问密钥。

由于该功能需要装箱函数,我们甚至可以用一个临界规模 ,如果我们想要更多的复杂箱不仅仅是四舍五入到最接近的30分钟。 甲量化尺度是做上面示出的舍入一个更一般的方式。

设置图表

使用该数据来驱动一个图表很简单:我们可以使用尺寸和假组如常。

chart
    .dimension(minutesPerMacDim)
    .group(macsPerMinuteCount)

建立图表,以便它可以过滤是一个比较复杂:

chart.filterHandler(function(dimension, filters) {
    if(filters.length === 0)
        dimension.filter(null);
    else {
        var bins = chart.group().bins(); // retrieve cached bins
        var macs = filters.map(function(key) { return bins[key]; })
        macs = Array.prototype.concat.apply([], macs);
        var macset = d3.set(macs);
        dimension.filterFunction(function(key) {
            return macset.has(key);
        })
    }
})

我们使用它的MAC地址键入一个维度召回; 因为我们要对MAC地址进行过滤,这是好的。 但图表接收分钟,计数其按键和filters将包含那些键,像306090 ,等等。所以我们需要提供一个filterHandler这需要分钟计数键和过滤基于这些维度。

注1:这是所有未经验证,因此,如果它不能正常工作,请发表一个例子作为小提琴或bl.ock -有小提琴和块你可以派生上手主页上 。

注2:严格地说,这不是测量的连接的长度:它的计数连接分钟的总数量。 不知道这对你很重要。 如果用户断开连接,然后将时间内重新连接,这两个会话将被计数为一个。 我认为你必须进行预处理,以获得时间。

编辑 :根据你的小提琴(谢谢!)上面的代码似乎工作。 这只是一个设置的X规模和物质xUnits正常。

  chart2
      .x(d3.scale.linear().domain([60,1440]))
      .xUnits(function(start, end) {
          return (end-start)/30;
      })

线性刻度会做就好了这里-我不会试图量化这种规模,因为30分钟的部门已经成立。 我们确实需要设置xUnits使dc.js知道有多宽,使酒吧。

我不知道为什么elasticX没有在这里工作,但<30箱完全矮化一切,所以我认为这是最好的离开了这一点。

你的小提琴叉: https://jsfiddle.net/gordonwoodhull/2a8ow1ay/2/



文章来源: crossfilter “double grouping” where key is the value of another reduction