Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Rename Tesseract to Crossfilter.

  • Loading branch information...
commit e46041d83ddfea0844e92ed2133ae56561d69a8f 1 parent 69a383d
@mbostock mbostock authored
View
10 Makefile
@@ -3,9 +3,9 @@ JS_COMPILER = ./node_modules/uglify-js/bin/uglifyjs
.PHONY: test benchmark
-all: tesseract.min.js package.json
+all: crossfilter.min.js package.json
-tesseract.js: \
+crossfilter.js: \
src/version.js \
src/identity.js \
src/permute.js \
@@ -19,7 +19,7 @@ tesseract.js: \
src/null.js \
src/zero.js \
src/reduce.js \
- src/tesseract.js \
+ src/crossfilter.js \
Makefile
%.min.js: %.js Makefile
@@ -33,13 +33,13 @@ tesseract.js: \
@echo '})(this);' >> $@
@chmod a-w $@
-package.json: tesseract.js src/package.js
+package.json: crossfilter.js src/package.js
@rm -f $@
node src/package.js > $@
@chmod a-w $@
clean:
- rm -f tesseract.js tesseract.min.js package.json
+ rm -f crossfilter.js crossfilter.min.js package.json
test: all
@$(JS_TESTER)
View
8 README.md
@@ -1,11 +1,11 @@
-# Tesseract
+# Crossfilter
Fast *n*-dimensional filtering and grouping of records in JavaScript.
-See <http://square.github.com/tesseract/> for an interactive example.
+See <http://square.github.com/crossfilter/> for an interactive example.
-See <https://github.com/square/tesseract/wiki/API-Reference> for documentation.
+See <https://github.com/square/crossfilter/wiki/API-Reference> for documentation.
## Contributing
-We'd love for you to participate in the development of Tesseract. Before we can accept your pull request, please sign our [Individual Contributor License Agreement](https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1). It's a short form that covers our bases and makes sure you're eligible to contribute. Thank you!
+We'd love for you to participate in the development of Crossfilter. Before we can accept your pull request, please sign our [Individual Contributor License Agreement](https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1). It's a short form that covers our bases and makes sure you're eligible to contribute. Thank you!
View
146 tesseract.js → crossfilter.js
@@ -1,9 +1,9 @@
(function(exports){
-tesseract.version = "1.0.1";
-function tesseract_identity(d) {
+crossfilter.version = "1.0.2";
+function crossfilter_identity(d) {
return d;
}
-tesseract.permute = permute;
+crossfilter.permute = permute;
function permute(array, index) {
for (var i = 0, n = index.length, copy = new Array(n); i < n; ++i) {
@@ -11,7 +11,7 @@ function permute(array, index) {
}
return copy;
}
-var bisect = tesseract.bisect = bisect_by(tesseract_identity);
+var bisect = crossfilter.bisect = bisect_by(crossfilter_identity);
bisect.by = bisect_by;
@@ -55,7 +55,7 @@ function bisect_by(f) {
bisectRight.left = bisectLeft;
return bisectRight;
}
-var heap = tesseract.heap = heap_by(tesseract_identity);
+var heap = crossfilter.heap = heap_by(crossfilter_identity);
heap.by = heap_by;
@@ -99,7 +99,7 @@ function heap_by(f) {
heap.sort = sort;
return heap;
}
-var heapselect = tesseract.heapselect = heapselect_by(tesseract_identity);
+var heapselect = crossfilter.heapselect = heapselect_by(crossfilter_identity);
heapselect.by = heapselect_by;
@@ -135,7 +135,7 @@ function heapselect_by(f) {
return heapselect;
}
-var insertionsort = tesseract.insertionsort = insertionsort_by(tesseract_identity);
+var insertionsort = crossfilter.insertionsort = insertionsort_by(crossfilter_identity);
insertionsort.by = insertionsort_by;
@@ -156,7 +156,7 @@ function insertionsort_by(f) {
// Algorithm designed by Vladimir Yaroslavskiy.
// Implementation based on the Dart project; see lib/dart/LICENSE for details.
-var quicksort = tesseract.quicksort = quicksort_by(tesseract_identity);
+var quicksort = crossfilter.quicksort = quicksort_by(crossfilter_identity);
quicksort.by = quicksort_by;
@@ -435,28 +435,28 @@ function quicksort_by(f) {
}
var quicksort_sizeThreshold = 32;
-var tesseract_array8 = tesseract_arrayUntyped,
- tesseract_array16 = tesseract_arrayUntyped,
- tesseract_array32 = tesseract_arrayUntyped,
- tesseract_arrayLengthen = tesseract_identity,
- tesseract_arrayWiden = tesseract_identity;
+var crossfilter_array8 = crossfilter_arrayUntyped,
+ crossfilter_array16 = crossfilter_arrayUntyped,
+ crossfilter_array32 = crossfilter_arrayUntyped,
+ crossfilter_arrayLengthen = crossfilter_identity,
+ crossfilter_arrayWiden = crossfilter_identity;
if (typeof Uint8Array !== "undefined") {
- tesseract_array8 = function(n) { return new Uint8Array(n); };
- tesseract_array16 = function(n) { return new Uint16Array(n); };
- tesseract_array32 = function(n) { return new Uint32Array(n); };
+ crossfilter_array8 = function(n) { return new Uint8Array(n); };
+ crossfilter_array16 = function(n) { return new Uint16Array(n); };
+ crossfilter_array32 = function(n) { return new Uint32Array(n); };
- tesseract_arrayLengthen = function(array, length) {
+ crossfilter_arrayLengthen = function(array, length) {
var copy = new array.constructor(length);
copy.set(array);
return copy;
};
- tesseract_arrayWiden = function(array, width) {
+ crossfilter_arrayWiden = function(array, width) {
var copy;
switch (width) {
- case 16: copy = tesseract_array16(array.length); break;
- case 32: copy = tesseract_array32(array.length); break;
+ case 16: copy = crossfilter_array16(array.length); break;
+ case 32: copy = crossfilter_array32(array.length); break;
default: throw new Error("invalid array width!");
}
copy.set(array);
@@ -464,17 +464,17 @@ if (typeof Uint8Array !== "undefined") {
};
}
-function tesseract_arrayUntyped(n) {
+function crossfilter_arrayUntyped(n) {
return new Array(n);
}
-function tesseract_filterExact(bisect, value) {
+function crossfilter_filterExact(bisect, value) {
return function(values) {
var n = values.length;
return [bisect.left(values, value, 0, n), bisect.right(values, value, 0, n)];
};
}
-function tesseract_filterRange(bisect, range) {
+function crossfilter_filterRange(bisect, range) {
var min = range[0],
max = range[1];
return function(values) {
@@ -483,38 +483,38 @@ function tesseract_filterRange(bisect, range) {
};
}
-function tesseract_filterAll(values) {
+function crossfilter_filterAll(values) {
return [0, values.length];
}
-function tesseract_null() {
+function crossfilter_null() {
return null;
}
-function tesseract_zero() {
+function crossfilter_zero() {
return 0;
}
-function tesseract_reduceIncrement(p) {
+function crossfilter_reduceIncrement(p) {
return p + 1;
}
-function tesseract_reduceDecrement(p) {
+function crossfilter_reduceDecrement(p) {
return p - 1;
}
-function tesseract_reduceAdd(f) {
+function crossfilter_reduceAdd(f) {
return function(p, v) {
return p + +f(v);
};
}
-function tesseract_reduceSubtract(f) {
+function crossfilter_reduceSubtract(f) {
return function(p, v) {
return p - f(v);
};
}
-exports.tesseract = tesseract;
+exports.crossfilter = crossfilter;
-function tesseract() {
- var tesseract = {
+function crossfilter() {
+ var crossfilter = {
add: add,
dimension: dimension,
groupAll: groupAll,
@@ -525,11 +525,11 @@ function tesseract() {
n = 0, // the number of records; data.length
m = 0, // number of dimensions in use
M = 8, // number of dimensions that can fit in `filters`
- filters = tesseract_array8(0), // M bits per record; 1 is filtered out
+ filters = crossfilter_array8(0), // M bits per record; 1 is filtered out
filterListeners = [], // when the filters change
dataListeners = []; // when data is added
- // Adds the specified new records to this tesseract.
+ // Adds the specified new records to this crossfilter.
function add(newData) {
var n0 = n,
n1 = newData.length;
@@ -540,11 +540,11 @@ function tesseract() {
// Notify listeners (dimensions and groups) that new data is available.
if (n1) {
data = data.concat(newData);
- filters = tesseract_arrayLengthen(filters, n += n1);
+ filters = crossfilter_arrayLengthen(filters, n += n1);
dataListeners.forEach(function(l) { l(newData, n0, n1); });
}
- return tesseract;
+ return crossfilter;
}
// Adds a new dimension with the specified value accessor function.
@@ -566,7 +566,7 @@ function tesseract() {
newValues, // temporary array storing newly-added values
newIndex, // temporary array storing newly-added index
sort = quicksort_by(function(i) { return newValues[i]; }),
- refilter = tesseract_filterAll, // for recomputing filter
+ refilter = crossfilter_filterAll, // for recomputing filter
indexListeners = [], // when data is added
lo0 = 0,
hi0 = 0;
@@ -579,7 +579,7 @@ function tesseract() {
// Incorporate any existing data into this dimension, and make sure that the
// filter bitset is wide enough to handle the new dimension.
- if (m > M) filters = tesseract_arrayWiden(filters, M <<= 1);
+ if (m > M) filters = crossfilter_arrayWiden(filters, M <<= 1);
preAdd(data, 0, n);
postAdd(data, 0, n);
@@ -589,7 +589,7 @@ function tesseract() {
// Permute new values into natural order using a sorted index.
newValues = newData.map(value);
- newIndex = sort(tesseract_range(n1), 0, n1);
+ newIndex = sort(crossfilter_range(n1), 0, n1);
newValues = permute(newValues, newIndex);
// Bisect newValues to determine which new records are selected.
@@ -614,7 +614,7 @@ function tesseract() {
// Otherwise, create new arrays into which to merge new and old.
values = new Array(n);
- index = tesseract_index(n, n);
+ index = crossfilter_index(n, n);
// Merge the old and new sorted values, and old and new index.
for (i = 0; i0 < n0 && i1 < n1; ++i) {
@@ -705,18 +705,18 @@ function tesseract() {
// Filters this dimension to select the exact value.
function filterExact(value) {
- return filterIndex((refilter = tesseract_filterExact(bisect, value))(values));
+ return filterIndex((refilter = crossfilter_filterExact(bisect, value))(values));
}
// Filters this dimension to select the specified range [lo, hi].
// The lower bound is inclusive, and the upper bound is exclusive.
function filterRange(range) {
- return filterIndex((refilter = tesseract_filterRange(bisect, range))(values));
+ return filterIndex((refilter = crossfilter_filterRange(bisect, range))(values));
}
// Clears any filters on this dimension.
function filterAll() {
- return filterIndex((refilter = tesseract_filterAll)(values));
+ return filterIndex((refilter = crossfilter_filterAll)(values));
}
// Returns the top K selected records, based on this dimension's order.
@@ -752,20 +752,20 @@ function tesseract() {
var groups, // array of {key, value}
groupIndex, // object id ↦ group id
groupWidth = 8,
- groupCapacity = tesseract_capacity(groupWidth),
+ groupCapacity = crossfilter_capacity(groupWidth),
k = 0, // cardinality
select,
heap,
reduceAdd,
reduceRemove,
reduceInitial,
- update = tesseract_null,
- reset = tesseract_null,
+ update = crossfilter_null,
+ reset = crossfilter_null,
resetNeeded = true;
- if (arguments.length < 1) key = tesseract_identity;
+ if (arguments.length < 1) key = crossfilter_identity;
- // The group listens to the tesseract for when any dimension changes, so
+ // The group listens to the crossfilter for when any dimension changes, so
// that it can update the associated reduce values. It must also listen to
// the parent dimension for when data is added, and compute new keys.
filterListeners.push(update);
@@ -778,7 +778,7 @@ function tesseract() {
// This function is responsible for updating groups and groupIndex.
function add(newValues, newIndex, n0, n1) {
var oldGroups = groups,
- reIndex = tesseract_index(k, groupCapacity),
+ reIndex = crossfilter_index(k, groupCapacity),
add = reduceAdd,
initial = reduceInitial,
k0 = k, // old cardinality
@@ -792,12 +792,12 @@ function tesseract() {
x; // key of group to add
// If a reset is needed, we don't need to update the reduce values.
- if (resetNeeded) add = initial = tesseract_null;
+ if (resetNeeded) add = initial = crossfilter_null;
// Reset the new groups (k is a lower bound).
// Also, make sure that groupIndex exists and is long enough.
groups = new Array(k), k = 0;
- groupIndex = k0 > 1 ? tesseract_arrayLengthen(groupIndex, n) : tesseract_index(n, groupCapacity);
+ groupIndex = k0 > 1 ? crossfilter_arrayLengthen(groupIndex, n) : crossfilter_index(n, groupCapacity);
// Get the first old key (x0 of g0), if it exists.
if (k0) x0 = (g0 = oldGroups[0]).key;
@@ -865,8 +865,8 @@ function tesseract() {
update = updateOne;
reset = resetOne;
} else {
- update = tesseract_null;
- reset = tesseract_null;
+ update = crossfilter_null;
+ reset = crossfilter_null;
}
groupIndex = null;
}
@@ -876,9 +876,9 @@ function tesseract() {
// and widen the group index as needed.
function groupIncrement() {
if (++k === groupCapacity) {
- reIndex = tesseract_arrayWiden(reIndex, groupWidth <<= 1);
- groupIndex = tesseract_arrayWiden(groupIndex, groupWidth);
- groupCapacity = tesseract_capacity(groupWidth);
+ reIndex = crossfilter_arrayWiden(reIndex, groupWidth <<= 1);
+ groupIndex = crossfilter_arrayWiden(groupIndex, groupWidth);
+ groupCapacity = crossfilter_capacity(groupWidth);
}
}
}
@@ -995,12 +995,12 @@ function tesseract() {
// A convenience method for reducing by count.
function reduceCount() {
- return reduce(tesseract_reduceIncrement, tesseract_reduceDecrement, tesseract_zero);
+ return reduce(crossfilter_reduceIncrement, crossfilter_reduceDecrement, crossfilter_zero);
}
// A convenience method for reducing by sum(value).
function reduceSum(value) {
- return reduce(tesseract_reduceAdd(value), tesseract_reduceSubtract(value), tesseract_zero);
+ return reduce(crossfilter_reduceAdd(value), crossfilter_reduceSubtract(value), crossfilter_zero);
}
// Sets the reduce order, using the specified accessor.
@@ -1013,7 +1013,7 @@ function tesseract() {
// A convenience method for natural ordering by reduce value.
function orderNatural() {
- return order(tesseract_identity);
+ return order(crossfilter_identity);
}
// Returns the cardinality of this group, irrespective of any filters.
@@ -1026,7 +1026,7 @@ function tesseract() {
// A convenience function for generating a singleton group.
function groupAll() {
- var g = group(tesseract_null), all = g.all;
+ var g = group(crossfilter_null), all = g.all;
delete g.all;
delete g.top;
delete g.order;
@@ -1055,7 +1055,7 @@ function tesseract() {
reduceInitial,
resetNeeded = true;
- // The group listens to the tesseract for when any dimension changes, so
+ // The group listens to the crossfilter for when any dimension changes, so
// that it can update the reduce value. It must also listen to the parent
// dimension for when data is added.
filterListeners.push(update);
@@ -1126,12 +1126,12 @@ function tesseract() {
// A convenience method for reducing by count.
function reduceCount() {
- return reduce(tesseract_reduceIncrement, tesseract_reduceDecrement, tesseract_zero);
+ return reduce(crossfilter_reduceIncrement, crossfilter_reduceDecrement, crossfilter_zero);
}
// A convenience method for reducing by sum(value).
function reduceSum(value) {
- return reduce(tesseract_reduceAdd(value), tesseract_reduceSubtract(value), tesseract_zero);
+ return reduce(crossfilter_reduceAdd(value), crossfilter_reduceSubtract(value), crossfilter_zero);
}
// Returns the computed reduce value.
@@ -1143,32 +1143,32 @@ function tesseract() {
return reduceCount();
}
- // Returns the number of records in this tesseract, irrespective of any filters.
+ // Returns the number of records in this crossfilter, irrespective of any filters.
function size() {
return n;
}
return arguments.length
? add(arguments[0])
- : tesseract;
+ : crossfilter;
}
// Returns an array of size n, big enough to store ids up to m.
-function tesseract_index(n, m) {
+function crossfilter_index(n, m) {
return (m < 0x101
- ? tesseract_array8 : m < 0x10001
- ? tesseract_array16
- : tesseract_array32)(n);
+ ? crossfilter_array8 : m < 0x10001
+ ? crossfilter_array16
+ : crossfilter_array32)(n);
}
// Constructs a new array of size n, with sequential values from 0 to n - 1.
-function tesseract_range(n) {
- var range = tesseract_index(n, n);
+function crossfilter_range(n) {
+ var range = crossfilter_index(n, n);
for (var i = -1; ++i < n;) range[i] = i;
return range;
}
-function tesseract_capacity(w) {
+function crossfilter_capacity(w) {
return w === 8
? 0x100 : w === 16
? 0x10000
View
2  tesseract.min.js → crossfilter.min.js
@@ -1 +1 @@
-(function(a){function b(a){return a}function c(a,b){for(var c=0,d=b.length,e=new Array(d);c<d;++c)e[c]=a[b[c]];return e}function e(a){function b(b,c,d,e){while(d<e){var f=d+e>>1;a(b[f])<c?d=f+1:e=f}return d}function c(b,c,d,e){while(d<e){var f=d+e>>1;c<a(b[f])?e=f:d=f+1}return d}return c.right=c,c.left=b,c}function h(a){function b(a,b,c){var e=c-b,f=(e>>>1)+1;while(--f>0)d(a,f,e,b);return a}function c(a,b,c){var e=c-b,f;while(--e>0)f=a[b],a[b]=a[b+e],a[b+e]=f,d(a,1,e,b);return a}function d(b,c,d,e){var f=b[--e+c],g=a(f),h;while((h=c<<1)<=d){h<d&&a(b[e+h])>a(b[e+h+1])&&h++;if(g<=a(b[e+h]))break;b[e+c]=b[e+h],c=h}b[e+c]=f}return b.sort=c,b}function j(a){function c(c,d,e,f){var g=new Array(f=Math.min(e-d,f)),h,i,j,k;for(i=0;i<f;++i)g[i]=c[d++];b(g,0,f);if(d<e){h=a(g[0]);do if(j=a(k=c[d])>h)g[0]=k,h=a(b(g,0,f)[0]);while(++d<e)}return g}var b=h(a);return c}function l(a){function b(b,c,d){for(var e=c+1;e<d;++e){for(var f=e,g=b[e],h=a(g);f>c&&a(b[f-1])>h;--f)b[f]=b[f-1];b[f]=g}return b}return b}function n(a){function c(a,c,e){return(e-c<o?b:d)(a,c,e)}function d(b,d,e){var f=(e-d)/6|0,g=d+f,h=e-1-f,i=d+e-1>>1,j=i-f,k=i+f,l=b[g],m=a(l),n=b[j],o=a(n),p=b[i],q=a(p),r=b[k],s=a(r),u=b[h],v=a(u);m>o&&(t=l,l=n,n=t,t=m,m=o,o=t),s>v&&(t=r,r=u,u=t,t=s,s=v,v=t),m>q&&(t=l,l=p,p=t,t=m,m=q,q=t),o>q&&(t=n,n=p,p=t,t=o,o=q,q=t),m>s&&(t=l,l=r,r=t,t=m,m=s,s=t),q>s&&(t=p,p=r,r=t,t=q,q=s,s=t),o>v&&(t=n,n=u,u=t,t=o,o=v,v=t),o>q&&(t=n,n=p,p=t,t=o,o=q,q=t),s>v&&(t=r,r=u,u=t,t=s,s=v,v=t);var w=n,x=o,y=r,z=s;b[g]=l,b[j]=b[d],b[i]=p,b[k]=b[e-1],b[h]=u;var A=d+1,B=e-2,C=x<=z&&x>=z;if(C)for(var D=A;D<=B;++D){var E=b[D],F=a(E);if(F<x)D!==A&&(b[D]=b[A],b[A]=E),++A;else if(F>x)for(;;){var G=a(b[B]);if(G>x){B--;continue}if(G<x){b[D]=b[A],b[A++]=b[B],b[B--]=E;break}b[D]=b[B],b[B--]=E;break}}else for(var D=A;D<=B;D++){var E=b[D],F=a(E);if(F<x)D!==A&&(b[D]=b[A],b[A]=E),++A;else if(F>z)for(;;){var G=a(b[B]);if(G>z){B--;if(B<D)break;continue}G<x?(b[D]=b[A],b[A++]=b[B],b[B--]=E):(b[D]=b[B],b[B--]=E);break}}b[d]=b[A-1],b[A-1]=w,b[e-1]=b[B+1],b[B+1]=y,c(b,d,A-1),c(b,B+2,e);if(C)return b;if(A<g&&B>h){var H,G;while((H=a(b[A]))<=x&&H>=x)++A;while((G=a(b[B]))<=z&&G>=z)--B;for(var D=A;D<=B;D++){var E=b[D],F=a(E);if(F<=x&&F>=x)D!==A&&(b[D]=b[A],b[A]=E),A++;else if(F<=z&&F>=z)for(;;){var G=a(b[B]);if(G<=z&&G>=z){B--;if(B<D)break;continue}G<x?(b[D]=b[A],b[A++]=b[B],b[B--]=E):(b[D]=b[B],b[B--]=E);break}}}return c(b,A,B+1)}var b=l(a);return c}function v(a){return new Array(a)}function w(a,b){return function(c){var d=c.length;return[a.left(c,b,0,d),a.right(c,b,0,d)]}}function x(a,b){var c=b[0],d=b[1];return function(b){var e=b.length;return[a.left(b,c,0,e),a.left(b,d,0,e)]}}function y(a){return[0,a.length]}function z(){return null}function A(){return 0}function B(a){return a+1}function C(a){return a-1}function D(a){return function(b,c){return b+ +a(c)}}function E(a){return function(b,c){return b-a(c)}}function F(){function q(b){var c=f,d=b.length;return d&&(e=e.concat(b),l=s(l,f+=d),o.forEach(function(a){a(b,c,d)})),a}function r(a){function Q(b,d,e){F=b.map(a),J=K(H(e),0,e),F=c(F,J);var g=L(F),h=g[0],i=g[1],j;for(j=0;j<h;++j)l[J[j]+d]|=q;for(j=i;j<e;++j)l[J[j]+d]|=q;if(!d){t=F,v=J,O=h,P=i;return}var k=t,m=v,n=0,o=0;t=new Array(f),v=G(f,f);for(j=0;n<d&&o<e;++j)k[n]<F[o]?(t[j]=k[n],v[j]=m[n++]):(t[j]=F[o],v[j]=J[o++]+d);for(;n<d;++n,++j)t[j]=k[n],v[j]=m[n];for(;o<e;++o,++j)t[j]=F[o],v[j]=J[o]+d;g=L(t),O=g[0],P=g[1]}function R(a,b,c){N.forEach(function(a){a(F,J,b,c)}),F=J=null}function S(a){var b,c,d,e=a[0],f=a[1],g=[],h=[];if(e<O)for(b=e,c=Math.min(O,f);b<c;++b)l[d=v[b]]^=q,g.push(d);else if(e>O)for(b=O,c=Math.min(e,P);b<c;++b)l[d=v[b]]^=q,h.push(d);if(f>P)for(b=Math.max(e,P),c=f;b<c;++b)l[d=v[b]]^=q,g.push(d);else if(f<P)for(b=Math.max(O,f),c=P;b<c;++b)l[d=v[b]]^=q,h.push(d);return O=e,P=f,m.forEach(function(a){a(q,g,h)}),p}function T(a){return a==null?W():Array.isArray(a)?V(a):U(a)}function U(a){return S((L=w(d,a))(t))}function V(a){return S((L=x(d,a))(t))}function W(){return S((L=y)(t))}function X(a){var b=[],c=P,d;while(--c>=O&&a>0)l[d=v[c]]||(b.push(e[d]),--a);return b}function Y(a){function L(b,c,g,h){function N(){++o===n&&(p=u(p,k<<=1),i=u(i,k),n=I(k))}var j=d,p=G(o,n),q=x,t=F,v=o,w=0,y=0,A,B,C,D,E,L;K&&(q=t=z),d=new Array(o),o=0,i=v>1?s(i,f):G(f,n),v&&(C=(B=j[0]).key);while(y<h&&!((D=a(b[y]))>=D))++y;while(y<h){if(B&&C<=D){E=B,L=C,p[w]=o;if(B=j[++w])C=B.key}else E={key:D,value:t()},L=D;d[o]=E;while(!(D>L)){i[A=c[y]+g]=o,l[A]&r||(E.value=q(E.value,e[A]));if(++y>=h)break;D=a(b[y])}N()}while(w<v)d[p[w]=o]=j[w++],N();if(o>w)for(w=0;w<g;++w)i[w]=p[i[w]];A=m.indexOf(H),o>1?(H=M,J=P):(o===1?(H=O,J=Q):(H=z,J=z),i=null),m[A]=H}function M(a,b,c){if(a===q||K)return;var f,h,j;for(f=0,j=b.length;f<j;++f)l[h=b[f]]&r||(g=d[i[h]],g.value=x(g.value,e[h]));for(f=0,j=c.length;f<j;++f)(l[h=c[f]]&r)===a&&(g=d[i[h]],g.value=y(g.value,e[h]))}function O(a,b,c){if(a===q||K)return;var f,g,h,i=d[0];for(f=0,h=b.length;f<h;++f)l[g=b[f]]&r||(i.value=x(i.value,e[g]));for(f=0,h=c.length;f<h;++f)(l[g=c[f]]&r)===a&&(i.value=y(i.value,e[g]))}function P(){var a,b;for(a=0;a<o;++a)d[a].value=F();for(a=0;a<f;++a)l[a]&r||(b=d[i[a]],b.value=x(b.value,e[a]))}function Q(){var a,b=d[0];b.value=F();for(a=0;a<f;++a)l[a]&r||(b.value=x(b.value,e[a]))}function R(){return K&&(J(),K=!1),d}function S(a){var b=p(R(),0,d.length,a);return w.sort(b,0,b.length)}function T(a,b,d){return x=a,y=b,F=d,K=!0,c}function U(){return T(B,C,A)}function V(a){return T(D(a),E(a),A)}function W(a){function b(b){return a(b.value)}return p=j(b),w=h(b),c}function X(){return W(b)}function Y(){return o}var c={top:S,all:R,reduce:T,reduceCount:U,reduceSum:V,order:W,orderNatural:X,size:Y},d,i,k=8,n=I(k),o=0,p,w,x,y,F,H=z,J=z,K=!0;return arguments.length<1&&(a=b),m.push(H),N.push(L),L(t,v,0,f),U().orderNatural()}function Z(){var a=Y(z),b=a.all;return delete a.all,delete a.top,delete a.order,delete a.orderNatural,delete a.size,a.value=function(){return b()[0].value},a}var p={filter:T,filterExact:U,filterRange:V,filterAll:W,top:X,group:Y,groupAll:Z},q=1<<i++,r=~q,t,v,F,J,K=n(function(a){return F[a]}),L=y,N=[],O=0,P=0;return o.unshift(Q),o.push(R),i>k&&(l=u(l,k<<=1)),Q(e,0,f),R(e,0,f),p}function t(){function i(a,d,g){var i;if(h)return;for(i=d;i<f;++i)l[i]||(b=c(b,e[i]))}function j(a,f,g){var i,j,k;if(h)return;for(i=0,k=f.length;i<k;++i)l[j=f[i]]||(b=c(b,e[j]));for(i=0,k=g.length;i<k;++i)l[j=g[i]]===a&&(b=d(b,e[j]))}function k(){var a;b=g();for(a=0;a<f;++a)l[a]||(b=c(b,e[a]))}function n(b,e,f){return c=b,d=e,g=f,h=!0,a}function p(){return n(B,C,A)}function q(a){return n(D(a),E(a),A)}function r(){return h&&(k(),h=!1),b}var a={reduce:n,reduceCount:p,reduceSum:q,value:r},b,c,d,g,h=!0;return m.push(j),o.push(i),i(e,0,f),p()}function v(){return f}var a={add:q,dimension:r,groupAll:t,size:v},e=[],f=0,i=0,k=8,l=p(0),m=[],o=[];return arguments.length?q(arguments[0]):a}function G(a,b){return(b<257?p:b<65537?q:r)(a)}function H(a){var b=G(a,a);for(var c=-1;++c<a;)b[c]=c;return b}function I(a){return a===8?256:a===16?65536:4294967296}F.version="1.0.1",F.permute=c;var d=F.bisect=e(b);d.by=e;var f=F.heap=h(b);f.by=h;var i=F.heapselect=j(b);i.by=j;var k=F.insertionsort=l(b);k.by=l;var m=F.quicksort=n(b);m.by=n;var o=32,p=v,q=v,r=v,s=b,u=b;typeof Uint8Array!="undefined"&&(p=function(a){return new Uint8Array(a)},q=function(a){return new Uint16Array(a)},r=function(a){return new Uint32Array(a)},s=function(a,b){var c=new a.constructor(b);return c.set(a),c},u=function(a,b){var c;switch(b){case 16:c=q(a.length);break;case 32:c=r(a.length);break;default:throw new Error("invalid array width!")}return c.set(a),c}),a.tesseract=F})(this);
+(function(a){function b(a){return a}function c(a,b){for(var c=0,d=b.length,e=new Array(d);c<d;++c)e[c]=a[b[c]];return e}function e(a){function b(b,c,d,e){while(d<e){var f=d+e>>1;a(b[f])<c?d=f+1:e=f}return d}function c(b,c,d,e){while(d<e){var f=d+e>>1;c<a(b[f])?e=f:d=f+1}return d}return c.right=c,c.left=b,c}function h(a){function b(a,b,c){var e=c-b,f=(e>>>1)+1;while(--f>0)d(a,f,e,b);return a}function c(a,b,c){var e=c-b,f;while(--e>0)f=a[b],a[b]=a[b+e],a[b+e]=f,d(a,1,e,b);return a}function d(b,c,d,e){var f=b[--e+c],g=a(f),h;while((h=c<<1)<=d){h<d&&a(b[e+h])>a(b[e+h+1])&&h++;if(g<=a(b[e+h]))break;b[e+c]=b[e+h],c=h}b[e+c]=f}return b.sort=c,b}function j(a){function c(c,d,e,f){var g=new Array(f=Math.min(e-d,f)),h,i,j,k;for(i=0;i<f;++i)g[i]=c[d++];b(g,0,f);if(d<e){h=a(g[0]);do if(j=a(k=c[d])>h)g[0]=k,h=a(b(g,0,f)[0]);while(++d<e)}return g}var b=h(a);return c}function l(a){function b(b,c,d){for(var e=c+1;e<d;++e){for(var f=e,g=b[e],h=a(g);f>c&&a(b[f-1])>h;--f)b[f]=b[f-1];b[f]=g}return b}return b}function n(a){function c(a,c,e){return(e-c<o?b:d)(a,c,e)}function d(b,d,e){var f=(e-d)/6|0,g=d+f,h=e-1-f,i=d+e-1>>1,j=i-f,k=i+f,l=b[g],m=a(l),n=b[j],o=a(n),p=b[i],q=a(p),r=b[k],s=a(r),u=b[h],v=a(u);m>o&&(t=l,l=n,n=t,t=m,m=o,o=t),s>v&&(t=r,r=u,u=t,t=s,s=v,v=t),m>q&&(t=l,l=p,p=t,t=m,m=q,q=t),o>q&&(t=n,n=p,p=t,t=o,o=q,q=t),m>s&&(t=l,l=r,r=t,t=m,m=s,s=t),q>s&&(t=p,p=r,r=t,t=q,q=s,s=t),o>v&&(t=n,n=u,u=t,t=o,o=v,v=t),o>q&&(t=n,n=p,p=t,t=o,o=q,q=t),s>v&&(t=r,r=u,u=t,t=s,s=v,v=t);var w=n,x=o,y=r,z=s;b[g]=l,b[j]=b[d],b[i]=p,b[k]=b[e-1],b[h]=u;var A=d+1,B=e-2,C=x<=z&&x>=z;if(C)for(var D=A;D<=B;++D){var E=b[D],F=a(E);if(F<x)D!==A&&(b[D]=b[A],b[A]=E),++A;else if(F>x)for(;;){var G=a(b[B]);if(G>x){B--;continue}if(G<x){b[D]=b[A],b[A++]=b[B],b[B--]=E;break}b[D]=b[B],b[B--]=E;break}}else for(var D=A;D<=B;D++){var E=b[D],F=a(E);if(F<x)D!==A&&(b[D]=b[A],b[A]=E),++A;else if(F>z)for(;;){var G=a(b[B]);if(G>z){B--;if(B<D)break;continue}G<x?(b[D]=b[A],b[A++]=b[B],b[B--]=E):(b[D]=b[B],b[B--]=E);break}}b[d]=b[A-1],b[A-1]=w,b[e-1]=b[B+1],b[B+1]=y,c(b,d,A-1),c(b,B+2,e);if(C)return b;if(A<g&&B>h){var H,G;while((H=a(b[A]))<=x&&H>=x)++A;while((G=a(b[B]))<=z&&G>=z)--B;for(var D=A;D<=B;D++){var E=b[D],F=a(E);if(F<=x&&F>=x)D!==A&&(b[D]=b[A],b[A]=E),A++;else if(F<=z&&F>=z)for(;;){var G=a(b[B]);if(G<=z&&G>=z){B--;if(B<D)break;continue}G<x?(b[D]=b[A],b[A++]=b[B],b[B--]=E):(b[D]=b[B],b[B--]=E);break}}}return c(b,A,B+1)}var b=l(a);return c}function v(a){return new Array(a)}function w(a,b){return function(c){var d=c.length;return[a.left(c,b,0,d),a.right(c,b,0,d)]}}function x(a,b){var c=b[0],d=b[1];return function(b){var e=b.length;return[a.left(b,c,0,e),a.left(b,d,0,e)]}}function y(a){return[0,a.length]}function z(){return null}function A(){return 0}function B(a){return a+1}function C(a){return a-1}function D(a){return function(b,c){return b+ +a(c)}}function E(a){return function(b,c){return b-a(c)}}function F(){function q(b){var c=f,d=b.length;return d&&(e=e.concat(b),l=s(l,f+=d),o.forEach(function(a){a(b,c,d)})),a}function r(a){function Q(b,d,e){F=b.map(a),J=K(H(e),0,e),F=c(F,J);var g=L(F),h=g[0],i=g[1],j;for(j=0;j<h;++j)l[J[j]+d]|=q;for(j=i;j<e;++j)l[J[j]+d]|=q;if(!d){t=F,v=J,O=h,P=i;return}var k=t,m=v,n=0,o=0;t=new Array(f),v=G(f,f);for(j=0;n<d&&o<e;++j)k[n]<F[o]?(t[j]=k[n],v[j]=m[n++]):(t[j]=F[o],v[j]=J[o++]+d);for(;n<d;++n,++j)t[j]=k[n],v[j]=m[n];for(;o<e;++o,++j)t[j]=F[o],v[j]=J[o]+d;g=L(t),O=g[0],P=g[1]}function R(a,b,c){N.forEach(function(a){a(F,J,b,c)}),F=J=null}function S(a){var b,c,d,e=a[0],f=a[1],g=[],h=[];if(e<O)for(b=e,c=Math.min(O,f);b<c;++b)l[d=v[b]]^=q,g.push(d);else if(e>O)for(b=O,c=Math.min(e,P);b<c;++b)l[d=v[b]]^=q,h.push(d);if(f>P)for(b=Math.max(e,P),c=f;b<c;++b)l[d=v[b]]^=q,g.push(d);else if(f<P)for(b=Math.max(O,f),c=P;b<c;++b)l[d=v[b]]^=q,h.push(d);return O=e,P=f,m.forEach(function(a){a(q,g,h)}),p}function T(a){return a==null?W():Array.isArray(a)?V(a):U(a)}function U(a){return S((L=w(d,a))(t))}function V(a){return S((L=x(d,a))(t))}function W(){return S((L=y)(t))}function X(a){var b=[],c=P,d;while(--c>=O&&a>0)l[d=v[c]]||(b.push(e[d]),--a);return b}function Y(a){function L(b,c,g,h){function N(){++o===n&&(p=u(p,k<<=1),i=u(i,k),n=I(k))}var j=d,p=G(o,n),q=x,t=F,v=o,w=0,y=0,A,B,C,D,E,L;K&&(q=t=z),d=new Array(o),o=0,i=v>1?s(i,f):G(f,n),v&&(C=(B=j[0]).key);while(y<h&&!((D=a(b[y]))>=D))++y;while(y<h){if(B&&C<=D){E=B,L=C,p[w]=o;if(B=j[++w])C=B.key}else E={key:D,value:t()},L=D;d[o]=E;while(!(D>L)){i[A=c[y]+g]=o,l[A]&r||(E.value=q(E.value,e[A]));if(++y>=h)break;D=a(b[y])}N()}while(w<v)d[p[w]=o]=j[w++],N();if(o>w)for(w=0;w<g;++w)i[w]=p[i[w]];A=m.indexOf(H),o>1?(H=M,J=P):(o===1?(H=O,J=Q):(H=z,J=z),i=null),m[A]=H}function M(a,b,c){if(a===q||K)return;var f,h,j;for(f=0,j=b.length;f<j;++f)l[h=b[f]]&r||(g=d[i[h]],g.value=x(g.value,e[h]));for(f=0,j=c.length;f<j;++f)(l[h=c[f]]&r)===a&&(g=d[i[h]],g.value=y(g.value,e[h]))}function O(a,b,c){if(a===q||K)return;var f,g,h,i=d[0];for(f=0,h=b.length;f<h;++f)l[g=b[f]]&r||(i.value=x(i.value,e[g]));for(f=0,h=c.length;f<h;++f)(l[g=c[f]]&r)===a&&(i.value=y(i.value,e[g]))}function P(){var a,b;for(a=0;a<o;++a)d[a].value=F();for(a=0;a<f;++a)l[a]&r||(b=d[i[a]],b.value=x(b.value,e[a]))}function Q(){var a,b=d[0];b.value=F();for(a=0;a<f;++a)l[a]&r||(b.value=x(b.value,e[a]))}function R(){return K&&(J(),K=!1),d}function S(a){var b=p(R(),0,d.length,a);return w.sort(b,0,b.length)}function T(a,b,d){return x=a,y=b,F=d,K=!0,c}function U(){return T(B,C,A)}function V(a){return T(D(a),E(a),A)}function W(a){function b(b){return a(b.value)}return p=j(b),w=h(b),c}function X(){return W(b)}function Y(){return o}var c={top:S,all:R,reduce:T,reduceCount:U,reduceSum:V,order:W,orderNatural:X,size:Y},d,i,k=8,n=I(k),o=0,p,w,x,y,F,H=z,J=z,K=!0;return arguments.length<1&&(a=b),m.push(H),N.push(L),L(t,v,0,f),U().orderNatural()}function Z(){var a=Y(z),b=a.all;return delete a.all,delete a.top,delete a.order,delete a.orderNatural,delete a.size,a.value=function(){return b()[0].value},a}var p={filter:T,filterExact:U,filterRange:V,filterAll:W,top:X,group:Y,groupAll:Z},q=1<<i++,r=~q,t,v,F,J,K=n(function(a){return F[a]}),L=y,N=[],O=0,P=0;return o.unshift(Q),o.push(R),i>k&&(l=u(l,k<<=1)),Q(e,0,f),R(e,0,f),p}function t(){function i(a,d,g){var i;if(h)return;for(i=d;i<f;++i)l[i]||(b=c(b,e[i]))}function j(a,f,g){var i,j,k;if(h)return;for(i=0,k=f.length;i<k;++i)l[j=f[i]]||(b=c(b,e[j]));for(i=0,k=g.length;i<k;++i)l[j=g[i]]===a&&(b=d(b,e[j]))}function k(){var a;b=g();for(a=0;a<f;++a)l[a]||(b=c(b,e[a]))}function n(b,e,f){return c=b,d=e,g=f,h=!0,a}function p(){return n(B,C,A)}function q(a){return n(D(a),E(a),A)}function r(){return h&&(k(),h=!1),b}var a={reduce:n,reduceCount:p,reduceSum:q,value:r},b,c,d,g,h=!0;return m.push(j),o.push(i),i(e,0,f),p()}function v(){return f}var a={add:q,dimension:r,groupAll:t,size:v},e=[],f=0,i=0,k=8,l=p(0),m=[],o=[];return arguments.length?q(arguments[0]):a}function G(a,b){return(b<257?p:b<65537?q:r)(a)}function H(a){var b=G(a,a);for(var c=-1;++c<a;)b[c]=c;return b}function I(a){return a===8?256:a===16?65536:4294967296}F.version="1.0.2",F.permute=c;var d=F.bisect=e(b);d.by=e;var f=F.heap=h(b);f.by=h;var i=F.heapselect=j(b);i.by=j;var k=F.insertionsort=l(b);k.by=l;var m=F.quicksort=n(b);m.by=n;var o=32,p=v,q=v,r=v,s=b,u=b;typeof Uint8Array!="undefined"&&(p=function(a){return new Uint8Array(a)},q=function(a){return new Uint16Array(a)},r=function(a){return new Uint32Array(a)},s=function(a,b){var c=new a.constructor(b);return c.set(a),c},u=function(a,b){var c;switch(b){case 16:c=q(a.length);break;case 32:c=r(a.length);break;default:throw new Error("invalid array width!")}return c.set(a),c}),a.crossfilter=F})(this);
View
2  index.js
@@ -1 +1 @@
-module.exports = require("./tesseract").tesseract;
+module.exports = require("./crossfilter").crossfilter;
View
4 package.json
@@ -1,6 +1,6 @@
{
- "name": "tesseract",
- "version": "1.0.1",
+ "name": "crossfilter",
+ "version": "1.0.2",
"private": true,
"main": "./index.js",
"devDependencies": {
View
26 src/array.js
@@ -1,25 +1,25 @@
-var tesseract_array8 = tesseract_arrayUntyped,
- tesseract_array16 = tesseract_arrayUntyped,
- tesseract_array32 = tesseract_arrayUntyped,
- tesseract_arrayLengthen = tesseract_identity,
- tesseract_arrayWiden = tesseract_identity;
+var crossfilter_array8 = crossfilter_arrayUntyped,
+ crossfilter_array16 = crossfilter_arrayUntyped,
+ crossfilter_array32 = crossfilter_arrayUntyped,
+ crossfilter_arrayLengthen = crossfilter_identity,
+ crossfilter_arrayWiden = crossfilter_identity;
if (typeof Uint8Array !== "undefined") {
- tesseract_array8 = function(n) { return new Uint8Array(n); };
- tesseract_array16 = function(n) { return new Uint16Array(n); };
- tesseract_array32 = function(n) { return new Uint32Array(n); };
+ crossfilter_array8 = function(n) { return new Uint8Array(n); };
+ crossfilter_array16 = function(n) { return new Uint16Array(n); };
+ crossfilter_array32 = function(n) { return new Uint32Array(n); };
- tesseract_arrayLengthen = function(array, length) {
+ crossfilter_arrayLengthen = function(array, length) {
var copy = new array.constructor(length);
copy.set(array);
return copy;
};
- tesseract_arrayWiden = function(array, width) {
+ crossfilter_arrayWiden = function(array, width) {
var copy;
switch (width) {
- case 16: copy = tesseract_array16(array.length); break;
- case 32: copy = tesseract_array32(array.length); break;
+ case 16: copy = crossfilter_array16(array.length); break;
+ case 32: copy = crossfilter_array32(array.length); break;
default: throw new Error("invalid array width!");
}
copy.set(array);
@@ -27,6 +27,6 @@ if (typeof Uint8Array !== "undefined") {
};
}
-function tesseract_arrayUntyped(n) {
+function crossfilter_arrayUntyped(n) {
return new Array(n);
}
View
2  src/bisect.js
@@ -1,4 +1,4 @@
-var bisect = tesseract.bisect = bisect_by(tesseract_identity);
+var bisect = crossfilter.bisect = bisect_by(crossfilter_identity);
bisect.by = bisect_by;
View
86 src/tesseract.js → src/crossfilter.js
@@ -1,7 +1,7 @@
-exports.tesseract = tesseract;
+exports.crossfilter = crossfilter;
-function tesseract() {
- var tesseract = {
+function crossfilter() {
+ var crossfilter = {
add: add,
dimension: dimension,
groupAll: groupAll,
@@ -12,11 +12,11 @@ function tesseract() {
n = 0, // the number of records; data.length
m = 0, // number of dimensions in use
M = 8, // number of dimensions that can fit in `filters`
- filters = tesseract_array8(0), // M bits per record; 1 is filtered out
+ filters = crossfilter_array8(0), // M bits per record; 1 is filtered out
filterListeners = [], // when the filters change
dataListeners = []; // when data is added
- // Adds the specified new records to this tesseract.
+ // Adds the specified new records to this crossfilter.
function add(newData) {
var n0 = n,
n1 = newData.length;
@@ -27,11 +27,11 @@ function tesseract() {
// Notify listeners (dimensions and groups) that new data is available.
if (n1) {
data = data.concat(newData);
- filters = tesseract_arrayLengthen(filters, n += n1);
+ filters = crossfilter_arrayLengthen(filters, n += n1);
dataListeners.forEach(function(l) { l(newData, n0, n1); });
}
- return tesseract;
+ return crossfilter;
}
// Adds a new dimension with the specified value accessor function.
@@ -53,7 +53,7 @@ function tesseract() {
newValues, // temporary array storing newly-added values
newIndex, // temporary array storing newly-added index
sort = quicksort_by(function(i) { return newValues[i]; }),
- refilter = tesseract_filterAll, // for recomputing filter
+ refilter = crossfilter_filterAll, // for recomputing filter
indexListeners = [], // when data is added
lo0 = 0,
hi0 = 0;
@@ -66,7 +66,7 @@ function tesseract() {
// Incorporate any existing data into this dimension, and make sure that the
// filter bitset is wide enough to handle the new dimension.
- if (m > M) filters = tesseract_arrayWiden(filters, M <<= 1);
+ if (m > M) filters = crossfilter_arrayWiden(filters, M <<= 1);
preAdd(data, 0, n);
postAdd(data, 0, n);
@@ -76,7 +76,7 @@ function tesseract() {
// Permute new values into natural order using a sorted index.
newValues = newData.map(value);
- newIndex = sort(tesseract_range(n1), 0, n1);
+ newIndex = sort(crossfilter_range(n1), 0, n1);
newValues = permute(newValues, newIndex);
// Bisect newValues to determine which new records are selected.
@@ -101,7 +101,7 @@ function tesseract() {
// Otherwise, create new arrays into which to merge new and old.
values = new Array(n);
- index = tesseract_index(n, n);
+ index = crossfilter_index(n, n);
// Merge the old and new sorted values, and old and new index.
for (i = 0; i0 < n0 && i1 < n1; ++i) {
@@ -192,18 +192,18 @@ function tesseract() {
// Filters this dimension to select the exact value.
function filterExact(value) {
- return filterIndex((refilter = tesseract_filterExact(bisect, value))(values));
+ return filterIndex((refilter = crossfilter_filterExact(bisect, value))(values));
}
// Filters this dimension to select the specified range [lo, hi].
// The lower bound is inclusive, and the upper bound is exclusive.
function filterRange(range) {
- return filterIndex((refilter = tesseract_filterRange(bisect, range))(values));
+ return filterIndex((refilter = crossfilter_filterRange(bisect, range))(values));
}
// Clears any filters on this dimension.
function filterAll() {
- return filterIndex((refilter = tesseract_filterAll)(values));
+ return filterIndex((refilter = crossfilter_filterAll)(values));
}
// Returns the top K selected records, based on this dimension's order.
@@ -239,20 +239,20 @@ function tesseract() {
var groups, // array of {key, value}
groupIndex, // object id ↦ group id
groupWidth = 8,
- groupCapacity = tesseract_capacity(groupWidth),
+ groupCapacity = crossfilter_capacity(groupWidth),
k = 0, // cardinality
select,
heap,
reduceAdd,
reduceRemove,
reduceInitial,
- update = tesseract_null,
- reset = tesseract_null,
+ update = crossfilter_null,
+ reset = crossfilter_null,
resetNeeded = true;
- if (arguments.length < 1) key = tesseract_identity;
+ if (arguments.length < 1) key = crossfilter_identity;
- // The group listens to the tesseract for when any dimension changes, so
+ // The group listens to the crossfilter for when any dimension changes, so
// that it can update the associated reduce values. It must also listen to
// the parent dimension for when data is added, and compute new keys.
filterListeners.push(update);
@@ -265,7 +265,7 @@ function tesseract() {
// This function is responsible for updating groups and groupIndex.
function add(newValues, newIndex, n0, n1) {
var oldGroups = groups,
- reIndex = tesseract_index(k, groupCapacity),
+ reIndex = crossfilter_index(k, groupCapacity),
add = reduceAdd,
initial = reduceInitial,
k0 = k, // old cardinality
@@ -279,12 +279,12 @@ function tesseract() {
x; // key of group to add
// If a reset is needed, we don't need to update the reduce values.
- if (resetNeeded) add = initial = tesseract_null;
+ if (resetNeeded) add = initial = crossfilter_null;
// Reset the new groups (k is a lower bound).
// Also, make sure that groupIndex exists and is long enough.
groups = new Array(k), k = 0;
- groupIndex = k0 > 1 ? tesseract_arrayLengthen(groupIndex, n) : tesseract_index(n, groupCapacity);
+ groupIndex = k0 > 1 ? crossfilter_arrayLengthen(groupIndex, n) : crossfilter_index(n, groupCapacity);
// Get the first old key (x0 of g0), if it exists.
if (k0) x0 = (g0 = oldGroups[0]).key;
@@ -352,8 +352,8 @@ function tesseract() {
update = updateOne;
reset = resetOne;
} else {
- update = tesseract_null;
- reset = tesseract_null;
+ update = crossfilter_null;
+ reset = crossfilter_null;
}
groupIndex = null;
}
@@ -363,9 +363,9 @@ function tesseract() {
// and widen the group index as needed.
function groupIncrement() {
if (++k === groupCapacity) {
- reIndex = tesseract_arrayWiden(reIndex, groupWidth <<= 1);
- groupIndex = tesseract_arrayWiden(groupIndex, groupWidth);
- groupCapacity = tesseract_capacity(groupWidth);
+ reIndex = crossfilter_arrayWiden(reIndex, groupWidth <<= 1);
+ groupIndex = crossfilter_arrayWiden(groupIndex, groupWidth);
+ groupCapacity = crossfilter_capacity(groupWidth);
}
}
}
@@ -482,12 +482,12 @@ function tesseract() {
// A convenience method for reducing by count.
function reduceCount() {
- return reduce(tesseract_reduceIncrement, tesseract_reduceDecrement, tesseract_zero);
+ return reduce(crossfilter_reduceIncrement, crossfilter_reduceDecrement, crossfilter_zero);
}
// A convenience method for reducing by sum(value).
function reduceSum(value) {
- return reduce(tesseract_reduceAdd(value), tesseract_reduceSubtract(value), tesseract_zero);
+ return reduce(crossfilter_reduceAdd(value), crossfilter_reduceSubtract(value), crossfilter_zero);
}
// Sets the reduce order, using the specified accessor.
@@ -500,7 +500,7 @@ function tesseract() {
// A convenience method for natural ordering by reduce value.
function orderNatural() {
- return order(tesseract_identity);
+ return order(crossfilter_identity);
}
// Returns the cardinality of this group, irrespective of any filters.
@@ -513,7 +513,7 @@ function tesseract() {
// A convenience function for generating a singleton group.
function groupAll() {
- var g = group(tesseract_null), all = g.all;
+ var g = group(crossfilter_null), all = g.all;
delete g.all;
delete g.top;
delete g.order;
@@ -542,7 +542,7 @@ function tesseract() {
reduceInitial,
resetNeeded = true;
- // The group listens to the tesseract for when any dimension changes, so
+ // The group listens to the crossfilter for when any dimension changes, so
// that it can update the reduce value. It must also listen to the parent
// dimension for when data is added.
filterListeners.push(update);
@@ -613,12 +613,12 @@ function tesseract() {
// A convenience method for reducing by count.
function reduceCount() {
- return reduce(tesseract_reduceIncrement, tesseract_reduceDecrement, tesseract_zero);
+ return reduce(crossfilter_reduceIncrement, crossfilter_reduceDecrement, crossfilter_zero);
}
// A convenience method for reducing by sum(value).
function reduceSum(value) {
- return reduce(tesseract_reduceAdd(value), tesseract_reduceSubtract(value), tesseract_zero);
+ return reduce(crossfilter_reduceAdd(value), crossfilter_reduceSubtract(value), crossfilter_zero);
}
// Returns the computed reduce value.
@@ -630,32 +630,32 @@ function tesseract() {
return reduceCount();
}
- // Returns the number of records in this tesseract, irrespective of any filters.
+ // Returns the number of records in this crossfilter, irrespective of any filters.
function size() {
return n;
}
return arguments.length
? add(arguments[0])
- : tesseract;
+ : crossfilter;
}
// Returns an array of size n, big enough to store ids up to m.
-function tesseract_index(n, m) {
+function crossfilter_index(n, m) {
return (m < 0x101
- ? tesseract_array8 : m < 0x10001
- ? tesseract_array16
- : tesseract_array32)(n);
+ ? crossfilter_array8 : m < 0x10001
+ ? crossfilter_array16
+ : crossfilter_array32)(n);
}
// Constructs a new array of size n, with sequential values from 0 to n - 1.
-function tesseract_range(n) {
- var range = tesseract_index(n, n);
+function crossfilter_range(n) {
+ var range = crossfilter_index(n, n);
for (var i = -1; ++i < n;) range[i] = i;
return range;
}
-function tesseract_capacity(w) {
+function crossfilter_capacity(w) {
return w === 8
? 0x100 : w === 16
? 0x10000
View
6 src/filter.js
@@ -1,11 +1,11 @@
-function tesseract_filterExact(bisect, value) {
+function crossfilter_filterExact(bisect, value) {
return function(values) {
var n = values.length;
return [bisect.left(values, value, 0, n), bisect.right(values, value, 0, n)];
};
}
-function tesseract_filterRange(bisect, range) {
+function crossfilter_filterRange(bisect, range) {
var min = range[0],
max = range[1];
return function(values) {
@@ -14,6 +14,6 @@ function tesseract_filterRange(bisect, range) {
};
}
-function tesseract_filterAll(values) {
+function crossfilter_filterAll(values) {
return [0, values.length];
}
View
2  src/heap.js
@@ -1,4 +1,4 @@
-var heap = tesseract.heap = heap_by(tesseract_identity);
+var heap = crossfilter.heap = heap_by(crossfilter_identity);
heap.by = heap_by;
View
2  src/heapselect.js
@@ -1,4 +1,4 @@
-var heapselect = tesseract.heapselect = heapselect_by(tesseract_identity);
+var heapselect = crossfilter.heapselect = heapselect_by(crossfilter_identity);
heapselect.by = heapselect_by;
View
2  src/identity.js
@@ -1,3 +1,3 @@
-function tesseract_identity(d) {
+function crossfilter_identity(d) {
return d;
}
View
2  src/insertionsort.js
@@ -1,4 +1,4 @@
-var insertionsort = tesseract.insertionsort = insertionsort_by(tesseract_identity);
+var insertionsort = crossfilter.insertionsort = insertionsort_by(crossfilter_identity);
insertionsort.by = insertionsort_by;
View
2  src/null.js
@@ -1,3 +1,3 @@
-function tesseract_null() {
+function crossfilter_null() {
return null;
}
View
6 src/package.js
@@ -1,9 +1,9 @@
var util = require("util"),
- tesseract = require("../tesseract").tesseract;
+ crossfilter = require("../crossfilter").crossfilter;
util.puts(JSON.stringify({
- "name": "tesseract",
- "version": tesseract.version,
+ "name": "crossfilter",
+ "version": crossfilter.version,
"private": true,
"main": "./index.js",
"devDependencies": {
View
2  src/permute.js
@@ -1,4 +1,4 @@
-tesseract.permute = permute;
+crossfilter.permute = permute;
function permute(array, index) {
for (var i = 0, n = index.length, copy = new Array(n); i < n; ++i) {
View
2  src/quicksort.js
@@ -1,7 +1,7 @@
// Algorithm designed by Vladimir Yaroslavskiy.
// Implementation based on the Dart project; see lib/dart/LICENSE for details.
-var quicksort = tesseract.quicksort = quicksort_by(tesseract_identity);
+var quicksort = crossfilter.quicksort = quicksort_by(crossfilter_identity);
quicksort.by = quicksort_by;
View
8 src/reduce.js
@@ -1,18 +1,18 @@
-function tesseract_reduceIncrement(p) {
+function crossfilter_reduceIncrement(p) {
return p + 1;
}
-function tesseract_reduceDecrement(p) {
+function crossfilter_reduceDecrement(p) {
return p - 1;
}
-function tesseract_reduceAdd(f) {
+function crossfilter_reduceAdd(f) {
return function(p, v) {
return p + +f(v);
};
}
-function tesseract_reduceSubtract(f) {
+function crossfilter_reduceSubtract(f) {
return function(p, v) {
return p - f(v);
};
View
2  src/version.js
@@ -1 +1 @@
-tesseract.version = "1.0.1";
+crossfilter.version = "1.0.2";
View
2  src/zero.js
@@ -1,3 +1,3 @@
-function tesseract_zero() {
+function crossfilter_zero() {
return 0;
}
View
6 test/benchmark.js
@@ -1,4 +1,4 @@
-var tesseract = require("../"),
+var crossfilter = require("../"),
d3 = require("d3");
var then,
@@ -31,9 +31,9 @@ console.log("Synthesizing " + formatNumber(totalSize) + " records: " + formatNum
var firstBatch = paymentRecords.slice(0, firstSize),
secondBatch = paymentRecords.slice(firstSize);
-// Create the tesseract and relevant dimensions and groups.
+// Create the crossfilter and relevant dimensions and groups.
then = then2 = Date.now();
-var payments = tesseract(firstBatch),
+var payments = crossfilter(firstBatch),
all = payments.groupAll(),
amount = payments.dimension(function(d) { return d.amount; }),
amounts = amount.group(Math.floor),
View
12 test/bisect-test.js
@@ -1,13 +1,13 @@
var vows = require("vows"),
assert = require("assert"),
- tesseract = require("../");
+ crossfilter = require("../");
var suite = vows.describe("bisect");
suite.addBatch({
"bisect": {
topic: function() {
- return tesseract.bisect;
+ return crossfilter.bisect;
},
"is the same as bisect.right": function(bisect) {
assert.strictEqual(bisect, bisect.right);
@@ -18,7 +18,7 @@ suite.addBatch({
suite.addBatch({
"bisect.left": {
topic: function() {
- return tesseract.bisect.left;
+ return crossfilter.bisect.left;
},
"finds the index of an exact match": function(bisect) {
var array = [1, 2, 3];
@@ -65,7 +65,7 @@ suite.addBatch({
suite.addBatch({
"bisect.by(value).left": {
topic: function() {
- return tesseract.bisect.by(function(d) { return d.value; }).left;
+ return crossfilter.bisect.by(function(d) { return d.value; }).left;
},
"finds the index of an exact match": function(bisect) {
var array = [{value: 1}, {value: 2}, {value: 3}];
@@ -112,7 +112,7 @@ suite.addBatch({
suite.addBatch({
"bisect.right": {
topic: function() {
- return tesseract.bisect.right;
+ return crossfilter.bisect.right;
},
"finds the index after an exact match": function(bisect) {
var array = [1, 2, 3];
@@ -159,7 +159,7 @@ suite.addBatch({
suite.addBatch({
"bisect.by(value).right": {
topic: function() {
- return tesseract.bisect.by(function(d) { return d.value; }).right;
+ return crossfilter.bisect.by(function(d) { return d.value; }).right;
},
"finds the index after an exact match": function(bisect) {
var array = [{value: 1}, {value: 2}, {value: 3}];
View
28 test/tesseract-test.js → test/crossfilter-test.js
@@ -1,14 +1,14 @@
var vows = require("vows"),
assert = require("assert"),
d3 = require("d3"),
- tesseract = require("../");
+ crossfilter = require("../");
-var suite = vows.describe("tesseract");
+var suite = vows.describe("crossfilter");
suite.addBatch({
- "tesseract": {
+ "crossfilter": {
topic: function() {
- var data = tesseract([
+ var data = 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"},
@@ -69,7 +69,7 @@ suite.addBatch({
},
"up to 32 dimensions supported": function() {
- var data = tesseract([]);
+ var data = crossfilter([]);
for (var i = 0; i < 32; i++) data.dimension(function() { return 0; });
assert.throws(function() { data.dimension(function() { return 0; }); }, Error);
},
@@ -391,7 +391,7 @@ suite.addBatch({
},
"cardinality may be greater than 256": function() {
- var data = tesseract(d3.range(256).concat(256, 256)),
+ var data = crossfilter(d3.range(256).concat(256, 256)),
index = data.dimension(function(d) { return d; }),
indexes = index.group();
assert.deepEqual(index.top(2), [256, 256]);
@@ -400,7 +400,7 @@ suite.addBatch({
},
"cardinality may be greater than 65536": function() {
- var data = tesseract(d3.range(65536).concat(65536, 65536)),
+ var data = crossfilter(d3.range(65536).concat(65536, 65536)),
index = data.dimension(function(d) { return d; }),
indexes = index.group();
assert.deepEqual(index.top(2), [65536, 65536]);
@@ -547,8 +547,8 @@ suite.addBatch({
},
"add": {
- "increases the size of the tesseract": function() {
- var data = tesseract([]);
+ "increases the size of the crossfilter": function() {
+ var data = crossfilter([]);
assert.equal(data.size(), 0);
data.add([0, 1, 2, 3, 4, 5, 6, 6, 6, 7]);
assert.equal(data.size(), 10);
@@ -556,7 +556,7 @@ suite.addBatch({
assert.equal(data.size(), 10);
},
"existing filters are consistent with new records": function(data) {
- var data = tesseract([]),
+ var data = crossfilter([]),
foo = data.dimension(function(d) { return +d; }),
bar = data.dimension(function(d) { return -d; });
assert.deepEqual(foo.top(Infinity), []);
@@ -582,7 +582,7 @@ suite.addBatch({
assert.deepEqual(bar.top(Infinity), [0, 41, 42, 42, 43, 43, 43, 43]);
},
"existing groups are consistent with new records": function(data) {
- var data = tesseract([]),
+ var data = crossfilter([]),
foo = data.dimension(function(d) { return +d; }),
bar = data.dimension(function(d) { return -d; }),
foos = foo.group(),
@@ -606,7 +606,7 @@ suite.addBatch({
assert.equal(all.value(), 6);
},
"can add new groups that are before existing groups": function(data) {
- var data = tesseract(),
+ var data = crossfilter(),
foo = data.dimension(function(d) { return +d; }),
foos = foo.group().reduce(add, remove, initial).order(order);
data.add([2]).add([1, 1, 1]);
@@ -617,7 +617,7 @@ suite.addBatch({
function initial() { return {foo: 0}; }
},
"can add more than 256 groups": function(data) {
- var data = tesseract(),
+ var data = crossfilter(),
foo = data.dimension(function(d) { return +d; }),
bar = data.dimension(function(d) { return +d; }),
foos = foo.group();
@@ -632,7 +632,7 @@ suite.addBatch({
assert.deepEqual(foos.top(1), [{key: 0, value: 1}]);
},
"can add lots of groups in reverse order": function(data) {
- var data = tesseract(),
+ var data = crossfilter(),
foo = data.dimension(function(d) { return -d.foo; }),
bar = data.dimension(function(d) { return d.bar; }),
foos = foo.group(Math.floor).reduceSum(function(d) { return d.foo; });
View
4 test/heap-test.js
@@ -1,13 +1,13 @@
var vows = require("vows"),
assert = require("assert"),
- tesseract = require("../");
+ crossfilter = require("../");
var suite = vows.describe("heap");
suite.addBatch({
"heap": {
topic: function() {
- return tesseract.heap;
+ return crossfilter.heap;
},
"children are greater than or equal to parents": function(heap) {
var array = [6, 5, 3, 1, 8, 7, 2, 4]
View
4 test/permute-test.js
@@ -1,13 +1,13 @@
var vows = require("vows"),
assert = require("assert"),
- tesseract = require("../");
+ crossfilter = require("../");
var suite = vows.describe("permute");
suite.addBatch({
"permute": {
topic: function() {
- return tesseract.permute;
+ return crossfilter.permute;
},
"permutes according to the specified index": function(permute) {
assert.deepEqual(permute([3, 4, 5], [2, 1, 0]), [5, 4, 3]);
View
4 test/select-test.js
@@ -1,11 +1,11 @@
var vows = require("vows"),
assert = require("assert"),
- tesseract = require("../");
+ crossfilter = require("../");
var suite = vows.describe("select");
suite.addBatch({
- "heapselect": batch(tesseract.heapselect)
+ "heapselect": batch(crossfilter.heapselect)
});
function batch(select, extras) {
View
6 test/sort-test.js
@@ -1,12 +1,12 @@
var vows = require("vows"),
assert = require("assert"),
- tesseract = require("../");
+ crossfilter = require("../");
var suite = vows.describe("sort");
suite.addBatch({
- "insertionsort": batch(tesseract.insertionsort),
- "quicksort": batch(tesseract.quicksort, {
+ "insertionsort": batch(crossfilter.insertionsort),
+ "quicksort": batch(crossfilter.quicksort, {
"can sort a largeish Uint32Array quickly": function(sort) {
var n = 1e6,
typedArray = new Uint32Array(n),
View
4 test/version-test.js
@@ -1,12 +1,12 @@
var vows = require("vows"),
assert = require("assert"),
- tesseract = require("../");
+ crossfilter = require("../");
var suite = vows.describe("version");
suite.addBatch({
"version": {
- topic: tesseract.version,
+ topic: crossfilter.version,
"has the form major.minor.patch": function(version) {
assert.match(version, /^[0-9]+\.[0-9]+\.[0-9]+$/);
}

2 comments on commit e46041d

@ciriarte

Why did you change the name Tesseract? I loved the name :(

Keep on the good work! It's an awesome project.

@mbostock
Collaborator

See #1. Thanks for the encouragement.

Please sign in to comment.
Something went wrong with that request. Please try again.