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
CrossfilterAPI 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
Crossfilterinstance.
生成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_90variable 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. Forfilter(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
90to
100inclusive,
we'd put the parameter in brackets. Since we want to include
100in 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
ReduceSumfunction.
Ok, this is where it gets a little tricky. Previously, we were filtering on the dimension. You would think that you'd use the
reduceSumfunction
on the filtered data. That is not the case. If we do a
ReduceSumon the filtered data through the
groupfunction,
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
Groupallon the
crossfilterobject
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
crossfilterobject 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"} ]"
相关文章推荐
- Flex 使用ArrayCollection的FilterFunction进行数据过滤
- 数据视图DataView中,行过滤RowFilter的技巧应用
- 关于同时设置 VAR_FILTERS 和 DEFAULT_FILTER 造成数据二次过滤的BUG
- sql中having关键字和where关键字用来过滤数据区别
- Filter(一)——设置SimpleAdapter的Filter从而过滤数据
- Flex 使用ArrayCollection的FilterFunction进行数据过滤
- Flex 使用ArrayCollection的FilterFunction进行数据过滤
- jQuery的filter过滤重复结构的xml数据
- Microshaoft Cross-Domain + ASP.NET MVC 5 WebAPI 2 + Self-Host + JsonpMediaTypeFormatter + WCF + JsonP + PerformaceCounterFilter + Knockout.js + MVVM
- java 使用全局过滤器Filter之后 防止css文件与js文件被过滤
- 动态数据过滤Filter
- PHP中使用Filter进行数据安全过滤
- jsData 使用教程(七) 过滤数据
- SingleColumnValueFilter 过滤数据时候,返回的数据不正常问题
- 大数据过滤及判断算法 -- Bitmap / Bloomfilter
- 数据视图DataView中,行过滤RowFilter的技巧整理
- js javaScript array 取指定元素索引、判断是否相同、重复、过滤数据
- 利用jQuery中的filter来过滤重复结构的xml数据
- Filter(三)——Android利用Filterable接口过滤数据
- Filter不过滤CSS和JS