d3_rails 2.8.0 → 2.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/README.md +27 -5
- data/lib/d3_rails/version.rb +1 -1
- data/vendor/.DS_Store +0 -0
- data/vendor/assets/.DS_Store +0 -0
- data/vendor/assets/javascripts/.DS_Store +0 -0
- data/vendor/assets/javascripts/d3.v2.js +99 -80
- data/vendor/assets/javascripts/morris.js +1 -0
- data/vendor/assets/javascripts/morris/.DS_Store +0 -0
- data/vendor/assets/javascripts/morris/Makefile +10 -0
- data/vendor/assets/javascripts/morris/README.md +87 -0
- data/vendor/assets/javascripts/morris/examples/_template.html +18 -0
- data/vendor/assets/javascripts/morris/examples/days.html +36 -0
- data/vendor/assets/javascripts/morris/examples/decimal.html +31 -0
- data/vendor/assets/javascripts/morris/examples/lib/example.css +13 -0
- data/vendor/assets/javascripts/morris/examples/lib/example.js +4 -0
- data/vendor/assets/javascripts/morris/examples/lib/prettify.css +1 -0
- data/vendor/assets/javascripts/morris/examples/lib/prettify.js +28 -0
- data/vendor/assets/javascripts/morris/examples/months-no-smooth.html +37 -0
- data/vendor/assets/javascripts/morris/examples/negative.html +35 -0
- data/vendor/assets/javascripts/morris/examples/non-date.html +36 -0
- data/vendor/assets/javascripts/morris/examples/quarters.html +53 -0
- data/vendor/assets/javascripts/morris/examples/timestamps.html +37 -0
- data/vendor/assets/javascripts/morris/examples/weeks.html +52 -0
- data/vendor/assets/javascripts/morris/morris.coffee +444 -0
- data/vendor/assets/javascripts/morris/morris.js +493 -0
- data/vendor/assets/javascripts/morris/morris.min.js +1 -0
- data/vendor/assets/javascripts/tesseract.js +1 -0
- data/vendor/assets/javascripts/tesseract/.gitignore +2 -0
- data/vendor/assets/javascripts/tesseract/LICENSE +12 -0
- data/vendor/assets/javascripts/tesseract/Makefile +48 -0
- data/vendor/assets/javascripts/tesseract/README.md +11 -0
- data/vendor/assets/javascripts/tesseract/index.js +1 -0
- data/vendor/assets/javascripts/tesseract/lib/dart/AUTHORS +9 -0
- data/vendor/assets/javascripts/tesseract/lib/dart/LICENSE +25 -0
- data/vendor/assets/javascripts/tesseract/lib/dart/dual_pivot_quicksort.dart +342 -0
- data/vendor/assets/javascripts/tesseract/package.json +11 -0
- data/vendor/assets/javascripts/tesseract/src/array.js +32 -0
- data/vendor/assets/javascripts/tesseract/src/bisect.js +44 -0
- data/vendor/assets/javascripts/tesseract/src/filter.js +19 -0
- data/vendor/assets/javascripts/tesseract/src/heap.js +44 -0
- data/vendor/assets/javascripts/tesseract/src/heapselect.js +36 -0
- data/vendor/assets/javascripts/tesseract/src/identity.js +3 -0
- data/vendor/assets/javascripts/tesseract/src/insertionsort.js +18 -0
- data/vendor/assets/javascripts/tesseract/src/null.js +3 -0
- data/vendor/assets/javascripts/tesseract/src/package.js +14 -0
- data/vendor/assets/javascripts/tesseract/src/permute.js +8 -0
- data/vendor/assets/javascripts/tesseract/src/quicksort.js +282 -0
- data/vendor/assets/javascripts/tesseract/src/reduce.js +19 -0
- data/vendor/assets/javascripts/tesseract/src/tesseract.js +663 -0
- data/vendor/assets/javascripts/tesseract/src/version.js +1 -0
- data/vendor/assets/javascripts/tesseract/src/zero.js +3 -0
- data/vendor/assets/javascripts/tesseract/tesseract.js +1177 -0
- data/vendor/assets/javascripts/tesseract/tesseract.min.js +1 -0
- data/vendor/assets/javascripts/tesseract/test/benchmark.js +177 -0
- data/vendor/assets/javascripts/tesseract/test/bisect-test.js +206 -0
- data/vendor/assets/javascripts/tesseract/test/heap-test.js +44 -0
- data/vendor/assets/javascripts/tesseract/test/permute-test.js +51 -0
- data/vendor/assets/javascripts/tesseract/test/select-test.js +63 -0
- data/vendor/assets/javascripts/tesseract/test/sort-test.js +83 -0
- data/vendor/assets/javascripts/tesseract/test/tesseract-test.js +655 -0
- data/vendor/assets/javascripts/tesseract/test/version-test.js +16 -0
- metadata +63 -8
@@ -0,0 +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);
|
@@ -0,0 +1,177 @@
|
|
1
|
+
var tesseract = require("../"),
|
2
|
+
d3 = require("d3");
|
3
|
+
|
4
|
+
var then,
|
5
|
+
then2;
|
6
|
+
|
7
|
+
// Various generators for our synthetic dataset.
|
8
|
+
var firstSize = 9e4,
|
9
|
+
secondSize = 1e4,
|
10
|
+
totalSize = firstSize + secondSize,
|
11
|
+
randomDayOfWeek = randomIndex([0, .6, .7, .75, .8, .76, 0]),
|
12
|
+
randomHourOfDay = randomIndex([0, 0, 0, 0, 0, 0, 0, .2, .5, .7, .85, .9, .8, .69, .72, .8, .78, .7, .3, 0, 0, 0, 0, 0]),
|
13
|
+
randomDate = randomRecentDate(randomDayOfWeek, randomHourOfDay, 13),
|
14
|
+
randomAmount = randomLogNormal(2.5, .5),
|
15
|
+
randomPayment = function() { return {date: randomDate(), amount: randomAmount()}; };
|
16
|
+
|
17
|
+
// Various formatters to show our synthetic distributions.
|
18
|
+
var x = d3.scale.linear().rangeRound([0, 20]),
|
19
|
+
dayNames = ["S", "M", "T", "W", "T", "F", "S"],
|
20
|
+
formatNumber = d3.format(",.02r"),
|
21
|
+
formatInteger = d3.format("8d"),
|
22
|
+
formatDate = d3.time.format("%x"),
|
23
|
+
formatDay = function(i) { return dayNames[i]; };
|
24
|
+
|
25
|
+
// Create the synthetic records.
|
26
|
+
then = Date.now();
|
27
|
+
var paymentRecords = d3.range(totalSize).map(randomPayment);
|
28
|
+
console.log("Synthesizing " + formatNumber(totalSize) + " records: " + formatNumber(Date.now() - then) + "ms.");
|
29
|
+
|
30
|
+
// Slice the records into batches so we can measure incremental add.
|
31
|
+
var firstBatch = paymentRecords.slice(0, firstSize),
|
32
|
+
secondBatch = paymentRecords.slice(firstSize);
|
33
|
+
|
34
|
+
// Create the tesseract and relevant dimensions and groups.
|
35
|
+
then = then2 = Date.now();
|
36
|
+
var payments = tesseract(firstBatch),
|
37
|
+
all = payments.groupAll(),
|
38
|
+
amount = payments.dimension(function(d) { return d.amount; }),
|
39
|
+
amounts = amount.group(Math.floor),
|
40
|
+
date = payments.dimension(function(d) { return d.date; }),
|
41
|
+
dates = date.group(d3.time.day),
|
42
|
+
day = payments.dimension(function(d) { return d.date.getDay(); }),
|
43
|
+
days = day.group(),
|
44
|
+
hour = payments.dimension(function(d) { return d.date.getHours(); }),
|
45
|
+
hours = hour.group();
|
46
|
+
console.log("Indexing " + formatNumber(firstSize) + " records: " + formatNumber(Date.now() - then) + "ms.");
|
47
|
+
|
48
|
+
// Add the second batch incrementally.
|
49
|
+
then = Date.now();
|
50
|
+
payments.add(secondBatch);
|
51
|
+
console.log("Indexing " + formatNumber(secondSize) + " records: " + formatNumber(Date.now() - then) + "ms.");
|
52
|
+
console.log("Total indexing time: " + formatNumber(Date.now() - then2) + "ms.");
|
53
|
+
console.log("");
|
54
|
+
|
55
|
+
// Simulate filtering by dates.
|
56
|
+
then = Date.now();
|
57
|
+
var today = d3.time.day(new Date());
|
58
|
+
for (var i = 0, n = 90, k = 0; i < n; ++i) {
|
59
|
+
var ti = d3.time.day.offset(today, -i);
|
60
|
+
for (var j = 0; j < i; ++j) {
|
61
|
+
var tj = d3.time.day.offset(today, -j);
|
62
|
+
date.filterRange([ti, tj]);
|
63
|
+
updateDisplay();
|
64
|
+
}
|
65
|
+
}
|
66
|
+
console.log("Filtering by date: " + formatNumber((Date.now() - then) / k) + "ms/op.");
|
67
|
+
date.filterAll();
|
68
|
+
|
69
|
+
// Simulate filtering by day.
|
70
|
+
then = Date.now();
|
71
|
+
for (var i = 0, n = 7, k = 0; i < n; ++i) {
|
72
|
+
for (var j = i; j < n; ++j) {
|
73
|
+
day.filterRange([i, j]);
|
74
|
+
updateDisplay();
|
75
|
+
}
|
76
|
+
}
|
77
|
+
console.log("Filtering by day: " + formatNumber((Date.now() - then) / k) + "ms/op.");
|
78
|
+
day.filterAll();
|
79
|
+
|
80
|
+
// Simulate filtering by hour.
|
81
|
+
then = Date.now();
|
82
|
+
for (var i = 0, n = 24, k = 0; i < n; ++i) {
|
83
|
+
for (var j = i; j < n; ++j) {
|
84
|
+
hour.filterRange([i, j]);
|
85
|
+
updateDisplay();
|
86
|
+
}
|
87
|
+
}
|
88
|
+
console.log("Filtering by hour: " + formatNumber((Date.now() - then) / k) + "ms/op.");
|
89
|
+
hour.filterAll();
|
90
|
+
|
91
|
+
// Simulate filtering by amount.
|
92
|
+
then = Date.now();
|
93
|
+
for (var i = 0, n = 35, k = 0; i < n; ++i) {
|
94
|
+
for (var j = i; j < n; ++j) {
|
95
|
+
amount.filterRange([i, j]);
|
96
|
+
updateDisplay();
|
97
|
+
}
|
98
|
+
}
|
99
|
+
console.log("Filtering by amount: " + formatNumber((Date.now() - then) / k) + "ms/op.");
|
100
|
+
amount.filterAll();
|
101
|
+
|
102
|
+
console.log("");
|
103
|
+
console.log("Day of Week:");
|
104
|
+
x.domain([0, days.top(1)[0].value]);
|
105
|
+
days.all().forEach(function(g) {
|
106
|
+
console.log(" " + formatDay(g.key) + ": " + new Array(x(g.value) + 1).join("▇"));
|
107
|
+
});
|
108
|
+
console.log("");
|
109
|
+
|
110
|
+
console.log("Hour of Day:");
|
111
|
+
x.domain([0, hours.top(1)[0].value]);
|
112
|
+
hours.all().forEach(function(g) {
|
113
|
+
console.log(formatInteger(g.key) + ": " + new Array(x(g.value) + 1).join("▇"));
|
114
|
+
});
|
115
|
+
console.log("");
|
116
|
+
|
117
|
+
console.log("Date:");
|
118
|
+
x.domain([0, dates.top(1)[0].value]);
|
119
|
+
dates.all().forEach(function(g) {
|
120
|
+
console.log(formatDate(g.key) + ": " + new Array(x(g.value) + 1).join("▇"));
|
121
|
+
});
|
122
|
+
console.log("");
|
123
|
+
|
124
|
+
console.log("Amount:");
|
125
|
+
x.domain([0, amounts.top(1)[0].value]);
|
126
|
+
amounts.all().filter(function(g) { return x(g.value); }).forEach(function(g) {
|
127
|
+
console.log(formatInteger(g.key) + ": " + new Array(x(g.value) + 1).join("▇"));
|
128
|
+
});
|
129
|
+
console.log("");
|
130
|
+
|
131
|
+
// Simulates updating the display whenever the filters change.
|
132
|
+
function updateDisplay() {
|
133
|
+
dates.all(); // update the date chart
|
134
|
+
days.all(); // update the day-of-week chart
|
135
|
+
hours.all(); // update the hour-of-day chart
|
136
|
+
amounts.all(); // update the amount histogram
|
137
|
+
all.value(); // update the summary totals
|
138
|
+
date.top(40); // update the payment list
|
139
|
+
++k; // count frame rate
|
140
|
+
}
|
141
|
+
|
142
|
+
// Returns a function that returns random index in [0, distribution.length -
|
143
|
+
// 1], based on the relative values in the specified distribution. Internally,
|
144
|
+
// the distribution is converted to a normalized cumulative distribution in
|
145
|
+
// [0, 1], and then a uniform random value is used with bisection.
|
146
|
+
function randomIndex(distribution) {
|
147
|
+
var k = 1 / d3.sum(distribution), s = 0;
|
148
|
+
for (var i = 0, n = distribution.length; i < n; ++i) {
|
149
|
+
s = (distribution[i] = distribution[i] * k + s);
|
150
|
+
}
|
151
|
+
return function() {
|
152
|
+
return d3.bisectLeft(distribution, Math.random());
|
153
|
+
};
|
154
|
+
}
|
155
|
+
|
156
|
+
// Returns a function that returns random values with a log-normal
|
157
|
+
// distribution, with the specified mean and deviation.
|
158
|
+
function randomLogNormal(µ, σ) {
|
159
|
+
var random = d3.random.normal();
|
160
|
+
return function() {
|
161
|
+
return Math.exp(µ + σ * random());
|
162
|
+
};
|
163
|
+
}
|
164
|
+
|
165
|
+
// Returns a function that returns random dates, built on top of the specified
|
166
|
+
// random day-of-week and hour-of-day generators. The minutes, seconds, and
|
167
|
+
// milliseconds of the return dates are uniform random; as is the week of the
|
168
|
+
// returned date, which is between now and some *weeks* ago.
|
169
|
+
function randomRecentDate(randomDayOfWeek, randomHourOfDay, weeks) {
|
170
|
+
var now = Date.now();
|
171
|
+
return function() {
|
172
|
+
var d = d3.time.week.offset(new Date(), -Math.floor(Math.random() * weeks));
|
173
|
+
d.setDate(d.getDate() + randomDayOfWeek() - d.getDay());
|
174
|
+
d.setHours(randomHourOfDay(), Math.random() * 60, Math.random() * 60, Math.random() * 1000);
|
175
|
+
return d;
|
176
|
+
};
|
177
|
+
}
|
@@ -0,0 +1,206 @@
|
|
1
|
+
var vows = require("vows"),
|
2
|
+
assert = require("assert"),
|
3
|
+
tesseract = require("../");
|
4
|
+
|
5
|
+
var suite = vows.describe("bisect");
|
6
|
+
|
7
|
+
suite.addBatch({
|
8
|
+
"bisect": {
|
9
|
+
topic: function() {
|
10
|
+
return tesseract.bisect;
|
11
|
+
},
|
12
|
+
"is the same as bisect.right": function(bisect) {
|
13
|
+
assert.strictEqual(bisect, bisect.right);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
});
|
17
|
+
|
18
|
+
suite.addBatch({
|
19
|
+
"bisect.left": {
|
20
|
+
topic: function() {
|
21
|
+
return tesseract.bisect.left;
|
22
|
+
},
|
23
|
+
"finds the index of an exact match": function(bisect) {
|
24
|
+
var array = [1, 2, 3];
|
25
|
+
assert.equal(bisect(array, 1, 0, 3), 0);
|
26
|
+
assert.equal(bisect(array, 2, 0, 3), 1);
|
27
|
+
assert.equal(bisect(array, 3, 0, 3), 2);
|
28
|
+
},
|
29
|
+
"finds the index of the first match": function(bisect) {
|
30
|
+
var array = [1, 2, 2, 3];
|
31
|
+
assert.equal(bisect(array, 1, 0, 4), 0);
|
32
|
+
assert.equal(bisect(array, 2, 0, 4), 1);
|
33
|
+
assert.equal(bisect(array, 3, 0, 4), 3);
|
34
|
+
},
|
35
|
+
"finds the insertion point of a non-exact match": function(bisect) {
|
36
|
+
var array = [1, 2, 3];
|
37
|
+
assert.equal(bisect(array, 0.5, 0, 3), 0);
|
38
|
+
assert.equal(bisect(array, 1.5, 0, 3), 1);
|
39
|
+
assert.equal(bisect(array, 2.5, 0, 3), 2);
|
40
|
+
assert.equal(bisect(array, 3.5, 0, 3), 3);
|
41
|
+
},
|
42
|
+
"observes the lower bound": function(bisect) {
|
43
|
+
var array = [1, 2, 3, 4, 5];
|
44
|
+
assert.equal(bisect(array, 0, 2, 5), 2);
|
45
|
+
assert.equal(bisect(array, 1, 2, 5), 2);
|
46
|
+
assert.equal(bisect(array, 2, 2, 5), 2);
|
47
|
+
assert.equal(bisect(array, 3, 2, 5), 2);
|
48
|
+
assert.equal(bisect(array, 4, 2, 5), 3);
|
49
|
+
assert.equal(bisect(array, 5, 2, 5), 4);
|
50
|
+
assert.equal(bisect(array, 6, 2, 5), 5);
|
51
|
+
},
|
52
|
+
"observes the lower and upper bounds": function(bisect) {
|
53
|
+
var array = [1, 2, 3, 4, 5];
|
54
|
+
assert.equal(bisect(array, 0, 2, 3), 2);
|
55
|
+
assert.equal(bisect(array, 1, 2, 3), 2);
|
56
|
+
assert.equal(bisect(array, 2, 2, 3), 2);
|
57
|
+
assert.equal(bisect(array, 3, 2, 3), 2);
|
58
|
+
assert.equal(bisect(array, 4, 2, 3), 3);
|
59
|
+
assert.equal(bisect(array, 5, 2, 3), 3);
|
60
|
+
assert.equal(bisect(array, 6, 2, 3), 3);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
});
|
64
|
+
|
65
|
+
suite.addBatch({
|
66
|
+
"bisect.by(value).left": {
|
67
|
+
topic: function() {
|
68
|
+
return tesseract.bisect.by(function(d) { return d.value; }).left;
|
69
|
+
},
|
70
|
+
"finds the index of an exact match": function(bisect) {
|
71
|
+
var array = [{value: 1}, {value: 2}, {value: 3}];
|
72
|
+
assert.equal(bisect(array, 1, 0, 3), 0);
|
73
|
+
assert.equal(bisect(array, 2, 0, 3), 1);
|
74
|
+
assert.equal(bisect(array, 3, 0, 3), 2);
|
75
|
+
},
|
76
|
+
"finds the index of the first match": function(bisect) {
|
77
|
+
var array = [{value: 1}, {value: 2}, {value: 2}, {value: 3}];
|
78
|
+
assert.equal(bisect(array, 1, 0, 4), 0);
|
79
|
+
assert.equal(bisect(array, 2, 0, 4), 1);
|
80
|
+
assert.equal(bisect(array, 3, 0, 4), 3);
|
81
|
+
},
|
82
|
+
"finds the insertion point of a non-exact match": function(bisect) {
|
83
|
+
var array = [{value: 1}, {value: 2}, {value: 3}];
|
84
|
+
assert.equal(bisect(array, 0.5, 0, 3), 0);
|
85
|
+
assert.equal(bisect(array, 1.5, 0, 3), 1);
|
86
|
+
assert.equal(bisect(array, 2.5, 0, 3), 2);
|
87
|
+
assert.equal(bisect(array, 3.5, 0, 3), 3);
|
88
|
+
},
|
89
|
+
"observes the lower bound": function(bisect) {
|
90
|
+
var array = [{value: 1}, {value: 2}, {value: 3}, {value: 4}, {value: 5}];
|
91
|
+
assert.equal(bisect(array, 0, 2, 5), 2);
|
92
|
+
assert.equal(bisect(array, 1, 2, 5), 2);
|
93
|
+
assert.equal(bisect(array, 2, 2, 5), 2);
|
94
|
+
assert.equal(bisect(array, 3, 2, 5), 2);
|
95
|
+
assert.equal(bisect(array, 4, 2, 5), 3);
|
96
|
+
assert.equal(bisect(array, 5, 2, 5), 4);
|
97
|
+
assert.equal(bisect(array, 6, 2, 5), 5);
|
98
|
+
},
|
99
|
+
"observes the lower and upper bounds": function(bisect) {
|
100
|
+
var array = [{value: 1}, {value: 2}, {value: 3}, {value: 4}, {value: 5}];
|
101
|
+
assert.equal(bisect(array, 0, 2, 3), 2);
|
102
|
+
assert.equal(bisect(array, 1, 2, 3), 2);
|
103
|
+
assert.equal(bisect(array, 2, 2, 3), 2);
|
104
|
+
assert.equal(bisect(array, 3, 2, 3), 2);
|
105
|
+
assert.equal(bisect(array, 4, 2, 3), 3);
|
106
|
+
assert.equal(bisect(array, 5, 2, 3), 3);
|
107
|
+
assert.equal(bisect(array, 6, 2, 3), 3);
|
108
|
+
}
|
109
|
+
}
|
110
|
+
});
|
111
|
+
|
112
|
+
suite.addBatch({
|
113
|
+
"bisect.right": {
|
114
|
+
topic: function() {
|
115
|
+
return tesseract.bisect.right;
|
116
|
+
},
|
117
|
+
"finds the index after an exact match": function(bisect) {
|
118
|
+
var array = [1, 2, 3];
|
119
|
+
assert.equal(bisect(array, 1, 0, 3), 1);
|
120
|
+
assert.equal(bisect(array, 2, 0, 3), 2);
|
121
|
+
assert.equal(bisect(array, 3, 0, 3), 3);
|
122
|
+
},
|
123
|
+
"finds the index after the last match": function(bisect) {
|
124
|
+
var array = [1, 2, 2, 3];
|
125
|
+
assert.equal(bisect(array, 1, 0, 4), 1);
|
126
|
+
assert.equal(bisect(array, 2, 0, 4), 3);
|
127
|
+
assert.equal(bisect(array, 3, 0, 4), 4);
|
128
|
+
},
|
129
|
+
"finds the insertion point of a non-exact match": function(bisect) {
|
130
|
+
var array = [1, 2, 3];
|
131
|
+
assert.equal(bisect(array, 0.5, 0, 3), 0);
|
132
|
+
assert.equal(bisect(array, 1.5, 0, 3), 1);
|
133
|
+
assert.equal(bisect(array, 2.5, 0, 3), 2);
|
134
|
+
assert.equal(bisect(array, 3.5, 0, 3), 3);
|
135
|
+
},
|
136
|
+
"observes the lower bound": function(bisect) {
|
137
|
+
var array = [1, 2, 3, 4, 5];
|
138
|
+
assert.equal(bisect(array, 0, 2, 5), 2);
|
139
|
+
assert.equal(bisect(array, 1, 2, 5), 2);
|
140
|
+
assert.equal(bisect(array, 2, 2, 5), 2);
|
141
|
+
assert.equal(bisect(array, 3, 2, 5), 3);
|
142
|
+
assert.equal(bisect(array, 4, 2, 5), 4);
|
143
|
+
assert.equal(bisect(array, 5, 2, 5), 5);
|
144
|
+
assert.equal(bisect(array, 6, 2, 5), 5);
|
145
|
+
},
|
146
|
+
"observes the lower and upper bounds": function(bisect) {
|
147
|
+
var array = [1, 2, 3, 4, 5];
|
148
|
+
assert.equal(bisect(array, 0, 2, 3), 2);
|
149
|
+
assert.equal(bisect(array, 1, 2, 3), 2);
|
150
|
+
assert.equal(bisect(array, 2, 2, 3), 2);
|
151
|
+
assert.equal(bisect(array, 3, 2, 3), 3);
|
152
|
+
assert.equal(bisect(array, 4, 2, 3), 3);
|
153
|
+
assert.equal(bisect(array, 5, 2, 3), 3);
|
154
|
+
assert.equal(bisect(array, 6, 2, 3), 3);
|
155
|
+
}
|
156
|
+
}
|
157
|
+
});
|
158
|
+
|
159
|
+
suite.addBatch({
|
160
|
+
"bisect.by(value).right": {
|
161
|
+
topic: function() {
|
162
|
+
return tesseract.bisect.by(function(d) { return d.value; }).right;
|
163
|
+
},
|
164
|
+
"finds the index after an exact match": function(bisect) {
|
165
|
+
var array = [{value: 1}, {value: 2}, {value: 3}];
|
166
|
+
assert.equal(bisect(array, 1, 0, 3), 1);
|
167
|
+
assert.equal(bisect(array, 2, 0, 3), 2);
|
168
|
+
assert.equal(bisect(array, 3, 0, 3), 3);
|
169
|
+
},
|
170
|
+
"finds the index after the last match": function(bisect) {
|
171
|
+
var array = [{value: 1}, {value: 2}, {value: 2}, {value: 3}];
|
172
|
+
assert.equal(bisect(array, 1, 0, 4), 1);
|
173
|
+
assert.equal(bisect(array, 2, 0, 4), 3);
|
174
|
+
assert.equal(bisect(array, 3, 0, 4), 4);
|
175
|
+
},
|
176
|
+
"finds the insertion point of a non-exact match": function(bisect) {
|
177
|
+
var array = [{value: 1}, {value: 2}, {value: 3}];
|
178
|
+
assert.equal(bisect(array, 0.5, 0, 3), 0);
|
179
|
+
assert.equal(bisect(array, 1.5, 0, 3), 1);
|
180
|
+
assert.equal(bisect(array, 2.5, 0, 3), 2);
|
181
|
+
assert.equal(bisect(array, 3.5, 0, 3), 3);
|
182
|
+
},
|
183
|
+
"observes the lower bound": function(bisect) {
|
184
|
+
var array = [{value: 1}, {value: 2}, {value: 3}, {value: 4}, {value: 5}];
|
185
|
+
assert.equal(bisect(array, 0, 2, 5), 2);
|
186
|
+
assert.equal(bisect(array, 1, 2, 5), 2);
|
187
|
+
assert.equal(bisect(array, 2, 2, 5), 2);
|
188
|
+
assert.equal(bisect(array, 3, 2, 5), 3);
|
189
|
+
assert.equal(bisect(array, 4, 2, 5), 4);
|
190
|
+
assert.equal(bisect(array, 5, 2, 5), 5);
|
191
|
+
assert.equal(bisect(array, 6, 2, 5), 5);
|
192
|
+
},
|
193
|
+
"observes the lower and upper bounds": function(bisect) {
|
194
|
+
var array = [{value: 1}, {value: 2}, {value: 3}, {value: 4}, {value: 5}];
|
195
|
+
assert.equal(bisect(array, 0, 2, 3), 2);
|
196
|
+
assert.equal(bisect(array, 1, 2, 3), 2);
|
197
|
+
assert.equal(bisect(array, 2, 2, 3), 2);
|
198
|
+
assert.equal(bisect(array, 3, 2, 3), 3);
|
199
|
+
assert.equal(bisect(array, 4, 2, 3), 3);
|
200
|
+
assert.equal(bisect(array, 5, 2, 3), 3);
|
201
|
+
assert.equal(bisect(array, 6, 2, 3), 3);
|
202
|
+
}
|
203
|
+
}
|
204
|
+
});
|
205
|
+
|
206
|
+
suite.export(module);
|
@@ -0,0 +1,44 @@
|
|
1
|
+
var vows = require("vows"),
|
2
|
+
assert = require("assert"),
|
3
|
+
tesseract = require("../");
|
4
|
+
|
5
|
+
var suite = vows.describe("heap");
|
6
|
+
|
7
|
+
suite.addBatch({
|
8
|
+
"heap": {
|
9
|
+
topic: function() {
|
10
|
+
return tesseract.heap;
|
11
|
+
},
|
12
|
+
"children are greater than or equal to parents": function(heap) {
|
13
|
+
var array = [6, 5, 3, 1, 8, 7, 2, 4]
|
14
|
+
n = array.length;
|
15
|
+
assert.strictEqual(heap(array, 0, n), array);
|
16
|
+
assert.equal(array[0], 1);
|
17
|
+
for (var i = 1; i < n; ++i) assert(array[i] >= array[i - 1 >> 1]);
|
18
|
+
},
|
19
|
+
"creates a heap from a subset of the array": function(heap) {
|
20
|
+
var array = [6, 5, 3, 1, 8, 7, 2, 4]
|
21
|
+
n = 6;
|
22
|
+
assert.strictEqual(heap(array, 0, n), array);
|
23
|
+
assert.equal(array[0], 1);
|
24
|
+
for (var i = 1; i < n; ++i) assert(array[i] >= array[i - 1 >> 1]);
|
25
|
+
},
|
26
|
+
|
27
|
+
"sort": {
|
28
|
+
"sorts an existing heap in descending order": function(heap) {
|
29
|
+
var array = [1, 4, 2, 5, 8, 7, 3, 6],
|
30
|
+
n = array.length;
|
31
|
+
heap.sort(array, 0, n);
|
32
|
+
assert.deepEqual(array, [8, 7, 6, 5, 4, 3, 2, 1]);
|
33
|
+
},
|
34
|
+
"sorts a two-element heap in descending order": function(heap) {
|
35
|
+
var array = [1, 4],
|
36
|
+
n = array.length;
|
37
|
+
heap.sort(array, 0, n);
|
38
|
+
assert.deepEqual(array, [4, 1]);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
44
|
+
suite.export(module);
|
@@ -0,0 +1,51 @@
|
|
1
|
+
var vows = require("vows"),
|
2
|
+
assert = require("assert"),
|
3
|
+
tesseract = require("../");
|
4
|
+
|
5
|
+
var suite = vows.describe("permute");
|
6
|
+
|
7
|
+
suite.addBatch({
|
8
|
+
"permute": {
|
9
|
+
topic: function() {
|
10
|
+
return tesseract.permute;
|
11
|
+
},
|
12
|
+
"permutes according to the specified index": function(permute) {
|
13
|
+
assert.deepEqual(permute([3, 4, 5], [2, 1, 0]), [5, 4, 3]);
|
14
|
+
assert.deepEqual(permute([3, 4, 5], [2, 0, 1]), [5, 3, 4]);
|
15
|
+
assert.deepEqual(permute([3, 4, 5], [0, 1, 2]), [3, 4, 5]);
|
16
|
+
},
|
17
|
+
"does not modify the input array": function(permute) {
|
18
|
+
var input = [3, 4, 5];
|
19
|
+
permute(input, [2, 1, 0]);
|
20
|
+
assert.deepEqual(input, [3, 4, 5]);
|
21
|
+
},
|
22
|
+
"can duplicate input values": function(permute) {
|
23
|
+
assert.deepEqual(permute([3, 4, 5], [0, 1, 0]), [3, 4, 3]);
|
24
|
+
assert.deepEqual(permute([3, 4, 5], [2, 2, 2]), [5, 5, 5]);
|
25
|
+
assert.deepEqual(permute([3, 4, 5], [0, 1, 1]), [3, 4, 4]);
|
26
|
+
},
|
27
|
+
"can return more elements": function(permute) {
|
28
|
+
assert.deepEqual(permute([3, 4, 5], [0, 0, 1, 2]), [3, 3, 4, 5]);
|
29
|
+
assert.deepEqual(permute([3, 4, 5], [0, 1, 1, 1]), [3, 4, 4, 4]);
|
30
|
+
},
|
31
|
+
"can return fewer elements": function(permute) {
|
32
|
+
assert.deepEqual(permute([3, 4, 5], [0]), [3]);
|
33
|
+
assert.deepEqual(permute([3, 4, 5], [1, 2]), [4, 5]);
|
34
|
+
assert.deepEqual(permute([3, 4, 5], []), []);
|
35
|
+
},
|
36
|
+
"can return undefined elements": function(permute) {
|
37
|
+
var v1 = permute([3, 4, 5], [10]);
|
38
|
+
assert.equal(v1.length, 1);
|
39
|
+
assert.isUndefined(v1[0]);
|
40
|
+
var v2 = permute([3, 4, 5], [-1]);
|
41
|
+
assert.equal(v2.length, 1);
|
42
|
+
assert.isUndefined(v2[0]);
|
43
|
+
var v3 = permute([3, 4, 5], [0, -1]);
|
44
|
+
assert.equal(v3.length, 2);
|
45
|
+
assert.equal(v3[0], 3);
|
46
|
+
assert.isUndefined(v3[1]);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
51
|
+
suite.export(module);
|