From 5f14855c2bc9496958f4d8009938588ce5406c16 Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Mon, 3 Feb 2014 17:20:43 -0800 Subject: [PATCH 01/23] Added Bar Renderer Currently extends XYRenderer, but it's a bit clunky due to the assumptions in XYRenderer. Clean up during barnstorming... --- examples/demo.ts | 20 ++++++++++++--- examples/demo1.html | 2 ++ examples/exampleUtil.ts | 15 ++++++++++++ src/renderer.ts | 54 +++++++++++++++++++++++++++++++++++++++-- style.css | 3 +++ 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/examples/demo.ts b/examples/demo.ts index 851ab00306..71bcf3bf49 100644 --- a/examples/demo.ts +++ b/examples/demo.ts @@ -132,8 +132,8 @@ multichart.render(); // var bottomAxes = iterate(bottom, () => new xAxis(yScale, "bottom")) // } -var svg1 = d3.select("#svg5"); -svg1.attr("width", 500).attr("height", 500); +var svg5 = d3.select("#svg5"); +svg5.attr("width", 500).attr("height", 500); var xScale = new LinearScale(); var yScale = new LinearScale(); var xAxis = new XAxis(xScale, "bottom"); @@ -153,11 +153,25 @@ var renderArea = new LineRenderer(data, xScale, yScale); var basicTable = new Table([[yAxisLeftTable, renderArea, yAxisRightTable], [null, xAxis, null]]); var title = new TitleLabel("bpIqd"); var outerTable = new Table([[title], [basicTable]]); -outerTable.anchor(svg1); +outerTable.anchor(svg5); outerTable.computeLayout(); outerTable.render(); +// bar renderer test +var svg6 = d3.select("#svg6"); +svg6.attr("width", 500).attr("height", 500); +var xScale = new LinearScale(); +var yScale = new LinearScale(); +var xAxis = new XAxis(xScale, "bottom"); +var yAxis = new YAxis(yScale, "left"); +var bucketData = makeRandomBucketData(10, 10, 80); + +var BarRenderArea = new BarRenderer(bucketData, xScale, yScale); +var basicTable = new Table([[yAxis, BarRenderArea], [null, xAxis]]) +basicTable.anchor(svg6); +basicTable.computeLayout(); +basicTable.render(); } // hackhack diff --git a/examples/demo1.html b/examples/demo1.html index 498d89712d..0f2050a52c 100644 --- a/examples/demo1.html +++ b/examples/demo1.html @@ -13,6 +13,8 @@

TSC with 2 axes

TSC with subplots, varying # of axes, and sparkline







+ +

Bar Renderer




