您的位置:首页 > Web前端 > JavaScript

Crossfilter.js用来过滤数据

2015-03-02 20:15 232 查看


这是一篇翻译 原文http://www.codeproject.com/Articles/693841/Making-Dashboards-with-Dc-js-Part-Using-Crossfil


Making Dashboards with Dc.js - Part 1: Using Crossfilter.js

原文是用来介绍dc.js的,我这里先来介绍crossfilter.js


Using the Code

Download the Crossfilter.js file from GitHub and include it in your HTML page. For these examples, I'm going to use the raw GitHub source for a reference.

首先从github上下载Crossfilter.js 文件并嵌入网页,如果是直接用github上面的代码的话就是一下引用。

Copy Code
<script type="text/javascript" src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js"></script>


We'll first need some data. This data was pulled from the
Crossfilter
API documentation:

首先要有初始数据,crossfilter的API文档中是以下的数据:

Copy Code
var data = [
{date: "2011-11-14T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
{date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
{date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
{date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"},
{date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
{date: "2011-11-14T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
];

We'll make our
Crossfilter
instance.

生成crossfilter实例。

Copy Code
var ndx = crossfilter(data);

For our first example, we'll setup a filter using one of the integer columns. Say we want to get all the transactions with a total equal to
90
.
To do this, we need to setup a dimension.

对于我们的第一个例子,我们首先用一个整数列实现一个滤镜。我们想要所有交易信息中等于90的数据,为了做这个,我们需要安排一个维度。

Copy Code
var totalDim = ndx.dimension(function(d) { return d.total; });

Now we can start to filter it. If we wanted to find all the totals equal to
90
,
we can do the following:
我们能够开始过滤数据了。如果我们想要找到所有totals等于90的数据,就能像如下所示:

Copy Code
var total_90= totalDim.filter(90);

To see the result, we can print out the
total_90
variable to the console.
为了看到结果,在console里面输出。(这里要注意,total_90本身是一个对象,需要特殊的函数来输出)

Copy Code
print_filter("total_90");

This prints out the following. I'll mark the webconsole data in black with white writing:
console的结果如下,print_filter这个函数下面会提到。

Copy Code
"total_90(6) = [
{"date":"2011-11-14T17:22:59Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T17:07:21Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:58:03Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:53:41Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:48:46Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:30:43Z","quantity":2,"total":90,"tip":0,"type":"tab"}
]"

### Tip ###

Since we want to be able to see if our filters are working correctly, I've created a small function to printout the data to the webconsole ("Tools" > "Web Developer" > "Web Console" in Firefox).
为了正确看到过滤效果,作者自己写了显示过滤效果的函数,粘贴在diamagnetic里面就好。

Copy Code
function print_filter(filter){
var f=eval(filter);
if (typeof(f.length) != "undefined") {}else{}
if (typeof(f.top) != "undefined") {f=f.top(Infinity);}else{}
if (typeof(f.dimension) != "undefined") {f=f.dimension(function(d) { return "";}).top(Infinity);}else{}
console.log(filter+"("+f.length+") = "+JSON.stringify(f).replace("[","[\n\t").replace(/}\,/g,"},\n\t").replace("]","\n]"));
}

### End Tip ###

Each of these short hand filters has a long hand equivalent. For
filter(90)
,
it is the same as using
filterExact(90)
:
filter(90)
,
filterExact(90)
效果是一样的


Copy Code
var total_90= totalDim.filterExact(90); 


Copy Code
print_filter("total_90");


Copy Code
"total_90(6) = [
{"date":"2011-11-14T17:22:59Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T17:07:21Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:58:03Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:53:41Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:48:46Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:30:43Z","quantity":2,"total":90,"tip":0,"type":"tab"}
]" 

If we want to filter a range from
90
to
100
inclusive,
we'd put the parameter in brackets. Since we want to include
100
in our filter, we'll need to have it
go to
101
. This is the same as total
Dim.filterRange([90,101]);

如果想要范围的话,可以用
filterRange([90,101])
表示。


Copy Code
var total_90_101= totalDim.filter([90,101]);


Copy Code
print_filter("total_90_101");


Copy Code
"total_90_101(7) = [
{"date":"2011-11-14T16:54:06Z","quantity":1,"total":100,"tip":0,"type":"cash"},
{"date":"2011-11-14T17:22:59Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T17:07:21Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:58:03Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:53:41Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:48:46Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:30:43Z","quantity":2,"total":90,"tip":0,"type":"tab"}
]"

You can even get a little more fancy like only grabbing items divisible by
3
.
This is the same as
totalDim.filterFunction(function(d) { if (d%3===0)return d; } );

能被3整除的可以通过以下方式。


Copy Code
var total_3= totalDim.filter(function(d) { if (d%3===0) {return d;} } );


Copy Code
print_filter("total_3");


Copy Code
"total_3(7) = [
{"date":"2011-11-14T16:28:54Z","quantity":1,"total":300,"tip":200,"type":"visa"},
{"date":"2011-11-14T17:22:59Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T17:07:21Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:58:03Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:53:41Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:48:46Z","quantity":2,"total":90,"tip":0,"type":"tab"},
{"date":"2011-11-14T16:30:43Z","quantity":2,"total":90,"tip":0,"type":"tab"}
]"

That was pretty easy. Filtering on numbers is pretty straightforward unless you have an entry which is NaN. This will completely confuse
crossfilter
,
so make sure there are no NaNs in your dataset.
Moving onto strings, if we wanted to find all the entries where people used visa, again, we need to first create a dimension, this time on the type, then we can do our filter.
如果数据有NaN,那么可能会出问题。
如果我们想要找到用visa用户的情况,那么我们就需要创造一个新的维度了。

Copy Code
var typeDim  = ndx.dimension(function(d) {return d.type;});


Copy Code
var visa_filter = typeDim.filter("visa");


Copy Code
print_filter("visa_filter");


Copy Code
"visa_filter(2) = [
{"date":"2011-11-14T17:29:52Z","quantity":1,"total":200,"tip":100,"type":"visa"},
{"date":"2011-11-14T16:28:54Z","quantity":1,"total":300,"tip":200,"type":"visa"}
]"

