Crossfilter API Reference
crossfilter 表示多维数组集
# crossfilter([records])
构建新的多维数组集。记录records被指定,添加指定的记录records。
记录records可以是任意的数组,JavaScript对象或者基础数据。如例:
var payments = crossfilter([
{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"}
]);
# crossfilter.add(records)
添加指定的记录records到多维数组集crossfilter。
# crossfilter.remove()
从多维数组集中删除所有当前过滤器匹配的记录records。
# crossfilter.size()
返回记录records的数量在多维数组集,独立的任何过滤器中。例如,已经添加单一批次的
记录到多维数据集中,这个方法将返回records.length。
# crossfilter.groupAll()
一个便捷的功能对所有的记录进行分组和减少为单一值。
注意:这个groupAll观察所有的过滤器,和dimension的groupAll不一样。
Dimension
# crossfilter.dimension(value)
使用指定的值访问器函数构造一个新的dimension。这个函数必须返回自然有序的值,即:
正确的行为关于javascript的<
, <=
和>
,>=
运算符。
这通常意味着基础数据:booleans,数字或者字符串; 然而: 可以重写object.valueOf来保证这个值和给定的对象值相似,如日期。
特别是,注意null
和undefined
是不支持的。此外,混合类型应该采用,例如:字符串和数字。
如果字符串和数字混合,那么字符串将会强制转换成数字,因此字符串必须可以强制转换成数字,否则就会导致NaN
。
例:
var paymentsByTotal = payments.dimension(function(d) { return d.total; });
给定的dimension访问器函数返回的值必须是确定的,并且对于crossfilter的存在永远不变。
性能说明:在内部,缓存给定的dimension的值。因此,如果 dimension值是从其他属性派生的,
没有必要在crossfilter以外派生值。只有当records添加到crossfilter中时才调用值函数。
dimension一旦创建就会绑定到crossfilter。创建超过8个dimension和超过16个dimension
会带来额外的开销。目前不支持一次超过32个dimension。但是可以用dimension.dispose
布置dimension来给新的dimension腾出空间。dimension的状态,记录关联的特定dimension的过滤器,如果真有的话。初期,如果dimension没有指定过滤器:所有的records都会被选中。由于创建dimension比较占用资源,因此应该谨慎保留对创建的任何dimension的引用。
# dimension.filter(value)
过滤records,使dimension值和value匹配,然后返回这个dimension。
这个被指定的value如果是null,这种情况下此方法相当于filterAll;
这个value如果是数组,这种情况下此方法相当于filterRange;
这个value如果是函数,这种情况下此方法相当于filterFunction;
除此之外,此方法相当于filterExact。
例:
paymentsByTotal.filter([100, 200]); // 选取总额在100到200之间的付款
paymentsByTotal.filter(120); // 选取总额等于120的付款
paymentsByTotal.filter(function(d) { return d % 2; }); // 选取总额是奇数的付款
paymentsByTotal.filter(null); // 选取所有的付款
如果调用过滤器将会替换现有的过滤器,如果dimension有的话
# dimension.filterExact(value)
过滤records,使dimension值和value匹配,然后返回这个dimension。
例:
paymentsByTotal.filterExact(120); // 选取总额等于120的付款
注意使用排序运算符<
, <=
和>
,>=
进行精确比较。例如,如果传递的值是null, 这相当于0;
过滤不要用==
和===
运算符。
如果调用过滤器将会替换现有的过滤器,如果dimension有的话
# dimension.filterRange(range)
过滤records,使dimension值大于等于range[0],小于range[1],返回这个dimension。
例:
paymentsByTotal.filterRange([100, 200]); // 选取总额在100到200之间的付款
# dimension.filterFunction(function)
过滤records,被调用时使用指定的函数返回dimension值的真值,并返回dimension。
例:
paymentsByTotal.filterFunction(function(d) { return d % 2; }); // // 选取总额是奇数的付款
这可以用于实现联合过滤器,例如:
// 选取总额在0到10或者20到30之间的付款
paymentsByTotal.filterFunction(function(d) { return 0 <= d && d < 10 || 20 <= d && d < 30; });
# dimension.filterAll()
清除任何dimension的过滤器,选取所有的records并返回dimension。
例:
paymentsByTotal.filterAll(); // 选取所有的付款
# dimension.top(k)
返回一个包含前k个records的数组,根据此dimension的自然顺序。被返回的数组是按照降序的自然顺序进行排列。这个方法和crossfilter当前的过滤器相交,只返回满足所有能动的过滤器(包括此维度的过滤器)的records。
例:
var topPayments = paymentsByTotal.top(4); // the top four payments, by total
topPayments[0]; // the biggest payment
topPayments[1]; // the second-biggest payment
// etc.
如果根据crossfilter所有的过滤器选择的records比k少,那就返回一个少于k的数组。
例:
var allPayments = paymentsByTotal.top(Infinity); //返回所有的
# dimension.bottom(k)
返回一个包含后k个records的数组,根据此dimension的自然顺序。被返回的数组是按照升序的自然顺序进行排列。这个方法和crossfilter当前的过滤器相交,只返回满足所有能动的过滤器(包括此维度的过滤器)的records。
例:
var bottomPayments = paymentsByTotal.bottom(4); // the bottom four payments, by total
bottomPayments[0]; // the smallest payment
bottomPayments[1]; // the second-smallest payment
// etc.
# dimension.dispose()
删除这个dimension(包括它的groups)从crossfilter。这为添加到这个crossfilter其他的dimension释放了空间。
Group (Map-Reduce)
# dimension.group([groupValue])
为给定的dimension构造一个新的群组,根据指定的groupValue函数,采取dimension的值作为输入值,并返回相应的四舍五入值。这个groupValue是可选的;如果不指定,则默认为恒等函数。类似的值函数,groupValue必须返回自然有序的值;此外,这种顺序必须符合这个dimension的值函数。
例:
var paymentGroupsByTotal = paymentsByTotal.group(function(total) { return Math.floor(total / 100); });
默认情况下,这个group的reduce函数将计算每个组的记录数。此外,这个groups将按照记录数排序。
注意:这个分组和crossfire当前的过滤器相交,除了相关联的dimension的过滤器。因此,group方法仅考虑满足除dimension的过滤器之外的每个过滤器的记录。所以,如果付款的ceossfilter是按照type和total过滤,则总额的group只按照type观察过滤器。
# group.size()
返回group中不同值的数量,无关任何过滤器;基础数据。
# group.reduce(add, remove, initial)
指定分组的reduce函数,并返回这个group。默认的行为,通过count进行缩减。
例:
//p是上一数据,v是当前数据
function reduceAdd(p, v) {
return p + 1;
}
function reduceRemove(p, v) {
return p - 1;
}
function reduceInitial() {
return 0;
}
为了缩减total的总数(计算total的总和),你可以修改add函数和remove函数,如下实施:
function reduceAdd(p, v) {
return p + v.total;
}
function reduceRemove(p, v) {
return p - v.total;
}
除了add函数以外,remove函数也是需要的,因为group的缩减是逐渐地随着记录被过滤而更新的;在一些情况下,需要从先前计算的group reduction中删除记录。使用许多不同的属性,你可以使用javascript闭包创建add和remove函数。
# group.reduceCount()
一个便捷的方法为了统计记录数量的reduce函数,返回这个group。
# group.reduceSum(value)
一个便捷的方法使用指定的value访问器计算记录总和的reduce函数,返回这个group。
例:
//按照付款类型,计算付款总额,相同类型的付款值累加
var paymentsByType = payments.dimension(function(d) { return d.type; }),
paymentVolumeByType = paymentsByType.group().reduceSum(function(d) { return d.total; }),
topTypes = paymentVolumeByType.top(1);
topTypes[0].key; // the top payment type (e.g., "tab")
topTypes[0].value; // the payment volume for that type (e.g., 920)
# group.order(orderValue)
指定orderValue计算前K个组。默认的order函数是恒等函数,假定reduction值是自然顺序(如简单的计数和款项)。
例:
function reduceAdd(p, v) {
++p.count;
p.total += v.total;
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.total;
return p;
}
function reduceInitial() {
return {count: 0, total: 0};
}
function orderValue(p) {
return p.total;
}
var topTotals = paymentVolumeByType.reduce(reduceAdd, reduceRemove, reduceInitial).order(orderValue).top(2);
topTotals[0].key; // payment type with highest total (e.g., "tab")
topTotals[0].value; // reduced value for that type (e.g., {count:8, total:920})
这种技术同样可以计算每个组中特殊值的个数,把计数每一个组缩减的值存储为map,当计数到达零时删除这个map。
# group.orderNatural()
使用自然顺序缩减值的便捷方法。返回这个分组。
# group.top(k)
返回一个包含前k个组的新数组,根据被关联缩减值的组顺序。被返回的数组是按照缩减(统计会不会更容易理解?)值的降序排列。
例:
//检索付款类型数量最多的一个
var paymentsByType = payments.dimension(function(d) { return d.type; }),
paymentCountByType = paymentsByType.group(),
topTypes = paymentCountByType.top(1);
topTypes[0].key; // the top payment type (e.g., "tab")
topTypes[0].value; // the count of payments of that type (e.g., 8)
通过crossfilter的过滤器如果group少于k个,就返回一个少于k的数组。如果有一个少于k的非空组,这个方法也有可能返回空的组(零个被选定的记录)。
# group.all()
返回包含所有的组的数组,按照key的升序排列。就像top,被返回的对象包含key
和value
两个属性。被返回的数组也有可能包含空的组:group缩减初始化函数返回的值。
例:
//通过类型计数付款
var types = paymentCountByType.all();
这个方法比’top(Infinity)’更快,因为整个数组原样被返回,而不是选择新数组和排序。不要修改被返回的数组!
# group.dispose()
从dimension中删除group。当新的过滤器应用于crossfilter时这个组将不再更新,如果他没有其他引用,则可能被垃圾回收。
Group All(Reduce)
# dimension.groupAll()
将所有的记录分组到一个简单的组中的便捷函数。被返回的对象相当于一个标准的grouping,除了没有top和order方法。相反,使用value检索符合所有records的缩减值。
# groupAll.reduce(add, remove, initial)
相当于reduce。
# groupAll.value()
相当于all()[0].value。
Extras
crossfilter有几个额外的东西,你应该会感觉很有用。
# crossfilter.bisect
恒等平分;适用于数字,字符串,日期和自然可比的对象。
# crossfilter.bisect.by(value)
使用指定的value访问器构建一个新的平分器,这个访问器必须能返回一个自然有序的值。