diff --git a/examples/exampleUtil.ts b/examples/exampleUtil.ts index b4b04f1d46..f2d1d5d690 100644 --- a/examples/exampleUtil.ts +++ b/examples/exampleUtil.ts @@ -8,3 +8,18 @@ function makeRandomData(numPoints, scaleFactor=1): IDataset { data = _.sortBy(data, (d) => d.x); return {"data": data, "seriesName": "random-data"}; } + +function makeRandomBucketData(numBuckets: number, bucketWidth: number, maxValue = 10): IDataset { + var data = []; + for (var i=0; i < numBuckets; i++) { + data.push({ + x: i * bucketWidth, + x2: (i+1) * bucketWidth, + y: Math.round(Math.random() * maxValue) + }); + } + return { + "data": data, + "seriesName": "random-buckets" + }; +} diff --git a/src/renderer.ts b/src/renderer.ts index 2328d58db9..353a3a7695 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -42,8 +42,8 @@ class XYRenderer extends Renderer { public yScale: QuantitiveScale; private xAccessor: IAccessor; private yAccessor: IAccessor; - public xScaledAccessor: (datum: any) => number; - public yScaledAccessor: (datum: any) => number; + public xScaledAccessor: IAccessor; + public yScaledAccessor: IAccessor; constructor(dataset: IDataset, xScale: QuantitiveScale, yScale: QuantitiveScale, xAccessor?: IAccessor, yAccessor?: IAccessor) { super(dataset); this.xAccessor = (xAccessor != null) ? xAccessor : XYRenderer.defaultXAccessor; @@ -140,6 +140,56 @@ class CircleRenderer extends XYRenderer { } } +class BarRenderer extends XYRenderer { + private BAR_START_PADDING_PX = 1; + private BAR_END_PADDING_PX = 1; + + private x2Accessor: IAccessor; + public x2ScaledAccessor: IAccessor; + + constructor(dataset: IDataset, + xScale: QuantitiveScale, + yScale: QuantitiveScale, + xAccessor?: IAccessor, + x2Accessor?: IAccessor, + yAccessor?: IAccessor) { + super(dataset, xScale, yScale, xAccessor, yAccessor); + + var inRange = (x: number, a: number, b: number) => { + return (Math.min(a,b) <= x && x <= Math.max(a,b)); + } + + var yDomain = this.yScale.domain(); + if (!inRange(0, yDomain[0], yDomain[1])) { + var newMin = 0; + var newMax = 1.1 * yDomain[1]; + this.yScale.widenDomain([newMin, newMax]); // TODO: make this handle reversed scales + } + + this.x2Accessor = (x2Accessor != null) ? x2Accessor : (d: any) => d.x2; + this.x2ScaledAccessor = (datum: any) => xScale.scale(this.x2Accessor(datum)); + + var x2Extent = d3.extent(dataset.data, this.x2Accessor); + this.xScale.widenDomain(x2Extent); + } + + public render() { + super.render(); + var yRange = this.yScale.range(); + var maxScaledY = Math.max(yRange[0], yRange[1]); + + this.dataSelection = this.renderArea.selectAll("rect"); + this.dataSelection.data(this.dataset.data).enter() + .append("rect") + .attr("x", (d: any) => this.xScaledAccessor(d) + this.BAR_START_PADDING_PX) + .attr("y", this.yScaledAccessor) + .attr("width", (d: any) => (this.x2ScaledAccessor(d) - this.xScaledAccessor(d) + - this.BAR_START_PADDING_PX - this.BAR_END_PADDING_PX)) + .attr("height", (d: any) => maxScaledY - this.yScaledAccessor(d)); + + } +} + // class ResizingCircleRenderer extends CircleRenderer { // public transform(translate: number[], scale: number) { // this.renderArea.selectAll("circle").attr("r", 0.5/scale); diff --git a/style.css b/style.css index 2ff6501e22..772376b46b 100644 --- a/style.css +++ b/style.css @@ -47,6 +47,9 @@ div { circle { fill: steelblue; } +rect { + fill: steelblue; +} .table-rect { fill: none; From ac5710d4b7b5eac786ae13a6fdfbbe4c98b746f1 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Mon, 3 Feb 2014 18:17:28 -0800 Subject: [PATCH 02/23] Initial prototype of demo day code --- examples/demo-day.html | 18 ++++++++++++ examples/demoDay.ts | 67 ++++++++++++++++++++++++++++++++++++++++++ index.html | 1 + 3 files changed, 86 insertions(+) create mode 100644 examples/demo-day.html create mode 100644 examples/demoDay.ts diff --git a/examples/demo-day.html b/examples/demo-day.html new file mode 100644 index 0000000000..fa228a95ee --- /dev/null +++ b/examples/demo-day.html @@ -0,0 +1,18 @@ + + + + + + +

Basic TSC

+


+ + + + + + + + + + diff --git a/examples/demoDay.ts b/examples/demoDay.ts new file mode 100644 index 0000000000..8b34fc7570 --- /dev/null +++ b/examples/demoDay.ts @@ -0,0 +1,67 @@ +/// + +/// +/// +/// +/// +/// +/// +/// + +if (( window).demoName === "demo-day") { + +// First we make the scatterplot that shows the full dataset + +function makeScatterPlotWithSparkline(data) { + var s: any = {}; + s.xScale = new LinearScale(); + s.yScale = new LinearScale(); + s.leftAxis = new YAxis(s.yScale, "left"); + s.xAxis = new XAxis(s.xScale, "bottom"); + s.renderer = new CircleRenderer(data, s.xScale, s.yScale); + s.xSpark = new LinearScale(); + s.ySpark = new LinearScale(); + s.sparkline = new CircleRenderer(data, s.xSpark, s.ySpark); + s.sparkline.rowWeight(0.25); + var r1 = [s.leftAxis, s.renderer]; + var r2 = [null, s.xAxis]; + var r3 = [null, s.sparkline]; + s.table = new Table([r1,r2,r3]); + return s; +} + +function makeHistograms(data) { + var h: any = {}; + h.xScale1 = new LinearScale(); + h.xScale2 = new LinearScale(); + h.yScale = new LinearScale(); + var data1 = data; + var data2 = data; + h.renderer1 = new BarRenderer(data1, h.xScale1, h.yScale); + h.renderer2 = new BarRenderer(data2, h.xScale2, h.yScale); + h.yAxis = new YAxis(h.yScale, "right"); + h.xAxis1 = new XAxis(h.xScale1, "bottom"); + h.xAxis2 = new XAxis(h.xScale2, "bottom"); + var r1 = [h.renderer1, h.renderer2, h.yAxis]; + var r2 = [h.xAxis1, h.xAxis2, null]; + h.table = new Table([r1, r2]); + return h; +} + +function makeScatterHisto(data) { + var s = makeScatterPlotWithSparkline(data); + var h = makeHistograms(data); + var r = [s.table, h.table]; + var table = new Table([r]); + return table; +} + +var chart = makeScatterHisto({seriesName: "foo", data: []}); + +var svg = d3.select("#table"); +chart.anchor(svg); +chart.computeLayout(); +chart.render(); + + +} diff --git a/index.html b/index.html index 5e155f86bf..2e0be02d17 100644 --- a/index.html +++ b/index.html @@ -11,5 +11,6 @@

Tests

The old demo

Sparkline demo

+

Demo Day

From 38b4ad53cf92ee5eddb1ddcc7d055881fb798c7f Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Mon, 3 Feb 2014 18:22:17 -0800 Subject: [PATCH 03/23] Plug some example data into the DemoDay display --- examples/demoDay.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 8b34fc7570..04e8c87c51 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -50,13 +50,18 @@ function makeHistograms(data) { function makeScatterHisto(data) { var s = makeScatterPlotWithSparkline(data); - var h = makeHistograms(data); + var h = makeHistograms(makeRandomBucketData(5, 5, 20)); var r = [s.table, h.table]; var table = new Table([r]); + table.colPadding = 10; return table; } -var chart = makeScatterHisto({seriesName: "foo", data: []}); +var data1 = makeRandomData(1000, 1).data; +var data2 = makeRandomData(1000, 3).data; +var data = {seriesName: "randomData", data: data1.concat(data2)} + +var chart = makeScatterHisto(data); var svg = d3.select("#table"); chart.anchor(svg); From 4078409f5f9eb609257b1fe510da26fb9795e368 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 11:06:03 -0800 Subject: [PATCH 04/23] Histogram works with a binning function, throws some errors though --- examples/demoDay.ts | 54 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 04e8c87c51..7f2ee9eb6c 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -35,10 +35,12 @@ function makeHistograms(data) { h.xScale1 = new LinearScale(); h.xScale2 = new LinearScale(); h.yScale = new LinearScale(); - var data1 = data; - var data2 = data; - h.renderer1 = new BarRenderer(data1, h.xScale1, h.yScale); - h.renderer2 = new BarRenderer(data2, h.xScale2, h.yScale); + var data1 = binByVal(data.data, (d) => d.x, [0,1], 10); + var data2 = binByVal(data.data, (d) => d.y, [0,1], 10); + var ds1 = {data: data1, seriesName: "xVals"} + var ds2 = {data: data2, seriesName: "yVals"} + h.renderer1 = new BarRenderer(ds1, h.xScale1, h.yScale); + h.renderer2 = new BarRenderer(ds2, h.xScale2, h.yScale); h.yAxis = new YAxis(h.yScale, "right"); h.xAxis1 = new XAxis(h.xScale1, "bottom"); h.xAxis2 = new XAxis(h.xScale2, "bottom"); @@ -50,17 +52,55 @@ function makeHistograms(data) { function makeScatterHisto(data) { var s = makeScatterPlotWithSparkline(data); - var h = makeHistograms(makeRandomBucketData(5, 5, 20)); + var h = makeHistograms(data); var r = [s.table, h.table]; var table = new Table([r]); table.colPadding = 10; return table; } -var data1 = makeRandomData(1000, 1).data; -var data2 = makeRandomData(1000, 3).data; +function filterSelectedData(data) { + var p = (d) => d.selected; + return data.filter(p); +} + +function binByVal(data: any[], accessor: IAccessor, range=[0,100], nBins=10) { + if (accessor == null) {accessor = (d) => d.x}; + var min = range[0]; + var max = range[1]; + var binBeginnings = _.range(nBins).map((n) => n * max / nBins); + var binEndings = _.range(nBins).map((n) => (n+1) * max / nBins); + var counts = new Array(nBins); + _.range(nBins).forEach((b, i) => counts[i] = 0); + data.forEach((d) => { + var v = accessor(d); + var found = false; + for (var i=0; i { + var bin: any = {}; + bin.x = binBeginnings[i]; + bin.x2 = binEndings[i]; + bin.y = count; + return bin; + }) + return bins; +} + +var data1 = makeRandomData(5, 1).data; +var data2 = makeRandomData(5, 3).data; var data = {seriesName: "randomData", data: data1.concat(data2)} +var smallData = makeRandomData(10).data; +var smallBins = binByVal(smallData, null, [0,1], 4); + var chart = makeScatterHisto(data); var svg = d3.select("#table"); From c411904192f59ee5403d187b8f18549b139e16ae Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Tue, 4 Feb 2014 11:09:57 -0800 Subject: [PATCH 05/23] Added data() call to Renderer You can update data with the data() call. Bar Renderer now transitions if re-rendering with new data. --- examples/demo.ts | 6 ++++++ examples/demo1.html | 7 +++++-- src/renderer.ts | 22 +++++++++++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/examples/demo.ts b/examples/demo.ts index 71bcf3bf49..ac69bd8e08 100644 --- a/examples/demo.ts +++ b/examples/demo.ts @@ -168,10 +168,16 @@ var yAxis = new YAxis(yScale, "left"); var bucketData = makeRandomBucketData(10, 10, 80); +var replacementData = makeRandomBucketData(5, 20, 80); + var BarRenderArea = new BarRenderer(bucketData, xScale, yScale); var basicTable = new Table([[yAxis, BarRenderArea], [null, xAxis]]) basicTable.anchor(svg6); basicTable.computeLayout(); basicTable.render(); +window.BarRenderArea = BarRenderArea; +window.replacementData = replacementData; +console.log("type 'window.BarRenderArea.data(replacementData).render()'' to see new data"); + } // hackhack diff --git a/examples/demo1.html b/examples/demo1.html index 0f2050a52c..6e1fdaacf1 100644 --- a/examples/demo1.html +++ b/examples/demo1.html @@ -4,6 +4,11 @@ + +

Bar Renderer

+


+ +

Basic TSC




Chartbag of timeseriescharts

@@ -14,8 +19,6 @@

TSC with subplots, varying # of axes, and sparkline







-

Bar Renderer

-


diff --git a/src/renderer.ts b/src/renderer.ts index 353a3a7695..8320b6f253 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -5,20 +5,27 @@ class Renderer extends Component { public CLASS_RENDERER_CONTAINER = "renderer-container"; + public dataset: IDataset; public renderArea: D3.Selection; public element: D3.Selection; public scales: Scale[]; constructor( - public dataset: IDataset + dataset: IDataset ) { super(); super.rowWeight(1); super.colWeight(1); + this.dataset = dataset; this.classed(this.CLASS_RENDERER_CONTAINER, true); } + public data(dataset: IDataset): Renderer { + this.dataset = dataset; + return this; + } + public zoom(translate, scale) { this.renderArea.attr("transform", "translate("+translate+") scale("+scale+")"); } @@ -178,15 +185,16 @@ class BarRenderer extends XYRenderer { var yRange = this.yScale.range(); var maxScaledY = Math.max(yRange[0], yRange[1]); - this.dataSelection = this.renderArea.selectAll("rect"); - this.dataSelection.data(this.dataset.data).enter() - .append("rect") - .attr("x", (d: any) => this.xScaledAccessor(d) + this.BAR_START_PADDING_PX) + var dataSelection = this.renderArea.selectAll("rect").data(this.dataset.data); + dataSelection.enter().append("rect"); + dataSelection.transition().attr("x", (d: any) => this.xScaledAccessor(d) + this.BAR_START_PADDING_PX) .attr("y", this.yScaledAccessor) .attr("width", (d: any) => (this.x2ScaledAccessor(d) - this.xScaledAccessor(d) - this.BAR_START_PADDING_PX - this.BAR_END_PADDING_PX)) - .attr("height", (d: any) => maxScaledY - this.yScaledAccessor(d)); - + .attr("height", (d: any) => { + return (maxScaledY - this.yScaledAccessor(d)); + }); + dataSelection.exit().remove(); } } From aee551cfaecc1309da0cf84cd3a5e445f3f9c249 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 11:20:30 -0800 Subject: [PATCH 06/23] Add function to return indices of selected data, for use in demo day --- src/interaction.ts | 7 ++++++- src/renderer.ts | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/interaction.ts b/src/interaction.ts index f2e4397eca..de613bcc10 100644 --- a/src/interaction.ts +++ b/src/interaction.ts @@ -82,7 +82,8 @@ class AreaInteraction extends Interaction { constructor( private rendererComponent: XYRenderer, public areaCallback?: (a: FullSelectionArea) => any, - public selectionCallback?: (a: D3.Selection) => any + public selectionCallback?: (a: D3.Selection) => any, + public indicesCallback?: (a: number[]) => any ) { super(rendererComponent); this.dragBehavior = d3.behavior.drag(); @@ -137,6 +138,10 @@ class AreaInteraction extends Interaction { var selection = this.rendererComponent.getSelectionFromArea(fullArea); this.selectionCallback(selection); } + if (this.indicesCallback != null) { + var indices = this.rendererComponent.getDataIndicesFromArea(fullArea); + this.indicesCallback(indices); + } } public anchor(hitBox: D3.Selection) { diff --git a/src/renderer.ts b/src/renderer.ts index 353a3a7695..6eeda35797 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -92,6 +92,26 @@ class XYRenderer extends Renderer { return selection; } + public getDataIndicesFromArea(area: FullSelectionArea) { + var dataArea = area.data; + var inRange = (x: number, a: number, b: number) => { + return (Math.min(a,b) <= x && x <= Math.max(a,b)); + } + var filterFunction = (d: any) => { + var x = this.xAccessor(d); + var y = this.yAccessor(d); + // use inRange rather than direct comparison to avoid thinking about scale inversion + return inRange(x, dataArea.xMin, dataArea.xMax) && inRange(y, dataArea.yMin, dataArea.yMax);; + } + var results = []; + this.dataset.data.forEach((d, i) => { + if (filterFunction(d)) { + results.push(i); + } + }); + return results; + } + public rescale() { if (this.element != null) { this.renderArea.remove(); From 825b055a8e0c2ad2a6764071ad108b69c2363635 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 11:31:43 -0800 Subject: [PATCH 07/23] Add coordinator logic, not yet called, need to merge in renderer.data call --- examples/demoDay.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 7f2ee9eb6c..d0915d6fc8 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -30,13 +30,13 @@ function makeScatterPlotWithSparkline(data) { return s; } -function makeHistograms(data) { +function makeHistograms(data: any[]) { var h: any = {}; h.xScale1 = new LinearScale(); h.xScale2 = new LinearScale(); h.yScale = new LinearScale(); - var data1 = binByVal(data.data, (d) => d.x, [0,1], 10); - var data2 = binByVal(data.data, (d) => d.y, [0,1], 10); + var data1 = binByVal(data, (d) => d.x, [0,1], 10); + var data2 = binByVal(data, (d) => d.y, [0,1], 10); var ds1 = {data: data1, seriesName: "xVals"} var ds2 = {data: data2, seriesName: "yVals"} h.renderer1 = new BarRenderer(ds1, h.xScale1, h.yScale); @@ -52,7 +52,7 @@ function makeHistograms(data) { function makeScatterHisto(data) { var s = makeScatterPlotWithSparkline(data); - var h = makeHistograms(data); + var h = makeHistograms(data.data); var r = [s.table, h.table]; var table = new Table([r]); table.colPadding = 10; @@ -94,6 +94,24 @@ function binByVal(data: any[], accessor: IAccessor, range=[0,100], nBins=10) { return bins; } +function coordinator(scatterplot: any, histogram: any, dataset: IDataset) { + var data = dataset.data; + var dataCallback = (selectedIndices: number[]) => { + var selectedData = grabIndices(data, selectedIndices); + var xBins = binByVal(selectedData, (d) => d.x, [0,1], 5); + var yBins = binByVal(selectedData, (d) => d.y, [0,3], 5); + histogram.renderer1.data({seriesName: "xBins", data: xBins}) + histogram.renderer2.data({seriesName: "yBins", data: yBins}) + histogram.renderer1.render(); + histogram.renderer2.render(); + }; + var areaInteraction = new AreaInteraction(scatterplot.renderer, null, null, dataCallback); +} + +function grabIndices(itemsToGrab: any[], indices: number[]) { + return indices.map((i) => itemsToGrab[i]); +} + var data1 = makeRandomData(5, 1).data; var data2 = makeRandomData(5, 3).data; var data = {seriesName: "randomData", data: data1.concat(data2)} From 8698185d51ed6ef7bdd889d818654bbf36b8b7ce Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Tue, 4 Feb 2014 11:33:07 -0800 Subject: [PATCH 08/23] Fixed off-by-one bug in binByVal. --- examples/demo.ts | 5 ----- examples/demoDay.ts | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/demo.ts b/examples/demo.ts index ac69bd8e08..914a5b7a3f 100644 --- a/examples/demo.ts +++ b/examples/demo.ts @@ -175,9 +175,4 @@ var basicTable = new Table([[yAxis, BarRenderArea], [null, xAxis]]) basicTable.anchor(svg6); basicTable.computeLayout(); basicTable.render(); - -window.BarRenderArea = BarRenderArea; -window.replacementData = replacementData; -console.log("type 'window.BarRenderArea.data(replacementData).render()'' to see new data"); - } // hackhack diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 7f2ee9eb6c..1be4e8c3c3 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -82,7 +82,7 @@ function binByVal(data: any[], accessor: IAccessor, range=[0,100], nBins=10) { break; } } - if (!found) {counts[i]++}; + if (!found) {counts[counts.length-1]++}; }); var bins = counts.map((count, i) => { var bin: any = {}; From 09a1eb3de0f592806a01056a63ee70337b30669a Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Tue, 4 Feb 2014 11:52:19 -0800 Subject: [PATCH 09/23] Reworked layout in demo-day demo. --- examples/demoDay.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 4e79b74f47..d3ec18777c 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -33,20 +33,24 @@ function makeScatterPlotWithSparkline(data) { function makeHistograms(data: any[]) { var h: any = {}; h.xScale1 = new LinearScale(); - h.xScale2 = new LinearScale(); - h.yScale = new LinearScale(); + h.yScale1 = new LinearScale(); var data1 = binByVal(data, (d) => d.x, [0,1], 10); - var data2 = binByVal(data, (d) => d.y, [0,1], 10); var ds1 = {data: data1, seriesName: "xVals"} - var ds2 = {data: data2, seriesName: "yVals"} - h.renderer1 = new BarRenderer(ds1, h.xScale1, h.yScale); - h.renderer2 = new BarRenderer(ds2, h.xScale2, h.yScale); - h.yAxis = new YAxis(h.yScale, "right"); + h.renderer1 = new BarRenderer(ds1, h.xScale1, h.yScale1); h.xAxis1 = new XAxis(h.xScale1, "bottom"); + h.yAxis1 = new YAxis(h.yScale1, "right"); + var table1 = new Table([[h.renderer1, h.yAxis1], [h.xAxis1, null]]); + + h.xScale2 = new LinearScale(); + h.yScale2 = new LinearScale(); + var data2 = binByVal(data, (d) => d.y, [0,1], 10); + var ds2 = {data: data2, seriesName: "yVals"} + h.renderer2 = new BarRenderer(ds2, h.xScale2, h.yScale2); h.xAxis2 = new XAxis(h.xScale2, "bottom"); - var r1 = [h.renderer1, h.renderer2, h.yAxis]; - var r2 = [h.xAxis1, h.xAxis2, null]; - h.table = new Table([r1, r2]); + h.yAxis2 = new YAxis(h.yScale2, "right"); + var table2 = new Table([[h.renderer2, h.yAxis2], [h.xAxis2, null]]); + + h.table = new Table([[table1], [table2]]); return h; } From 11c1784a3f384bf65816979c0aad91cf2e41993b Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 11:35:26 -0800 Subject: [PATCH 10/23] Missing data call, gonna look into this --- examples/demoDay.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index d3ec18777c..59dfde9e27 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -60,7 +60,8 @@ function makeScatterHisto(data) { var r = [s.table, h.table]; var table = new Table([r]); table.colPadding = 10; - return table; + + return {table: table, s: s, h: h}; } function filterSelectedData(data) { @@ -125,10 +126,12 @@ var smallBins = binByVal(smallData, null, [0,1], 4); var chart = makeScatterHisto(data); +coordinator(chart.s, chart.h, data); + var svg = d3.select("#table"); -chart.anchor(svg); -chart.computeLayout(); -chart.render(); +chart.table.anchor(svg); +chart.table.computeLayout(); +chart.table.render(); } From f304bec01de2628e25c4f4f078d463e23bb699c3 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 11:52:42 -0800 Subject: [PATCH 11/23] Change demo example to use normally distributed data --- examples/demoDay.ts | 20 ++++++++++---------- examples/exampleUtil.ts | 11 +++++++++++ src/renderer.ts | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 59dfde9e27..4d679e4e21 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -117,21 +117,21 @@ function grabIndices(itemsToGrab: any[], indices: number[]) { return indices.map((i) => itemsToGrab[i]); } -var data1 = makeRandomData(5, 1).data; -var data2 = makeRandomData(5, 3).data; -var data = {seriesName: "randomData", data: data1.concat(data2)} +var clump1 = makeNormallyDistributedData(300, -10, 5, 7, 1); +var clump2 = makeNormallyDistributedData(300, 2, 0.5, 3, 3); +var clump3 = makeNormallyDistributedData(400, 5, 10, -3, 9); -var smallData = makeRandomData(10).data; -var smallBins = binByVal(smallData, null, [0,1], 4); +var clumpData = clump1.concat(clump2, clump3); +var dataset = {seriesName: "clumpedData", data: clumpData}; -var chart = makeScatterHisto(data); +var chartSH = makeScatterHisto(dataset); -coordinator(chart.s, chart.h, data); +coordinator(chartSH.s, chartSH.h, dataset); var svg = d3.select("#table"); -chart.table.anchor(svg); -chart.table.computeLayout(); -chart.table.render(); +chartSH.table.anchor(svg); +chartSH.table.computeLayout(); +chartSH.table.render(); } diff --git a/examples/exampleUtil.ts b/examples/exampleUtil.ts index f2d1d5d690..592f4b9a0a 100644 --- a/examples/exampleUtil.ts +++ b/examples/exampleUtil.ts @@ -9,6 +9,17 @@ function makeRandomData(numPoints, scaleFactor=1): IDataset { return {"data": data, "seriesName": "random-data"}; } +function makeNormallyDistributedData(n=100, xMean?, yMean?, xStdDev?, yStdDev?) { + var results = []; + var x = d3.random.normal(xMean, xStdDev); + var y = d3.random.normal(yMean, yStdDev); + for (var i=0; i Date: Tue, 4 Feb 2014 11:54:14 -0800 Subject: [PATCH 12/23] Mess around with data some more --- examples/demoDay.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 4d679e4e21..7202480aa1 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -120,8 +120,9 @@ function grabIndices(itemsToGrab: any[], indices: number[]) { var clump1 = makeNormallyDistributedData(300, -10, 5, 7, 1); var clump2 = makeNormallyDistributedData(300, 2, 0.5, 3, 3); var clump3 = makeNormallyDistributedData(400, 5, 10, -3, 9); +var clump4 = makeNormallyDistributedData(200, -25, 1, 20, 5); -var clumpData = clump1.concat(clump2, clump3); +var clumpData = clump1.concat(clump2, clump3, clump4); var dataset = {seriesName: "clumpedData", data: clumpData}; var chartSH = makeScatterHisto(dataset); From eb4310e6d0cd4f3089841b9e4fe823467f65c64e Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 12:11:27 -0800 Subject: [PATCH 13/23] Improvements to demos, bins now scale properly --- examples/demoDay.ts | 45 +++++++++++++++++++++++++++++++-------------- src/renderer.ts | 6 ++++-- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 7202480aa1..cb429c7efe 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -12,6 +12,8 @@ if (( window).demoName === "demo-day") { // First we make the scatterplot that shows the full dataset + +var N_BINS = 3; function makeScatterPlotWithSparkline(data) { var s: any = {}; s.xScale = new LinearScale(); @@ -32,18 +34,22 @@ function makeScatterPlotWithSparkline(data) { function makeHistograms(data: any[]) { var h: any = {}; - h.xScale1 = new LinearScale(); + var xExtent = d3.extent(data, (d) => d.x); + h.xScale1 = new LinearScale().domain(xExtent); h.yScale1 = new LinearScale(); - var data1 = binByVal(data, (d) => d.x, [0,1], 10); + h.bin1 = makeBinFunction((d) => d.x, xExtent, N_BINS); + var data1 = h.bin1(data); var ds1 = {data: data1, seriesName: "xVals"} h.renderer1 = new BarRenderer(ds1, h.xScale1, h.yScale1); h.xAxis1 = new XAxis(h.xScale1, "bottom"); h.yAxis1 = new YAxis(h.yScale1, "right"); var table1 = new Table([[h.renderer1, h.yAxis1], [h.xAxis1, null]]); - h.xScale2 = new LinearScale(); + var yExtent = d3.extent(data, (d) => d.y); + h.xScale2 = new LinearScale().domain(yExtent); h.yScale2 = new LinearScale(); - var data2 = binByVal(data, (d) => d.y, [0,1], 10); + h.bin2 = makeBinFunction((d) => d.y, yExtent, N_BINS); + var data2 = h.bin2(data); var ds2 = {data: data2, seriesName: "yVals"} h.renderer2 = new BarRenderer(ds2, h.xScale2, h.yScale2); h.xAxis2 = new XAxis(h.xScale2, "bottom"); @@ -69,12 +75,17 @@ function filterSelectedData(data) { return data.filter(p); } +function makeBinFunction(accessor, range, nBins) { + return (d) => binByVal(d, accessor, range, nBins); +} + function binByVal(data: any[], accessor: IAccessor, range=[0,100], nBins=10) { if (accessor == null) {accessor = (d) => d.x}; var min = range[0]; var max = range[1]; - var binBeginnings = _.range(nBins).map((n) => n * max / nBins); - var binEndings = _.range(nBins).map((n) => (n+1) * max / nBins); + var spread = max-min; + var binBeginnings = _.range(nBins).map((n) => min + n * spread / nBins); + var binEndings = _.range(nBins) .map((n) => min + (n+1) * spread / nBins); var counts = new Array(nBins); _.range(nBins).forEach((b, i) => counts[i] = 0); data.forEach((d) => { @@ -99,12 +110,18 @@ function binByVal(data: any[], accessor: IAccessor, range=[0,100], nBins=10) { return bins; } -function coordinator(scatterplot: any, histogram: any, dataset: IDataset) { +function coordinator(chart: any, dataset: IDataset) { + var scatterplot = chart.s; + var histogram = chart.h; + chart.c = {}; + var data = dataset.data; var dataCallback = (selectedIndices: number[]) => { var selectedData = grabIndices(data, selectedIndices); - var xBins = binByVal(selectedData, (d) => d.x, [0,1], 5); - var yBins = binByVal(selectedData, (d) => d.y, [0,3], 5); + var xBins = histogram.bin1(selectedData); + var yBins = histogram.bin2(selectedData); + chart.c.xBins = xBins; + chart.c.yBins = yBins; histogram.renderer1.data({seriesName: "xBins", data: xBins}) histogram.renderer2.data({seriesName: "yBins", data: yBins}) histogram.renderer1.render(); @@ -117,17 +134,17 @@ function grabIndices(itemsToGrab: any[], indices: number[]) { return indices.map((i) => itemsToGrab[i]); } -var clump1 = makeNormallyDistributedData(300, -10, 5, 7, 1); -var clump2 = makeNormallyDistributedData(300, 2, 0.5, 3, 3); -var clump3 = makeNormallyDistributedData(400, 5, 10, -3, 9); -var clump4 = makeNormallyDistributedData(200, -25, 1, 20, 5); +var clump1 = makeNormallyDistributedData(3, -10, 5, 7, 1); +var clump2 = makeNormallyDistributedData(3, 2, 0.5, 3, 3); +var clump3 = makeNormallyDistributedData(4, 5, 10, -3, 9); +var clump4 = makeNormallyDistributedData(2, -25, 1, 20, 5); var clumpData = clump1.concat(clump2, clump3, clump4); var dataset = {seriesName: "clumpedData", data: clumpData}; var chartSH = makeScatterHisto(dataset); -coordinator(chartSH.s, chartSH.h, dataset); +coordinator(chartSH, dataset); var svg = d3.select("#table"); chartSH.table.anchor(svg); diff --git a/src/renderer.ts b/src/renderer.ts index 3c7d634b50..a14b42bf94 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -152,8 +152,10 @@ class LineRenderer extends XYRenderer { } class CircleRenderer extends XYRenderer { - constructor(dataset: IDataset, xScale: QuantitiveScale, yScale: QuantitiveScale, xAccessor?: IAccessor, yAccessor?: IAccessor) { + public size: number; + constructor(dataset: IDataset, xScale: QuantitiveScale, yScale: QuantitiveScale, xAccessor?: IAccessor, yAccessor?: IAccessor, size=3) { super(dataset, xScale, yScale, xAccessor, yAccessor); + this.size = size; } public render() { @@ -163,7 +165,7 @@ class CircleRenderer extends XYRenderer { .append("circle") .attr("cx", this.xScaledAccessor) .attr("cy", this.yScaledAccessor) - .attr("r", 1); + .attr("r", this.size); } } From 194ced0b2a44cb6f5b194646e76f175e12e06d77 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 12:17:22 -0800 Subject: [PATCH 14/23] Histograms look nice. Scales update. Sparkline zooms. Things are good. --- examples/demoDay.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index cb429c7efe..7c65d6a763 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -13,22 +13,23 @@ if (( window).demoName === "demo-day") { // First we make the scatterplot that shows the full dataset -var N_BINS = 3; +var N_BINS = 25; function makeScatterPlotWithSparkline(data) { var s: any = {}; s.xScale = new LinearScale(); s.yScale = new LinearScale(); s.leftAxis = new YAxis(s.yScale, "left"); s.xAxis = new XAxis(s.xScale, "bottom"); - s.renderer = new CircleRenderer(data, s.xScale, s.yScale); + s.renderer = new CircleRenderer(data, s.xScale, s.yScale, null, null, 1.5); s.xSpark = new LinearScale(); s.ySpark = new LinearScale(); - s.sparkline = new CircleRenderer(data, s.xSpark, s.ySpark); + s.sparkline = new CircleRenderer(data, s.xSpark, s.ySpark, null, null, 0.5); s.sparkline.rowWeight(0.25); var r1 = [s.leftAxis, s.renderer]; var r2 = [null, s.xAxis]; var r3 = [null, s.sparkline]; s.table = new Table([r1,r2,r3]); + s.zoom = new BrushZoomInteraction(s.sparkline, s.xScale, s.yScale); return s; } @@ -115,6 +116,10 @@ function coordinator(chart: any, dataset: IDataset) { var histogram = chart.h; chart.c = {}; + var selectionCallback = (selection: D3.Selection) => { + selection.classed("selected-point", true); + } + var data = dataset.data; var dataCallback = (selectedIndices: number[]) => { var selectedData = grabIndices(data, selectedIndices); @@ -127,17 +132,17 @@ function coordinator(chart: any, dataset: IDataset) { histogram.renderer1.render(); histogram.renderer2.render(); }; - var areaInteraction = new AreaInteraction(scatterplot.renderer, null, null, dataCallback); + var areaInteraction = new AreaInteraction(scatterplot.renderer, null, selectionCallback, dataCallback); } function grabIndices(itemsToGrab: any[], indices: number[]) { return indices.map((i) => itemsToGrab[i]); } -var clump1 = makeNormallyDistributedData(3, -10, 5, 7, 1); -var clump2 = makeNormallyDistributedData(3, 2, 0.5, 3, 3); -var clump3 = makeNormallyDistributedData(4, 5, 10, -3, 9); -var clump4 = makeNormallyDistributedData(2, -25, 1, 20, 5); +var clump1 = makeNormallyDistributedData(300, -10, 5, 7, 1); +var clump2 = makeNormallyDistributedData(300, 2, 0.5, 3, 3); +var clump3 = makeNormallyDistributedData(400, 5, 10, -3, 9); +var clump4 = makeNormallyDistributedData(200, -25, 1, 20, 5); var clumpData = clump1.concat(clump2, clump3, clump4); var dataset = {seriesName: "clumpedData", data: clumpData}; From 2bd614b7de96d83a1978e2987b5229f2ec574f96 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 12:22:24 -0800 Subject: [PATCH 15/23] A little cleverer in working with selected data, still kind of buggy. --- examples/demoDay.ts | 7 +++++++ src/renderer.ts | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 7c65d6a763..b2680d28ca 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -116,13 +116,20 @@ function coordinator(chart: any, dataset: IDataset) { var histogram = chart.h; chart.c = {}; + var lastSelection = null; var selectionCallback = (selection: D3.Selection) => { + if (lastSelection != null) lastSelection.classed("selected-point", false); selection.classed("selected-point", true); + lastSelection = selection; } var data = dataset.data; + var lastSelectedData = null; var dataCallback = (selectedIndices: number[]) => { var selectedData = grabIndices(data, selectedIndices); + selectedData.forEach((d) => d.selected = true); + if (lastSelectedData != null) lastSelectedData.forEach((d) => d.selected = false); + lastSelectedData = selectedData; var xBins = histogram.bin1(selectedData); var yBins = histogram.bin2(selectedData); chart.c.xBins = xBins; diff --git a/src/renderer.ts b/src/renderer.ts index a14b42bf94..7241865d1b 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -165,7 +165,8 @@ class CircleRenderer extends XYRenderer { .append("circle") .attr("cx", this.xScaledAccessor) .attr("cy", this.yScaledAccessor) - .attr("r", this.size); + .attr("r", this.size) + .classed("selected-point", (d) => d.selected); } } From f461f97f2c696323b91c19fd17f7d1eab13ba3fc Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 12:32:07 -0800 Subject: [PATCH 16/23] Interactions working really nicely. --- examples/demoDay.ts | 11 ++++++----- src/interaction.ts | 7 ++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index b2680d28ca..25cc6f3347 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -29,7 +29,6 @@ function makeScatterPlotWithSparkline(data) { var r2 = [null, s.xAxis]; var r3 = [null, s.sparkline]; s.table = new Table([r1,r2,r3]); - s.zoom = new BrushZoomInteraction(s.sparkline, s.xScale, s.yScale); return s; } @@ -124,12 +123,12 @@ function coordinator(chart: any, dataset: IDataset) { } var data = dataset.data; - var lastSelectedData = null; + // var lastSelectedData = null; var dataCallback = (selectedIndices: number[]) => { var selectedData = grabIndices(data, selectedIndices); - selectedData.forEach((d) => d.selected = true); - if (lastSelectedData != null) lastSelectedData.forEach((d) => d.selected = false); - lastSelectedData = selectedData; + // selectedData.forEach((d) => d.selected = true); + // if (lastSelectedData != null) lastSelectedData.forEach((d) => d.selected = false); + // lastSelectedData = selectedData; var xBins = histogram.bin1(selectedData); var yBins = histogram.bin2(selectedData); chart.c.xBins = xBins; @@ -140,6 +139,8 @@ function coordinator(chart: any, dataset: IDataset) { histogram.renderer2.render(); }; var areaInteraction = new AreaInteraction(scatterplot.renderer, null, selectionCallback, dataCallback); + var zoomCallback = (indices) => {areaInteraction.clearBox(); dataCallback(indices)}; + chart.c.zoom = new BrushZoomInteraction(scatterplot.sparkline, scatterplot.xScale, scatterplot.yScale, zoomCallback); } function grabIndices(itemsToGrab: any[], indices: number[]) { diff --git a/src/interaction.ts b/src/interaction.ts index de613bcc10..ffdde85ba8 100644 --- a/src/interaction.ts +++ b/src/interaction.ts @@ -144,6 +144,10 @@ class AreaInteraction extends Interaction { } } + public clearBox() { + this.dragBox.attr("height", 0).attr("width", 0); + } + public anchor(hitBox: D3.Selection) { super.anchor(hitBox); var cname = AreaInteraction.CLASS_DRAG_BOX; @@ -162,9 +166,10 @@ class BrushZoomInteraction extends AreaInteraction { make a sparkline, you do not want to update the sparkline's scales, but rather the scales of a linked chart. */ - constructor(eventComponent: XYRenderer, public xScale: QuantitiveScale, public yScale: QuantitiveScale) { + constructor(eventComponent: XYRenderer, public xScale: QuantitiveScale, public yScale: QuantitiveScale, public indicesCallback?: (a: number[]) => any) { super(eventComponent); this.areaCallback = this.zoom; + this.indicesCallback = indicesCallback; } public zoom(area: FullSelectionArea) { From 0dc90273814fda4d4280b354e3e1def95f2bc7fe Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Tue, 4 Feb 2014 12:34:57 -0800 Subject: [PATCH 17/23] Added labels to demo day demo. Labels, labels everywhere! --- examples/demo-day.css | 7 +++++++ examples/demo-day.html | 6 ++++-- examples/demoDay.ts | 32 +++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 examples/demo-day.css diff --git a/examples/demo-day.css b/examples/demo-day.css new file mode 100644 index 0000000000..fc5e10e944 --- /dev/null +++ b/examples/demo-day.css @@ -0,0 +1,7 @@ +.demo-table-title text { + text-decoration: underline; +} + +.scatterplot-title text { + font-size: 24pt; +} diff --git a/examples/demo-day.html b/examples/demo-day.html index fa228a95ee..486136301f 100644 --- a/examples/demo-day.html +++ b/examples/demo-day.html @@ -2,10 +2,12 @@ + -

Basic TSC

-


+


+ +


diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 7202480aa1..992b0eaf15 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -17,16 +17,22 @@ function makeScatterPlotWithSparkline(data) { s.xScale = new LinearScale(); s.yScale = new LinearScale(); s.leftAxis = new YAxis(s.yScale, "left"); + var leftAxisTable = new Table([[new AxisLabel("Y", "vertical-left"), s.leftAxis]]); + leftAxisTable.colWeight(0); s.xAxis = new XAxis(s.xScale, "bottom"); + var xAxisTable = new Table([[s.xAxis], [new AxisLabel("X")]]); + xAxisTable.rowWeight(0); + s.renderer = new CircleRenderer(data, s.xScale, s.yScale); s.xSpark = new LinearScale(); s.ySpark = new LinearScale(); s.sparkline = new CircleRenderer(data, s.xSpark, s.ySpark); s.sparkline.rowWeight(0.25); - var r1 = [s.leftAxis, s.renderer]; - var r2 = [null, s.xAxis]; + var r1 = [leftAxisTable, s.renderer]; + var r2 = [null, xAxisTable]; var r3 = [null, s.sparkline]; - s.table = new Table([r1,r2,r3]); + var chartTable = new Table([r1,r2,r3]); + s.table = new Table([[new TitleLabel("Random Data").classed("scatterplot-title", true)], [chartTable]]); return s; } @@ -39,7 +45,11 @@ function makeHistograms(data: any[]) { h.renderer1 = new BarRenderer(ds1, h.xScale1, h.yScale1); h.xAxis1 = new XAxis(h.xScale1, "bottom"); h.yAxis1 = new YAxis(h.yScale1, "right"); - var table1 = new Table([[h.renderer1, h.yAxis1], [h.xAxis1, null]]); + var labelX1Table = new Table([[h.xAxis1], [new AxisLabel("X values")]]); + labelX1Table.rowWeight(0); + var labelY1Table = new Table([[h.yAxis1, new AxisLabel("Counts", "vertical-right")]]); + labelY1Table.colWeight(0); + var table1 = new Table([[h.renderer1, labelY1Table], [labelX1Table, null]]); h.xScale2 = new LinearScale(); h.yScale2 = new LinearScale(); @@ -48,9 +58,15 @@ function makeHistograms(data: any[]) { h.renderer2 = new BarRenderer(ds2, h.xScale2, h.yScale2); h.xAxis2 = new XAxis(h.xScale2, "bottom"); h.yAxis2 = new YAxis(h.yScale2, "right"); - var table2 = new Table([[h.renderer2, h.yAxis2], [h.xAxis2, null]]); + var labelX2Table = new Table([[h.xAxis2], [new AxisLabel("Y values")]]); + labelX2Table.rowWeight(0); + var labelY2Table = new Table([[h.yAxis2, new AxisLabel("Counts", "vertical-right")]]); + labelY2Table.colWeight(0); + var table2 = new Table([[h.renderer2, labelY2Table], [labelX2Table, null]]); h.table = new Table([[table1], [table2]]); + h.table.rowPadding = 5; + h.table.colPadding = 5; return h; } @@ -58,8 +74,10 @@ function makeScatterHisto(data) { var s = makeScatterPlotWithSparkline(data); var h = makeHistograms(data.data); var r = [s.table, h.table]; - var table = new Table([r]); - table.colPadding = 10; + var chartTable = new Table([r]); + chartTable.colPadding = 10; + + var table = new Table([[new TitleLabel("Glorious Demo Day Demo of Glory").classed("demo-table-title", true)], [chartTable]]); return {table: table, s: s, h: h}; } From ca19dc6107cd71cd43440eecb930e04adfcab76f Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 12:38:32 -0800 Subject: [PATCH 18/23] Fix the normal distributions arg list --- examples/demoDay.ts | 2 +- examples/exampleUtil.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/demoDay.ts b/examples/demoDay.ts index d989d320b9..0d0af91c97 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -167,7 +167,7 @@ function grabIndices(itemsToGrab: any[], indices: number[]) { var clump1 = makeNormallyDistributedData(300, -10, 5, 7, 1); var clump2 = makeNormallyDistributedData(300, 2, 0.5, 3, 3); -var clump3 = makeNormallyDistributedData(400, 5, 10, -3, 9); +var clump3 = makeNormallyDistributedData(30, 5, 10, -3, 9); var clump4 = makeNormallyDistributedData(200, -25, 1, 20, 5); var clumpData = clump1.concat(clump2, clump3, clump4); diff --git a/examples/exampleUtil.ts b/examples/exampleUtil.ts index 592f4b9a0a..de6bbd7ec1 100644 --- a/examples/exampleUtil.ts +++ b/examples/exampleUtil.ts @@ -9,7 +9,7 @@ function makeRandomData(numPoints, scaleFactor=1): IDataset { return {"data": data, "seriesName": "random-data"}; } -function makeNormallyDistributedData(n=100, xMean?, yMean?, xStdDev?, yStdDev?) { +function makeNormallyDistributedData(n=100, xMean?, xStdDev?, yMean?, yStdDev?) { var results = []; var x = d3.random.normal(xMean, xStdDev); var y = d3.random.normal(yMean, yStdDev); From dd665921b665a21482ee3b7e6b1253698590ab05 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 12:45:36 -0800 Subject: [PATCH 19/23] Some changes --- examples/demo-day.css | 4 ++++ examples/demoDay.ts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/demo-day.css b/examples/demo-day.css index fc5e10e944..0bf254a594 100644 --- a/examples/demo-day.css +++ b/examples/demo-day.css @@ -5,3 +5,7 @@ .scatterplot-title text { font-size: 24pt; } + +.axis-label text { + font-size: 12pt; +} diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 0d0af91c97..eeb74d6e63 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -19,10 +19,10 @@ function makeScatterPlotWithSparkline(data) { s.xScale = new LinearScale(); s.yScale = new LinearScale(); s.leftAxis = new YAxis(s.yScale, "left"); - var leftAxisTable = new Table([[new AxisLabel("Y", "vertical-left"), s.leftAxis]]); + var leftAxisTable = new Table([[new AxisLabel("y", "vertical-left"), s.leftAxis]]); leftAxisTable.colWeight(0); s.xAxis = new XAxis(s.xScale, "bottom"); - var xAxisTable = new Table([[s.xAxis], [new AxisLabel("X")]]); + var xAxisTable = new Table([[s.xAxis], [new AxisLabel("x")]]); xAxisTable.rowWeight(0); s.renderer = new CircleRenderer(data, s.xScale, s.yScale, null, null, 1.5); From cac3b73d334e8e1086ce3923a2aa239910ab4c7e Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Tue, 4 Feb 2014 12:59:12 -0800 Subject: [PATCH 20/23] Added alternate crazy stylesheet for demo. --- examples/demo-day.css | 4 ++++ examples/demoDay.ts | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/demo-day.css b/examples/demo-day.css index fc5e10e944..4894caee5a 100644 --- a/examples/demo-day.css +++ b/examples/demo-day.css @@ -5,3 +5,7 @@ .scatterplot-title text { font-size: 24pt; } + +.histogram-title text { + font-size: 24pt; +} diff --git a/examples/demoDay.ts b/examples/demoDay.ts index d989d320b9..665783146b 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -33,8 +33,7 @@ function makeScatterPlotWithSparkline(data) { var r1 = [leftAxisTable, s.renderer]; var r2 = [null, xAxisTable]; var r3 = [null, s.sparkline]; - var chartTable = new Table([r1,r2,r3]); - s.table = new Table([[new TitleLabel("Random Data").classed("scatterplot-title", true)], [chartTable]]); + s.table = new Table([r1,r2,r3]); return s; } @@ -80,9 +79,10 @@ function makeScatterHisto(data) { var s = makeScatterPlotWithSparkline(data); var h = makeHistograms(data.data); var r = [s.table, h.table]; - var chartTable = new Table([r]); + var titleRow = [ new TitleLabel("Random Data").classed("scatterplot-title", true), + new TitleLabel("Histograms").classed("histogram-title", true) ]; + var chartTable = new Table([titleRow, r]); chartTable.colPadding = 10; - var table = new Table([[new TitleLabel("Glorious Demo Day Demo of Glory").classed("demo-table-title", true)], [chartTable]]); return {table: table, s: s, h: h}; From bb4c8738f8556b5079a5783c3ca3d93fabb887db Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 12:59:39 -0800 Subject: [PATCH 21/23] Add tscdemo --- examples/demoDay.ts | 1 - examples/tsc-demo.html | 18 ++++++++++++++++++ examples/tscDemo.ts | 32 ++++++++++++++++++++++++++++++++ index.html | 1 + 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 examples/tsc-demo.html create mode 100644 examples/tscDemo.ts diff --git a/examples/demoDay.ts b/examples/demoDay.ts index eeb74d6e63..6d3944e7a8 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -182,5 +182,4 @@ chartSH.table.anchor(svg); chartSH.table.computeLayout(); chartSH.table.render(); - } diff --git a/examples/tsc-demo.html b/examples/tsc-demo.html new file mode 100644 index 0000000000..fae6819b04 --- /dev/null +++ b/examples/tsc-demo.html @@ -0,0 +1,18 @@ + + + + + + +

Basic TSC

+


+ + + + + + + + + + diff --git a/examples/tscDemo.ts b/examples/tscDemo.ts new file mode 100644 index 0000000000..8775cfabb1 --- /dev/null +++ b/examples/tscDemo.ts @@ -0,0 +1,32 @@ +/// + +/// +/// +/// +/// +/// +/// +/// + +if (( window).demoName === "tsc-demo") { + +var yScale = new LinearScale(); +var xScale = new LinearScale(); +var left = new YAxis(yScale, "left"); +var data = makeRandomData(1000, 200); +var renderer = new LineRenderer(data, xScale, yScale); +var bottomAxis = new XAxis(xScale, "bottom"); + +var chart = new Table([[left, renderer] + ,[null, bottomAxis]]); + +var outerTable = new Table([ [new TitleLabel("A Chart")], + [chart] ]) +outerTable.xMargin = 10; +outerTable.yMargin = 10; + +var svg = d3.select("#table"); +outerTable.anchor(svg); +outerTable.computeLayout(); +outerTable.render(); +} diff --git a/index.html b/index.html index 2e0be02d17..15cd1221c6 100644 --- a/index.html +++ b/index.html @@ -12,5 +12,6 @@

Tests

The old demo

Sparkline demo

Demo Day

+

TSC Demo

From c0f7d1ac3f2cbdecbd67c097b835fcda6aa49c24 Mon Sep 17 00:00:00 2001 From: Justin Lan Date: Tue, 4 Feb 2014 13:01:01 -0800 Subject: [PATCH 22/23] Actually added crazy style now. --- examples/demo-day-crazy.css | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 examples/demo-day-crazy.css diff --git a/examples/demo-day-crazy.css b/examples/demo-day-crazy.css new file mode 100644 index 0000000000..e1638cee10 --- /dev/null +++ b/examples/demo-day-crazy.css @@ -0,0 +1,29 @@ +.demo-table-title text { + text-decoration: line-through; + fill: yellow; + font-family: Times; +} + +.scatterplot-title text { + font-size: 24pt; + fill: magenta; + font-family: monospace; +} + +.histogram-title text { + font-size: 24pt; + fill: cyan; + font-family: cursive; +} + +rect { + fill: green; +} + +circle { + fill: orange; +} + +.selected-point { + fill: black; +} From 7baf7a778257dab9781c3c7a867c7ad1030eaf26 Mon Sep 17 00:00:00 2001 From: Daniel Mane Date: Tue, 4 Feb 2014 15:29:29 -0800 Subject: [PATCH 23/23] Last-minute changes for the demo, such as making a seperate page for the crazy css demo --- examples/demo-day-crazy.css | 5 ++++ examples/demo-day-crazy.html | 20 ++++++++++++++++ examples/demoDay.ts | 45 ------------------------------------ examples/exampleUtil.ts | 33 ++++++++++++++++++++++++++ index.html | 3 ++- 5 files changed, 60 insertions(+), 46 deletions(-) create mode 100644 examples/demo-day-crazy.html diff --git a/examples/demo-day-crazy.css b/examples/demo-day-crazy.css index e1638cee10..00304266cf 100644 --- a/examples/demo-day-crazy.css +++ b/examples/demo-day-crazy.css @@ -27,3 +27,8 @@ circle { .selected-point { fill: black; } + +.drag-box { + fill: red; + opacity: 0.5; +} diff --git a/examples/demo-day-crazy.html b/examples/demo-day-crazy.html new file mode 100644 index 0000000000..ee114e7d2a --- /dev/null +++ b/examples/demo-day-crazy.html @@ -0,0 +1,20 @@ + + + + + + + +


+ +


+ + + + + + + + + + diff --git a/examples/demoDay.ts b/examples/demoDay.ts index 35fb30df18..4f9dfee525 100644 --- a/examples/demoDay.ts +++ b/examples/demoDay.ts @@ -9,10 +9,6 @@ /// if (( window).demoName === "demo-day") { - -// First we make the scatterplot that shows the full dataset - - var N_BINS = 25; function makeScatterPlotWithSparkline(data) { var s: any = {}; @@ -88,46 +84,6 @@ function makeScatterHisto(data) { return {table: table, s: s, h: h}; } -function filterSelectedData(data) { - var p = (d) => d.selected; - return data.filter(p); -} - -function makeBinFunction(accessor, range, nBins) { - return (d) => binByVal(d, accessor, range, nBins); -} - -function binByVal(data: any[], accessor: IAccessor, range=[0,100], nBins=10) { - if (accessor == null) {accessor = (d) => d.x}; - var min = range[0]; - var max = range[1]; - var spread = max-min; - var binBeginnings = _.range(nBins).map((n) => min + n * spread / nBins); - var binEndings = _.range(nBins) .map((n) => min + (n+1) * spread / nBins); - var counts = new Array(nBins); - _.range(nBins).forEach((b, i) => counts[i] = 0); - data.forEach((d) => { - var v = accessor(d); - var found = false; - for (var i=0; i { - var bin: any = {}; - bin.x = binBeginnings[i]; - bin.x2 = binEndings[i]; - bin.y = count; - return bin; - }) - return bins; -} - function coordinator(chart: any, dataset: IDataset) { var scatterplot = chart.s; var histogram = chart.h; @@ -164,7 +120,6 @@ function coordinator(chart: any, dataset: IDataset) { function grabIndices(itemsToGrab: any[], indices: number[]) { return indices.map((i) => itemsToGrab[i]); } - var clump1 = makeNormallyDistributedData(300, -10, 5, 7, 1); var clump2 = makeNormallyDistributedData(300, 2, 0.5, 3, 3); var clump3 = makeNormallyDistributedData(30, 5, 10, -3, 9); diff --git a/examples/exampleUtil.ts b/examples/exampleUtil.ts index de6bbd7ec1..9a31034a68 100644 --- a/examples/exampleUtil.ts +++ b/examples/exampleUtil.ts @@ -19,7 +19,40 @@ function makeNormallyDistributedData(n=100, xMean?, xStdDev?, yMean?, yStdDev?) } return results; } +function makeBinFunction(accessor, range, nBins) { + return (d) => binByVal(d, accessor, range, nBins); +} +function binByVal(data: any[], accessor: IAccessor, range=[0,100], nBins=10) { + if (accessor == null) {accessor = (d) => d.x}; + var min = range[0]; + var max = range[1]; + var spread = max-min; + var binBeginnings = _.range(nBins).map((n) => min + n * spread / nBins); + var binEndings = _.range(nBins) .map((n) => min + (n+1) * spread / nBins); + var counts = new Array(nBins); + _.range(nBins).forEach((b, i) => counts[i] = 0); + data.forEach((d) => { + var v = accessor(d); + var found = false; + for (var i=0; i { + var bin: any = {}; + bin.x = binBeginnings[i]; + bin.x2 = binEndings[i]; + bin.y = count; + return bin; + }) + return bins; +} function makeRandomBucketData(numBuckets: number, bucketWidth: number, maxValue = 10): IDataset { var data = []; for (var i=0; i < numBuckets; i++) { diff --git a/index.html b/index.html index 15cd1221c6..d9c8deee16 100644 --- a/index.html +++ b/index.html @@ -12,6 +12,7 @@

Tests

The old demo

Sparkline demo

Demo Day

-

TSC Demo

+

Demo Day With Crazy CSS

+

TSC Demo

(the code)