Crossfilter.js用来过滤数据
来源:互联网 发布:java常用开发环境 编辑:程序博客网 时间:2024/05/14 03:15
这是一篇翻译 原文http://www.codeproject.com/Articles/693841/Making-Dashboards-with-Dc-js-Part-Using-Crossfil
Making Dashboards with Dc.js - Part 1: Using 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上面的代码的话就是一下引用。
<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文档中是以下的数据:
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 实例。
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.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的数据,就能像如下所示:
var total_90 = totalDim.filter(90);
To see the result, we can print out the total_90
variable to the console.
为了看到结果,在console里面输出。(这里要注意,total_90本身是一个对象,需要特殊的函数来输出)
print_filter("total_90");
This prints out the following. I'll mark the webconsole data in black with white writing:
console的结果如下,print_filter这个函数下面会提到。
"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里面就好。
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 usingfilterExact(90)
:
filter(90)
,filterExact(90)
效果是一样的
。
var total_90 = totalDim.filterExact(90);
print_filter("total_90");
"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 include100
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])
表示。
var total_90_101= totalDim.filter([90,101]);
print_filter("total_90_101");
"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 astotalDim.filterFunction(function(d) { if (d%3===0)return d; } );
能被3整除的可以通过以下方式。
var total_3= totalDim.filter(function(d) { if (d%3===0) {return d;} } );
print_filter("total_3");
"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用户的情况,那么我们就需要创造一个新的维度了。
var typeDim = ndx.dimension(function(d) {return d.type;});
var visa_filter = typeDim.filter("visa");
print_filter("visa_filter");
"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.
var cash_filter = typeDim.filter("cash");
print_filter("cash_filter");
"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的数据。
var total = typeDim.group().reduceSum(function(d) {return d.total;});
print_filter("total");
"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)
var cash_total = ndx.groupAll().reduceSum(function(d) {return d.total;}).value()
console.log("cash_total="+cash_total);
"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.:
var cash_and_visa_filter = typeDim.filter(function(d) { if (d ==="visa" || d==="cash") {return d;} });
print_filter("cash_and_visa_filter");
"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.
首先要清除所有的过滤效果,在每次开始之前都要清楚原来的过滤效果。
typeDim.filterAll()
var cash_and_visa_filter = typeDim.filter(function(d) { if (d ==="visa" || d==="cash") {return d;} });
print_filter("cash_and_visa_filter");
"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"}]"
- Crossfilter.js用来过滤数据
- js数据过滤
- 使用 Crossfilter 和 dc.js 构建交互式报表
- Crossfilter总结
- D3 JS 库 - 用来展示数据分析的结果
- sql中having关键字和where关键字用来过滤数据区别
- js根据条件过滤table数据
- Crossfilter API翻译
- php中filter函数用来验证、过滤
- php中filter函数用来验证、过滤
- 数据过滤
- JS中可以用来存储用户数据的方法或方式
- 在Ext JS Store用正则表达式过滤数据
- 利用js和css实现Bootstrap下拉列表数据过滤
- js过滤字符串
- 过滤js脚本
- js 过滤尖括号
- js过滤特殊字符
- Python--ZOJ1205
- Android assets是拿不到uri的! 坑爹的吧
- git服务器新增用户
- 流媒体传输原理
- Pig安装
- Crossfilter.js用来过滤数据
- 安装office 2007 后 安装vs 2008 显示web组件有问题
- 辛星笔记云计算第四篇即云的四种模式
- linux tomcat 启动不成功-关于文件权限
- PAT(B)1008. 数组元素循环右移问题 (20)
- Quartz2D颜色渐变效果
- 并查集模版&最小生成树
- 看数据结构写代码(12)栈的应用(三) 行编辑器
- POJ 1321 棋盘问题