From 21bb287c2aa2779f55b3a7391ca4976f13a7398f Mon Sep 17 00:00:00 2001 From: Schmuli Raskin Date: Thu, 31 Oct 2013 13:25:59 +0200 Subject: [PATCH] Added CrossFilter definition file and tests --- README.md | 2 +- crossfilter/crossfilter-tests.ts | 136 +++++++++++++++++++++++++ crossfilter/crossfilter.d.ts | 111 ++++++++++++++++++++ crossfilter/crossfilter.d.ts.tscparams | 0 4 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 crossfilter/crossfilter-tests.ts create mode 100644 crossfilter/crossfilter.d.ts create mode 100644 crossfilter/crossfilter.d.ts.tscparams diff --git a/README.md b/README.md index 5b2e26e789..c6b75370e4 100755 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ List of Definitions * [Chrome App](http://developer.chrome.com/apps/) (by [Adam Lay](https://github.com/AdamLay)) * [CodeMirror](http://codemirror.net) (by [François de Campredon](https://github.com/fdecampredon)) * [Commander](http://github.com/visionmedia/commander.js) (by [Marcelo Dezem](https://github.com/mdezem)) +* [Crossfilter](https://github.com/square/crossfilter) (by [Schmulik Raskin](https://github.com/schmuli)) * [d3.js](http://d3js.org/) (from TypeScript samples) * [dhtmlxGantt](http://dhtmlx.com/docs/products/dhtmlxGantt) (by [Maksim Kozhukh](http://github.com/mkozhukh)) * [dhtmlxScheduler](http://dhtmlx.com/docs/products/dhtmlxScheduler) (by [Maksim Kozhukh](http://github.com/mkozhukh)) @@ -234,7 +235,6 @@ List of Definitions Requested Definitions --------------------- * [jQuery ScrollTo](https://github.com/balupton/jquery-scrollto) -* [Crossfilter](https://github.com/square/crossfilter) * [dc.js](https://github.com/NickQiZhu/dc.js) * [google.visualizations](https://developers.google.com/chart/) * [Prelude.ls](http://gkz.github.com/prelude-ls/) diff --git a/crossfilter/crossfilter-tests.ts b/crossfilter/crossfilter-tests.ts new file mode 100644 index 0000000000..222096566e --- /dev/null +++ b/crossfilter/crossfilter-tests.ts @@ -0,0 +1,136 @@ + +/// + +interface Payment { + date: string; + quantity: number; + total: number; + tip: number; + type: string; +} + +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"} +]); + +var paymentsByTotal = payments.dimension((d) => d.total); + +// Filters +paymentsByTotal.filter([100, 200]); // selects payments whose total is between 100 and 200 +paymentsByTotal.filter(120); // selects payments whose total equals 120 +paymentsByTotal.filter(d => d % 2); // selects payments whose total is odd +paymentsByTotal.filter(null); // selects all payments + +paymentsByTotal.filterExact(120); // selects payments whose total equals 120 + +paymentsByTotal.filterRange([100, 200]); // selects payments whose total is between 100 and 200 + +paymentsByTotal.filterFunction(d => d % 2); // selects payments whose total is odd + +// Selects payments whose total is between 0 and 10 or 20 and 30: +paymentsByTotal.filterFunction(d => 0 <= d && d < 10 || 20 <= d && d < 30); + +paymentsByTotal.filterAll(); // selects all payments + +var topPayments = paymentsByTotal.top(4); // the top four payments, by total +topPayments[0]; // the biggest payment +topPayments[1]; // the second-biggest payment + +var allPayments = paymentsByTotal.top(Infinity); + +var bottomPayments = paymentsByTotal.bottom(4); // the bottom four payments, by total +bottomPayments[0]; // the smallest payment +bottomPayments[1]; // the second-smallest payment + +var paymentGroupsByTotal = paymentsByTotal.group(total => Math.floor(total / 100)); + +paymentGroupsByTotal.size(); + +paymentGroupsByTotal.reduce((p, v) => p + 1, (p, v) => p - 1, () => 0); + +paymentGroupsByTotal.reduceCount(); + +var paymentsByType = payments.dimension(d => d.type), + paymentVolumeByType = paymentsByType.group().reduceSum(d => 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., 900) + +interface Group { + count: number; + total: number; +} + +function reduceAdd(p: Group, v: Payment) { + ++p.count; + p.total += v.total; + return p; +} + +function reduceRemove(p: Group, v: Payment) { + --p.count; + p.total -= v.total; + return p; +} + +function reduceInitial() : Group { + return {count: 0, total: 0}; +} + +function orderValue(p: Group) { + 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}) + +paymentGroupsByTotal.orderNatural(); + +var 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) + +var types = paymentCountByType.all(); + +paymentsByTotal.dispose(); + +crossfilter.bisect([], null, 0, 0); +var bisectBy = crossfilter.bisect.by(t => t); +bisectBy([], null, 0, 0); +bisectBy.left([], null, 0, 0); +bisectBy.right([], null, 0, 0); + +crossfilter.heap([], 0, 0); +var heapBy = crossfilter.heap.by(t => t); +heapBy([], 0, 0); +heapBy.sort([], 0, 0); + +crossfilter.heapselect([], 0, 0, 0); +var heapselectBy = crossfilter.heapselect.by(t => t); +heapselectBy([], 0, 0, 0); + +crossfilter.insertionsort([], 0, 0); +var insertionsortBy = crossfilter.insertionsort.by(t => t); +insertionsortBy([], 0, 0); + +crossfilter.quicksort([], 0, 0); +var quicksortBy = crossfilter.quicksort.by(t => t); +quicksortBy([], 0, 0); + +crossfilter.permute([], []); diff --git a/crossfilter/crossfilter.d.ts b/crossfilter/crossfilter.d.ts new file mode 100644 index 0000000000..a54f546711 --- /dev/null +++ b/crossfilter/crossfilter.d.ts @@ -0,0 +1,111 @@ +// Type definitions for CrossFilter +// Project: https://github.com/square/crossfilter +// Definitions by: Schmulik Raskin +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module CrossFilter { + + export interface Selector { + (value: T): any; + } + + export interface CrossFilterStatic { + (data: T[]): CrossFilter; + version: string; + permute(array: T[], index: number[]): T[]; + bisect: { + (array: T[], value: T, lo: number, hi: number): number; + by(value: Selector): Bisector; + } + heap: { + (array: T[], lo: number, hi: number): T[]; + + by(value: Selector): Heap; + } + heapselect: { + (array: T[], lo: number, hi: number, k: number): T[]; + by(value: Selector): HeapSelect; + } + insertionsort: { + (array: T[], lo: number, hi: number): T[]; + by(value: Selector): Sort; + } + quicksort: { + (array: T[], lo: number, hi: number): T[]; + by(value: Selector): Sort; + } + } + + export interface Bisection { + (array: T[], value: T, lo: number, hi: number): number; + } + + export interface Bisector extends Bisection { + left: Bisection + right: Bisection + } + + export interface Heap { + (array: T[], lo: number, hi: number): T[]; + sort(array: T[], lo: number, hi: number): T[]; + } + + export interface HeapSelect { + (array: T[], lo: number, hi: number, k: number): T[]; + } + + export interface Sort { + (array: T[], lo: number, hi: number): T[]; + } + + export interface GroupAll { + reduce(add: (p: TValue, v: T) => TValue, remove: (p: TValue, v: T) => TValue, initial: () => TValue): GroupAll; + reduceCount(): GroupAll; + reduceSum(value: Selector): GroupAll; + dispose(): GroupAll; + value(): T; + } + + export interface Grouping { + key: TKey; + value: TValue; + } + + export interface Group { + top(k: number): Grouping[]; + all(): Grouping[]; + reduce(add: (p: TGroup, v: T) => TGroup, remove: (p: TGroup, v: T) => TGroup, initial: () => TGroup): Group; + reduceCount(): Group; + reduceSum(value: (data: T) => TGroup): Group; + order(value?: Selector): Group; + orderNatural(): Group; + size(): number; + dispose(): Group; + } + + export interface CrossFilter { + add(records: T[]): CrossFilter; + remove(): CrossFilter; + size(): number; + groupAll(): GroupAll; + dimension(value: (data: T) => TDimension): Dimension; + } + + export interface Dimension { + filter(value: TDimension[]): Dimension; + filter(value: TDimension): Dimension; + filter(value: Selector): Dimension; + filterExact(value: TDimension): Dimension; + filterRange(value: TDimension[]): Dimension; + filterFunction(value: Selector): Dimension; + filterAll(): Dimension; + top(k: number): T[]; + bottom(k: number): T[]; + dispose(): void; + group(): Group; + group(groupValue: (data: T) => TGroup): Group; + groupAll(): GroupAll; + } +} + +declare var crossfilter: CrossFilter.CrossFilterStatic; \ No newline at end of file diff --git a/crossfilter/crossfilter.d.ts.tscparams b/crossfilter/crossfilter.d.ts.tscparams new file mode 100644 index 0000000000..e69de29bb2