diff --git a/dcjs/dc.d.ts b/dcjs/dc.d.ts new file mode 100644 index 0000000000..ca4f8fdc85 --- /dev/null +++ b/dcjs/dc.d.ts @@ -0,0 +1,198 @@ +// Type definitions for DCJS +// Project: https://github.com/dc-js +// Definitions by: hans windhoff +// 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 + interface IGetSet { + (): T; + (T): V; + } + + export interface IBaseChart { + width: IGetSet; + height: IGetSet; + minWidth: IGetSet; + minHeight: IGetSet; + dimension: IGetSet; + group: IGetSet; // not sure here + transitionDuration: IGetSet; + colors: IGetSet; + keyAccessor: IGetSet<(d) => number, T>; + valueAccessor: IGetSet<(d) => number, T>; + label: IGetSet<(any) => string, T>; + renderLabel: IGetSet; + renderlet: (fnctn: (T) => void) => T; + title: IGetSet<(any) => string, T>; + filter: IGetSet; + filterAll: () => void; + expireCache: () => void; + legend: (ILegendwidget) => T; + chartID: () => number; + options: (Object)=>void ; + select: (selector: D3.Selection) => D3.Selection; + selectAll: (selector: D3.Selection) => D3.Selection; + } + + export interface IEvents { + trigger(fnctn: () => void, delay?: number); + } + + export var events: IEvents; + + export interface IListener { + on: (eventName: string, fnctn: (IChart) => void) => T; + } + + export interface ImarginObj { + top: number; + right: number; + bottom: number; + left: number; + + } + + export interface IMarginable { + margins: IGetSet; + } + + // abstract interfaces + export interface IAbstractColorChart { + colorDomain: IGetSet; + } + export interface IAbstractStackableChart { + stack: (group, name?, retriever?) => T; + } + + export interface IAbstractCoordinateGridChart { + x: IGetSet; + y: IGetSet; + elasticY: IGetSet; + xAxis: IGetSet; + yAxis: IGetSet; + yAxisPadding: IGetSet; + xAxisPadding: IGetSet; + renderHorizontalGridLines: IGetSet; + + } + + export interface IAbstractBubblechart { + r: IGetSet; + radiusValueAccessor: IGetSet<(d) => number, T>; + } + + + + // function interfaces + export interface columnFunction { + (any): any; + } + export interface sortbyFunction { + (any): any; + } + export interface orderFunction { + (a: T, b: T): number; + } + + + // chart interfaces + export interface ILegendwidget { + x: IGetSet; + y: IGetSet; + gap: IGetSet; + itemHeight: IGetSet; + horizontal: IGetSet; + legendWidth: IGetSet; + itemWidth: IGetSet; + } + + export interface IBubblechart extends + IBaseChart, + IAbstractColorChart, + IAbstractBubblechart, + IAbstractCoordinateGridChart, + IMarginable, + IListener { + } + + export interface IPiechart extends + IBaseChart, + IAbstractColorChart, + IAbstractBubblechart, + IAbstractCoordinateGridChart, + IMarginable, + IListener { + radius: IGetSet; + minAngleForLabel: IGetSet; + + } + + export interface IBarchart extends + IBaseChart, + IAbstractStackableChart, + IAbstractCoordinateGridChart, + IMarginable, + IListener { + centerBar: (boolean) => IBarchart; + gap: (gapBetweenBars: number) => IBarchart; + } + + export interface ILinechart extends + IBaseChart, + IAbstractStackableChart, + IAbstractCoordinateGridChart, + IMarginable, + IListener { + } + + + export interface IDatachart extends + IBaseChart, + IAbstractStackableChart, + IAbstractCoordinateGridChart, + IMarginable, + IListener { + size: IGetSet; + columns: IGetSet; + sortBy: IGetSet; + order: IGetSet; + } + + + export interface IRowchart extends + IBaseChart, + IAbstractColorChart, + IAbstractStackableChart, + IAbstractCoordinateGridChart, + IMarginable, + IListener { + } + + + + + // utilities + export interface IChartGroup { } + + export function filterAll(chartGroup?: IChartGroup): void; + export function renderAll(chartGroup?: IChartGroup); + export function redrawAll(chartGroup?: IChartGroup); + + + export function bubbleChart(cssSel: string): IBubblechart; + export function pieChart(cssSel: string): IPiechart; + export function barChart(cssSel: string): IBarchart; + export function lineChart(cssSel: string): ILinechart; + export function dataTable(cssSel: string): IDatachart; + export function rowChart(cssSel: string): IRowchart; + + +} \ No newline at end of file diff --git a/dcjs/dc.test.ts b/dcjs/dc.test.ts new file mode 100644 index 0000000000..6e2bf6f97e --- /dev/null +++ b/dcjs/dc.test.ts @@ -0,0 +1,244 @@ +/// +/// +/// + + +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[] +} + + +interface IYelpDataExtended { + 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 * +* * +********************************************************/ + +/******************************************************** +* * +* 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"); + +/******************************************************** +* * +* Step2: Run data through crossfilter * +* * +********************************************************/ +var ndx = crossfilter(yelp_data); + +/******************************************************** +* * +* Step3: Create Dimension that we'll need * +* * +********************************************************/ + + // 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}; + } + ); + + // for pieChart + var startValue = ndx.dimension(function (d) { + return d.stars*1.0; + }); + var startValueGroup = startValue.group(); + + // 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()); + }); + }); + ; + + +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(); + }); + }); + +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;}); + +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(function(d) { + return d.value; + }) + .renderHorizontalGridLines(true) + .elasticY(true) + .xAxis().tickFormat(function(v) {return 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()); + }); + }); + + +dataTable.width(800).height(800) + .dimension(businessDimension) + .group(function(d) { 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(); +});