diff --git a/dcjs/dc-tests.ts b/dcjs/dc-tests.ts
index 60d3aa059a..91b1dc77d2 100644
--- a/dcjs/dc-tests.ts
+++ b/dcjs/dc-tests.ts
@@ -3,240 +3,221 @@
///
interface IYelpData {
- city: string;
- review_count: number;
- name: string;
- neighborhoods: string[];
- type: string;
- business_id: string;
- full_address: string;
- state: string;
- longitude: number;
- stars: number;
- latitude: number;
- open: boolean;
- categories: string[]
+ city: string;
+ review_count: number;
+ name: string;
+ neighborhoods: string[];
+ type: string;
+ business_id: string;
+ full_address: string;
+ state: string;
+ longitude: number;
+ stars: number;
+ latitude: number;
+ open: boolean;
+ categories: string[]
}
interface IYelpDataExtended {
- count: number;
- review_sum: number;
- star_sum: number;
- review_avg: number;
- star_avg: number;
+ count: number;
+ review_sum: number;
+ star_sum: number;
+ review_avg: number;
+ star_avg: number;
}
/********************************************************
-* *
-* dj.js example using Yelp Kaggle Test Dataset *
-* Eamonn O'Loughlin 9th May 2013 *
-* *
-********************************************************/
+ * *
+ * dj.js example using Yelp Kaggle Test Dataset *
+ * Eamonn O'Loughlin 9th May 2013 *
+ * *
+ ********************************************************/
/********************************************************
-* *
-* Step0: Load data from json file *
-* *
-********************************************************/
-d3.json("data/yelp_test_set_business.json", function (yelp_data:IYelpData[]) {
-
-/********************************************************
-* *
-* Step1: Create the dc.js chart objects & ling to div *
-* *
-********************************************************/
-var bubbleChart = dc.bubbleChart("#dc-bubble-graph");
-var pieChart = dc.pieChart("#dc-pie-graph");
-var volumeChart = dc.barChart("#dc-volume-chart");
-var lineChart = dc.lineChart("#dc-line-chart");
-var dataTable = dc.dataTable("#dc-table-graph");
-var rowChart = dc.rowChart("#dc-row-graph");
+ * *
+ * Step0: Load data from json file *
+ * *
+ ********************************************************/
+d3.json("data/yelp_test_set_business.json", (yelp_data:IYelpData[]) => {
-/********************************************************
-* *
-* Step2: Run data through crossfilter *
-* *
-********************************************************/
-var ndx = crossfilter(yelp_data);
-
-/********************************************************
-* *
-* Step3: Create Dimension that we'll need *
-* *
-********************************************************/
+ /********************************************************
+ * *
+ * Step1: Create the dc.js chart objects & ling to div *
+ * *
+ ********************************************************/
+ var bubbleChart: DC.BubbleChart = dc.bubbleChart("#dc-bubble-graph");
+ var pieChart: DC.PieChart = dc.pieChart("#dc-pie-graph");
+ var volumeChart: DC.BarChart = dc.barChart("#dc-volume-chart");
+ var lineChart: DC.LineChart = dc.lineChart("#dc-line-chart");
+ var dataTable: DC.DataTableWidget = dc.dataTable("#dc-table-graph");
+ var rowChart: DC.RowChart = dc.rowChart("#dc-row-graph");
- // for volumechart
- var cityDimension = ndx.dimension(function (d) { return d.city; });
- var cityGroup = cityDimension.group();
- var cityDimensionGroup = cityDimension.group().reduce(
- //add
- function(p: IYelpDataExtended,v:IYelpData){
- ++p.count;
- p.review_sum += v.review_count;
- p.star_sum += v.stars;
- p.review_avg = p.review_sum / p.count;
- p.star_avg = p.star_sum / p.count;
- return p;
- },
- //remove
- function(p: IYelpDataExtended,v:IYelpData){
- --p.count;
- p.review_sum -= v.review_count;
- p.star_sum -= v.stars;
- p.review_avg = p.review_sum / p.count;
- p.star_avg = p.star_sum / p.count;
- return p;
- },
- //init
- function(){
- return {count:0, review_sum: 0, star_sum: 0, review_avg: 0, star_avg: 0};
- }
- );
+ /********************************************************
+ * *
+ * Step2: Run data through crossfilter *
+ * *
+ ********************************************************/
+ var ndx: CrossFilter.CrossFilter = crossfilter(yelp_data);
- // for pieChart
- var startValue = ndx.dimension(function (d) {
- return d.stars*1.0;
- });
- var startValueGroup = startValue.group();
+ /********************************************************
+ * *
+ * Step3: Create Dimension that we'll need *
+ * *
+ ********************************************************/
- // For datatable
- var businessDimension = ndx.dimension(function (d) { return d.business_id; });
-/********************************************************
-* *
-* Step4: Create the Visualisations *
-* *
-********************************************************/
-
- bubbleChart.width(650)
- .height(300)
- .dimension(cityDimension)
- .group(cityDimensionGroup)
- .transitionDuration(1500)
- .colors(["#a60000","#ff0000", "#ff4040","#ff7373","#67e667","#39e639","#00cc00"])
- .colorDomain([-12000, 12000])
-
- .x(d3.scale.linear().domain([0, 5.5]))
- .y(d3.scale.linear().domain([0, 5.5]))
- .r(d3.scale.linear().domain([0, 2500]))
- .keyAccessor(function (p) {
- return p.value.star_avg;
- })
- .valueAccessor(function (p) {
- return p.value.review_avg;
- })
- .radiusValueAccessor(function (p) {
- return p.value.count;
- })
- .transitionDuration(1500)
- .elasticY(true)
- .yAxisPadding(1)
- .xAxisPadding(1)
- .label(function (p) {
- return p.key;
- })
- .renderLabel(true)
- .renderlet(function (chart) {
- rowChart.filter(chart.filter());
- })
- .on("postRedraw", function (chart) {
- dc.events.trigger(function () {
- rowChart.filter(chart.filter());
- });
- });
- ;
+ // for volumechart
+ var cityDimension: CrossFilter.Dimension = ndx.dimension((d: IYelpData) => d.city);
+ var cityGroup: CrossFilter.Group = cityDimension.group();
+ var cityDimensionGroup: CrossFilter.Group = cityDimension.group().reduce(
+ //add
+ (p: IYelpDataExtended, v:IYelpData) => {
+ ++p.count;
+ p.review_sum += v.review_count;
+ p.star_sum += v.stars;
+ p.review_avg = p.review_sum / p.count;
+ p.star_avg = p.star_sum / p.count;
+ return p;
+ },
+ //remove
+ (p: IYelpDataExtended, v:IYelpData) => {
+ --p.count;
+ p.review_sum -= v.review_count;
+ p.star_sum -= v.stars;
+ p.review_avg = p.review_sum / p.count;
+ p.star_avg = p.star_sum / p.count;
+ return p;
+ },
+ //init
+ () => {
+ return {count: 0, review_sum: 0, star_sum: 0, review_avg: 0, star_avg: 0};
+ }
+ );
+ // for pieChart
+ var startValue: CrossFilter.Dimension = ndx.dimension((d: IYelpData) => d.stars * 1.0);
+ var startValueGroup: CrossFilter.Group = startValue.group();
-pieChart.width(200)
- .height(200)
- .transitionDuration(1500)
- .dimension(startValue)
- .group(startValueGroup)
- .radius(90)
- .minAngleForLabel(0)
- .label(function(d) { return d.data.key; })
- .on("filtered", function (chart) {
- dc.events.trigger(function () {
- if(chart.filter()) {
- console.log(chart.filter());
- volumeChart.filter([chart.filter()-.25,chart.filter()-(-0.25)]);
- }
- else volumeChart.filterAll();
- });
- });
+ // For datatable
+ var businessDimension: CrossFilter.Dimension = ndx.dimension((d: IYelpData) => d.business_id);
+ /********************************************************
+ * *
+ * Step4: Create the Visualisations *
+ * *
+ ********************************************************/
-volumeChart.width(230)
- .height(200)
- .dimension(startValue)
- .group(startValueGroup)
- .transitionDuration(1500)
- .centerBar(true)
- .gap(17)
- .x(d3.scale.linear().domain([0.5, 5.5]))
- .elasticY(true)
- .on("filtered", function (chart) {
- dc.events.trigger(function () {
- if(chart.filter()) {
- console.log(chart.filter());
- lineChart.filter(chart.filter());
- }
- else
- {lineChart.filterAll()}
- });
- })
- .xAxis().tickFormat(function(v) {return v;});
+ bubbleChart
+ .width(650)
+ .height(300)
+ .dimension(cityDimension)
+ .group(cityDimensionGroup)
+ .transitionDuration(1500)
+ .colors(["#a60000","#ff0000", "#ff4040","#ff7373","#67e667","#39e639","#00cc00"])
+ .colorDomain([-12000, 12000])
+ .x(d3.scale.linear().domain([0, 5.5]))
+ .y(d3.scale.linear().domain([0, 5.5]))
+ .r(d3.scale.linear().domain([0, 2500]))
+ .keyAccessor((p: any) => p.value.star_avg)
+ .valueAccessor((p: any) => p.value.review_avg)
+ .radiusValueAccessor((p: any) => p.value.count)
+ .transitionDuration(1500)
+ .elasticY(true)
+ .yAxisPadding(1)
+ .xAxisPadding(1)
+ .label((p: any) => p.key)
+ .renderLabel(true)
+ .renderlet((chart: DC.BubbleChart) => rowChart.filter(chart.filter()))
+ .on("postRedraw", (chart: DC.BubbleChart) => dc.events.trigger(() => rowChart.filter(chart.filter())));
-console.log(startValueGroup.top(1)[0].value);
+ pieChart
+ .width(200)
+ .height(200)
+ .transitionDuration(1500)
+ .dimension(startValue)
+ .group(startValueGroup)
+ .radius(90)
+ .minAngleForLabel(0)
+ .label((d: any) => d.data.key)
+ .on("filtered", (chart: DC.PieChart) =>
+ dc.events.trigger(() => {
+ if (chart.filter()) {
+ console.log(chart.filter());
+ volumeChart.filter([chart.filter()-.25,chart.filter()-(-0.25)]);
+ }
+ else volumeChart.filterAll();
+ }));
-lineChart.width(230)
- .height(200)
- .dimension(startValue)
- .group(startValueGroup)
- .x(d3.scale.linear().domain([0.5, 5.5]))
- .valueAccessor(function(d) {
- return d.value;
- })
- .renderHorizontalGridLines(true)
- .elasticY(true)
- .xAxis().tickFormat(function(v) {return v;}); ;
+ volumeChart
+ .width(230)
+ .height(200)
+ .dimension(startValue)
+ .group(startValueGroup)
+ .transitionDuration(1500)
+ .centerBar(true)
+ .gap(17)
+ .x(d3.scale.linear().domain([0.5, 5.5]))
+ .elasticY(true)
+ .on("filtered", (chart: DC.BarChart) =>
+ dc.events.trigger(() => {
+ if(chart.filter()) {
+ console.log(chart.filter());
+ lineChart.filter(chart.filter());
+ }
+ else {
+ lineChart.filterAll()
+ }
+ }))
+ .xAxis()
+ .tickFormat((v: string) => v);
-rowChart.width(340)
- .height(850)
- .dimension(cityDimension)
- .group(cityGroup)
- .renderLabel(true)
- .colors(["#a60000","#ff0000", "#ff4040","#ff7373","#67e667","#39e639","#00cc00"])
- .colorDomain([0, 0])
- .renderlet(function (chart) {
- bubbleChart.filter(chart.filter());
- })
- .on("filtered", function (chart) {
- dc.events.trigger(function () {
- bubbleChart.filter(chart.filter());
- });
- });
+ console.log(startValueGroup.top(1)[0].value);
+ lineChart
+ .width(230)
+ .height(200)
+ .dimension(startValue)
+ .group(startValueGroup)
+ .x(d3.scale.linear().domain([0.5, 5.5]))
+ .valueAccessor((d: any) => d.value)
+ .renderHorizontalGridLines(true)
+ .elasticY(true)
+ .xAxis()
+ .tickFormat((v: string) => v);
-dataTable.width(800).height(800)
- .dimension(businessDimension)
- .group(function(d:Object) { return "List of all Selected Businesses"
- })
- .size(100)
- .columns([
- function(d) { return d.name; },
- function(d) { return d.city; },
- function(d) { return d.stars; },
- function(d) { return d.review_count; },
- function(d) { return 'Map"}
- ])
- .sortBy(function(d){ return d.stars; })
- // (optional) sort order, :default ascending
- .order(d3.ascending);
-/********************************************************
-* *
-* Step6: Render the Charts *
-* *
-********************************************************/
-
- dc.renderAll();
+ rowChart
+ .width(340)
+ .height(850)
+ .dimension(cityDimension)
+ .group(cityGroup)
+ .renderLabel(true)
+ .colors(["#a60000","#ff0000", "#ff4040","#ff7373","#67e667","#39e639","#00cc00"])
+ .colorDomain([0, 0])
+ .renderlet((chart: DC.RowChart) => bubbleChart.filter(chart.filter()))
+ .on("filtered", (chart: DC.RowChart) =>
+ dc.events.trigger(() =>
+ bubbleChart.filter(chart.filter())));
+
+ dataTable
+ .width(800)
+ .height(800)
+ .dimension(businessDimension)
+ .group((d: any) => "List of all Selected Businesses")
+ .size(100)
+ .columns([
+ (d: IYelpData) => d.name,
+ (d: IYelpData) => d.city,
+ (d: IYelpData) => d.stars,
+ (d: IYelpData) => d.review_count,
+ (d: IYelpData) => 'Map"
+ ])
+ .sortBy((d: IYelpData) => d.stars)
+ // (optional) sort order, :default ascending
+ .order(d3.ascending);
+ /********************************************************
+ * *
+ * Step6: Render the Charts *
+ * *
+ ********************************************************/
+
+ dc.renderAll();
});
diff --git a/dcjs/dc.d.ts b/dcjs/dc.d.ts
new file mode 100644
index 0000000000..5a83b5c7cc
--- /dev/null
+++ b/dcjs/dc.d.ts
@@ -0,0 +1,433 @@
+// Type definitions for DCJS
+// Project: https://github.com/dc-js/dc.js
+// Definitions by: hans windhoff , matt traynham
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+// this makes only sense together with d3 and crossfilter so you need the d3.d.ts and crossfilter.d.ts files
+
+///
+///
+
+declare module DC {
+ // helper for get/set situation
+ export interface IGetSet {
+ (): T;
+ (t: T): V;
+ }
+
+ export interface IBiGetSet {
+ (): T;
+ (t: T, r?: R): V;
+ }
+
+ export interface Accessor {
+ (datum: T, index?: number): V;
+ }
+
+ export interface UnitFunction {
+ (start: number, end: number, domain?: Array): number|Array;
+ }
+
+ export interface FloatPointUnits {
+ precision(precision: number): UnitFunction;
+ }
+
+ export interface Units {
+ integers: UnitFunction;
+ ordinal: UnitFunction;
+ fp: FloatPointUnits;
+ }
+
+ export interface Events {
+ trigger(fn: () => void, delay?: number): void;
+ }
+
+ export interface Errors {
+ Exception(msg: string): void;
+ InvalidStateException(msg: string): void;
+ }
+
+ export interface Filter {
+ isFiltered(value: any): boolean;
+ }
+
+ export interface Filters {
+ RangedFilter(low: any, high: any): Filter;
+ TwoDimensionalFilter(arr: Array): Filter;
+ RangedTwoDimensionalFilter(arr: Array): Filter;
+ }
+
+ export interface Logger {
+ enableDebugLog: boolean;
+ warn(msg: string): void;
+ debug(msg: string): void;
+ deprecate(fn: Function, msg: string): void;
+ }
+
+ export interface Printers {
+ filters(filters: Array): string;
+ filter(filter: any): string;
+ }
+
+ export interface Round {
+ floor(n: number): number;
+ ceil(n: number): number;
+ round(n: number): number;
+ }
+
+ export interface Utils {
+ printSingleValue(filter: any): string;
+ add(l: any, r: any): any;
+ subtract(l: any, r: any): any;
+ isNumber(n: any): boolean;
+ isFloat(n: any): boolean;
+ isInteger(n: any): boolean;
+ isNegligible(n: any): boolean;
+ clamp(n: number, min: number, max: number): number;
+ uniqueId(): number;
+ nameToId(name: string): string;
+ appendOrSelect(parent: D3.Selection, selector: string, tag: any): D3.Selection;
+ safeNumber(n: any): number;
+ }
+
+ export interface Legend {
+ x: IGetSet;
+ y: IGetSet;
+ gap: IGetSet;
+ itemHeight: IGetSet;
+ horizontal: IGetSet;
+ legendWidth: IGetSet;
+ itemWidth: IGetSet;
+ autoItemWidth: IGetSet;
+ render: () => void;
+ }
+
+ export interface BaseMixin {
+ width: IGetSet;
+ height: IGetSet;
+ minWidth: IGetSet;
+ minHeight: IGetSet;
+ dimension: IGetSet;
+ data: IGetSet<(group: any) => Array, T>;
+ group: IGetSet;
+ ordering: IGetSet, T>;
+ filterAll(): void;
+ select(selector: D3.Selection|string): D3.Selection;
+ selectAll(selector: D3.Selection|string): D3.Selection;
+ anchor(anchor: BaseMixin|D3.Selection|string, chartGroup?: string): D3.Selection;
+ anchorName(): string;
+ svg: IGetSet;
+ resetSvg(): void;
+ filterPrinter: IGetSet<(filters: Array) => string, T>;
+ turnOnControls(): void;
+ turnOffControls(): void;
+ transitionDuration: IGetSet;
+ render(): void;
+ redraw(): void;
+ redrawGroup(): void;
+ hasFilterHandler: IGetSet<(filters: Array, filter: any) => boolean, T>;
+ hasFilter(filter?: any): boolean;
+ removeFilterHandler: IGetSet<(filters: Array) => Array, T>;
+ addFilterHandler: IGetSet<(filters: Array) => Array, T>;
+ resetFilterHandler: IGetSet<(filters: Array) => Array, T>;
+ filter: IGetSet;
+ filters(): Array;
+ onClick(datum: any): void;
+ filterHandler: IGetSet<(dimension: any, filter: any) => any, T>;
+ keyAccessor: IGetSet, T>;
+ valueAccessor: IGetSet, T>;
+ label: IGetSet, T>;
+ renderLabel: IGetSet;
+ title: IGetSet, T>;
+ renderTitle: IGetSet;
+ chartGroup: IGetSet;
+ expireCache(): T;
+ legend: IGetSet