If we wanted to do the same thing with cash, again, pretty easy.

Copy Code
var cash_filter = typeDim.filter("cash");


Copy Code
print_filter("cash_filter");


Copy Code
"cash_filter(2) = [
{"date":"2011-11-14T17:25:45Z","quantity":2,"total":200,"tip":0,"type":"cash"},
{"date":"2011-11-14T16:54:06Z","quantity":1,"total":100,"tip":0,"type":"cash"}
]"

We can even sum up our total column for just the cash entries using the
ReduceSum
function.
Ok, this is where it gets a little tricky. Previously, we were filtering on the dimension. You would think that you'd use the
reduceSum
function
on the filtered data. That is not the case. If we do a
ReduceSum
on the filtered data through the
group
function,
it won't observe the current filter and will give you back the totals per type in key value format. This kindof makes sense and is pretty handy for dc.js, but not when you want to try to
access the data for cash.
通过reduceSum可以对于cash的实例的total综合进行运算。typeDim是已经对tye进行维度提取的,然后再用group,reduceSum使用了total的数据。

Copy Code
var total = typeDim.group().reduceSum(function(d) {return d.total;});


Copy Code
print_filter("total");


Copy Code
"total(3) = [
{"key":"tab","value":920},
{"key":"visa","value":500},
{"key":"cash","value":300}
]"


Instead to get the total for cash, you have to do a
Groupall
on the
crossfilter
object
itself, which observes all filters; so that when we do a
ReduceSum
, we get the sum of the total column
for the current filter.
(作者这里说的是cash的total,但是代码本身表示的是所有的total的总和,除非ndx本身是cash的filter)

Copy Code
var cash_total = ndx.groupAll().reduceSum(function(d) {return d.total;}).value()


Copy Code
console.log("cash_total="+cash_total);


Copy Code
"cash_total=300"

So if the
crossfilter
object observes all filters, how come it didn't observer
the visa filter when we decided to filter on cash? Well ... it's just kind of quirky. If you try to do a filter for cash and visa, it still has the cash filter applied.:

Copy Code
var cash_and_visa_filter = typeDim.filter(function(d) { if (d ==="visa" || d==="cash") {return d;} });


Copy Code
print_filter("cash_and_visa_filter");


Copy Code
"cash_and_visa_filter(2) = [
{"date":"2011-11-14T17:25:45Z","quantity":2,"total":200,"tip":0,"type":"cash"},
{"date":"2011-11-14T16:54:06Z","quantity":1,"total":100,"tip":0,"type":"cash"}
]"

We need to first clear all filters and then it will work. It's good practise to always clear filters before starting another one.
首先要清除所有的过滤效果,在每次开始之前都要清楚原来的过滤效果。

Copy Code
typeDim.filterAll()


Copy Code
var cash_and_visa_filter = typeDim.filter(function(d) { if (d ==="visa" || d==="cash") {return d;} });


Copy Code
print_filter("cash_and_visa_filter");


Copy Code
"cash_and_visa_filter(4) = [
{"date":"2011-11-14T17:29:52Z","quantity":1,"total":200,"tip":100,"type":"visa"},
{"date":"2011-11-14T16:28:54Z","quantity":1,"total":300,"tip":200,"type":"visa"},
{"date":"2011-11-14T17:25:45Z","quantity":2,"total":200,"tip":0,"type":"cash"},
{"date":"2011-11-14T16:54:06Z","quantity":1,"total":100,"tip":0,"type":"cash"}
]"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: