-
Notifications
You must be signed in to change notification settings - Fork 221
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from palantir/dev
Merge version 0.1.0 into master - the demo day release
- v3.13.0
- v3.12.0
- v3.11.0
- v3.10.0
- v3.9.0
- v3.9.0-dev
- v3.8.8
- v3.8.7
- v3.8.6
- v3.8.5
- v3.8.4
- v3.8.3
- v.3.8.2
- v3.8.1
- v3.8.0
- v3.7.0
- v3.6.1
- v3.6.0
- v3.6.0-dev
- v3.5.4
- v3.5.3
- v3.5.2
- v3.5.1
- v3.5.0
- v3.5.0-dev
- v3.4.1
- v3.4.0
- v3.3.1
- v3.3.0
- v3.3.0-dev
- v3.2.0
- v3.2.0-dev
- v3.1.1
- v3.1.0
- v3.1.0-dev
- v3.0.0
- v3.0.0-rc.1
- v3.0.0-beta.4
- v3.0.0-beta.3
- v3.0.0-beta.2
- v3.0.0-beta.1
- v2.9.0
- v2.8.0
- v2.7.0
- v2.6.0
- v2.5.0
- v2.4.1
- v2.4.0
- v2.3.1
- v2.3.0
- v2.2.0
- v2.1.0
- v2.0.0
- v2.0.0-rc2
- v2.0.0-rc1
- v1.16.2
- v1.16.1
- v1.16.0
- v1.15.0
- v1.14.0
- v1.13.0
- v1.12.0
- v1.11.0
- v1.10.0
- v1.9.0
- v1.8.0
- v1.7.0
- v1.6.1
- v1.6.0
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.0
- v1.3.0
- v1.2.0
- v1.1.0
- v1.0.0
- v1.0.0-rc7
- v1.0.0-rc6
- v1.0.0-rc5
- v1.0.0-rc4
- v1.0.0-rc3
- v1.0.0-rc2
- v1.0.0-rc1
- v0.54.0
- v0.53.0
- v0.52.0
- v0.51.0
- v0.50.0
- v0.49.0
- v0.48.1
- v0.48.0
- v0.47.0
- v0.46.0
- v0.45.2
- v0.45.1
- v0.45.0
- v0.44.0
- v0.43.2
- v0.43.1
- v0.42.0
- v0.41.1
- v0.41.0
- v0.40.0
- v0.39.0
- v0.38.0
- v0.37.0
- v0.36.1
- v0.36.0
- v0.35.1
- v0.35.0
- v0.34.1
- v0.34.0
- v0.33.1
- v0.33.0
- v0.33.0-preview-2
- v0.32.1
- v0.32.0
- v0.31.0
- v0.30.0
- v0.29.0
- v0.28.1
- v0.28.0
- v0.27.1
- v0.27.0
- v0.26.2
- v0.26.1
- v0.26.0
- v0.25.1
- v0.25.0
- v0.24.0
- v0.23.2
- v0.23.1
- v0.23.0
- v0.22.0
- v0.21.3
- v0.21.2
- v0.21.1
- v0.21.0
- v0.20.5
- v0.20.4
- v0.20.3
- v0.20.3-hover-tooltip-1
- v0.20.3-hover-tooltip
- v0.20.2
- v0.20.1
- v0.20.0
- v0.19.3
- v0.19.2
- v0.19.1
- v0.19.0
- v0.18.2
- v0.18.1
- v.0.18.0
- v0.17.0
- v0.16.0
- v0.15.4
- v0.15.3
- v0.15.2
- v0.15.1
- v0.15.0
- v0.14.2
- v0.14.1
- v0.14.0
- v0.13.7
- v0.13.6
- v0.13.4
- v0.13.2
- v0.13.1
- v0.13.0
- v0.12.4
- v0.12.3
- v0.12.2
- v0.12.1
- v0.12.0
- v0.11.0
- v0.10.2
- v0.10.1
- v0.10.0
- v0.9.1
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.0
- v0.5.1
- v0.5.0
- v0.4.0
- v0.3.1
- v0.3.0
- v0.2.0
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v.0.1.0
- V1.13.0
- 0.2.2
- 0.2.1
Showing
30 changed files
with
1,233 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,5 @@ plottable.js | |
plottable.js.map | ||
tests.js | ||
tests.js.map | ||
examples/*.js | ||
examples/*.js.map |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
.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; | ||
} | ||
|
||
.drag-box { | ||
fill: red; | ||
opacity: 0.5; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<head> | ||
<link href="../style.css" type="text/css" rel="stylesheet" /> | ||
<link href="demo-day-crazy.css" type="text/css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
<br><hr><br> | ||
<svg id="table" width="800px" height="600px"></svg> | ||
<br><hr><br> | ||
|
||
|
||
<script type="text/javascript"> window.demoName = "demo-day"; //HACK HACK </script> | ||
<script src="../Lib/chai/chai.js"></script> | ||
<script src="../Lib/lodash.js"></script> | ||
<script src="../Lib/d3.ascii.js"></script> | ||
<script src="../plottable.js"></script> | ||
<script src="examples.js"></script> | ||
|
||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.demo-table-title text { | ||
text-decoration: underline; | ||
} | ||
|
||
.scatterplot-title text { | ||
font-size: 24pt; | ||
} | ||
|
||
.histogram-title text { | ||
font-size: 24pt; | ||
|
||
.axis-label text { | ||
font-size: 12pt; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<head> | ||
<link href="../style.css" type="text/css" rel="stylesheet" /> | ||
<link href="demo-day.css" type="text/css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
<br><hr><br> | ||
<svg id="table" width="800px" height="600px"></svg> | ||
<br><hr><br> | ||
|
||
|
||
<script type="text/javascript"> window.demoName = "demo-day"; //HACK HACK </script> | ||
<script src="../Lib/chai/chai.js"></script> | ||
<script src="../Lib/lodash.js"></script> | ||
<script src="../Lib/d3.ascii.js"></script> | ||
<script src="../plottable.js"></script> | ||
<script src="examples.js"></script> | ||
|
||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<head> | ||
<link href="../style.css" type="text/css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
|
||
<h1> Bar Renderer </h1> | ||
<svg id="svg6"></svg><br><hr><br> | ||
|
||
|
||
<h1> Basic TSC </h1> | ||
<svg id="svg1"></svg><br><hr><br> | ||
<h1> Chartbag of timeseriescharts </h1> | ||
<svg id="svg2"></svg><br><hr><br> | ||
<h1> TSC with 2 axes </h1> | ||
<svg id="svg3"></svg><br><hr><br> | ||
<h1> TSC with subplots, varying # of axes, and sparkline </h1> | ||
<svg id="svg4"></svg><br><hr><br> | ||
<svg id="svg5"></svg><br><hr><br> | ||
|
||
|
||
<script src="../Lib/d3.ascii.js"></script> | ||
<script src="../Lib/lodash.js"></script> | ||
<script src="../Lib/chai/chai.js"></script> | ||
<script type="text/javascript"> window.demoName = "demo1"; //HACK HACK </script> | ||
<script src="../plottable.js"></script> | ||
<script src="examples.js"></script> | ||
|
||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
///<reference path="../lib/d3.d.ts" /> | ||
|
||
///<reference path="../src/table.ts" /> | ||
///<reference path="../src/renderer.ts" /> | ||
///<reference path="../src/interaction.ts" /> | ||
///<reference path="../src/labelComponent.ts" /> | ||
///<reference path="../src/axis.ts" /> | ||
///<reference path="../src/scale.ts" /> | ||
///<reference path="exampleUtil.ts" /> | ||
|
||
if ((<any> window).demoName === "demo-day") { | ||
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"); | ||
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, null, null, 1.5); | ||
s.xSpark = new LinearScale(); | ||
s.ySpark = new LinearScale(); | ||
s.sparkline = new CircleRenderer(data, s.xSpark, s.ySpark, null, null, 0.5); | ||
s.sparkline.rowWeight(0.25); | ||
var r1 = [leftAxisTable, s.renderer]; | ||
var r2 = [null, xAxisTable]; | ||
var r3 = [null, s.sparkline]; | ||
s.table = new Table([r1,r2,r3]); | ||
return s; | ||
} | ||
|
||
function makeHistograms(data: any[]) { | ||
var h: any = {}; | ||
var xExtent = d3.extent(data, (d) => d.x); | ||
h.xScale1 = new LinearScale().domain(xExtent); | ||
h.yScale1 = new LinearScale(); | ||
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 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]]); | ||
|
||
var yExtent = d3.extent(data, (d) => d.y); | ||
h.xScale2 = new LinearScale().domain(yExtent); | ||
h.yScale2 = new LinearScale(); | ||
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"); | ||
h.yAxis2 = new YAxis(h.yScale2, "right"); | ||
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; | ||
} | ||
|
||
function makeScatterHisto(data) { | ||
var s = makeScatterPlotWithSparkline(data); | ||
var h = makeHistograms(data.data); | ||
var r = [s.table, h.table]; | ||
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}; | ||
} | ||
|
||
function coordinator(chart: any, dataset: IDataset) { | ||
var scatterplot = chart.s; | ||
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; | ||
chart.c.yBins = yBins; | ||
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, 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[]) { | ||
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); | ||
var clump4 = makeNormallyDistributedData(200, -25, 1, 20, 5); | ||
|
||
var clumpData = clump1.concat(clump2, clump3, clump4); | ||
var dataset = {seriesName: "clumpedData", data: clumpData}; | ||
|
||
var chartSH = makeScatterHisto(dataset); | ||
|
||
coordinator(chartSH, dataset); | ||
|
||
var svg = d3.select("#table"); | ||
chartSH.table.anchor(svg); | ||
chartSH.table.computeLayout(); | ||
chartSH.table.render(); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
function makeRandomData(numPoints, scaleFactor=1): IDataset { | ||
var data = []; | ||
for (var i = 0; i < numPoints; i++) { | ||
var x = Math.random(); | ||
var r = {x: x, y: (x + x * Math.random()) * scaleFactor} | ||
data.push(r); | ||
} | ||
data = _.sortBy(data, (d) => d.x); | ||
return {"data": data, "seriesName": "random-data"}; | ||
} | ||
|
||
function makeNormallyDistributedData(n=100, xMean?, xStdDev?, yMean?, yStdDev?) { | ||
var results = []; | ||
var x = d3.random.normal(xMean, xStdDev); | ||
var y = d3.random.normal(yMean, yStdDev); | ||
for (var i=0; i<n; i++) { | ||
var r = {x: x(), y: y()}; | ||
results.push(r); | ||
} | ||
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<nBins; i++) { | ||
if (v <= binEndings[i]) { | ||
counts[i]++; | ||
found = true; | ||
break; | ||
} | ||
} | ||
if (!found) {counts[counts.length-1]++}; | ||
}); | ||
var bins = counts.map((count, 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++) { | ||
data.push({ | ||
x: i * bucketWidth, | ||
x2: (i+1) * bucketWidth, | ||
y: Math.round(Math.random() * maxValue) | ||
}); | ||
} | ||
return { | ||
"data": data, | ||
"seriesName": "random-buckets" | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<head> | ||
<link href="../style.css" type="text/css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
<h1> Basic TSC </h1> | ||
<svg id="table" width="800px" height="600px"></svg><br><hr><br> | ||
|
||
|
||
<script type="text/javascript"> window.demoName = "sparkline-demo"; //HACK HACK </script> | ||
<script src="../Lib/chai/chai.js"></script> | ||
<script src="../Lib/lodash.js"></script> | ||
<script src="../Lib/d3.ascii.js"></script> | ||
<script src="../plottable.js"></script> | ||
<script src="examples.js"></script> | ||
|
||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
///<reference path="../lib/d3.d.ts" /> | ||
|
||
///<reference path="../src/table.ts" /> | ||
///<reference path="../src/renderer.ts" /> | ||
///<reference path="../src/interaction.ts" /> | ||
///<reference path="../src/labelComponent.ts" /> | ||
///<reference path="../src/axis.ts" /> | ||
///<reference path="../src/scale.ts" /> | ||
///<reference path="exampleUtil.ts" /> | ||
|
||
if ((<any> window).demoName === "sparkline-demo") { | ||
|
||
var yScale = new LinearScale(); | ||
var xScale = new LinearScale(); | ||
var left = new YAxis(yScale, "left"); | ||
var data = makeRandomData(1000, 200); | ||
var renderer = new CircleRenderer(data, xScale, yScale); | ||
var bottomAxis = new XAxis(xScale, "bottom"); | ||
var xSpark = new LinearScale(); | ||
var ySpark = new LinearScale(); | ||
var sparkline = new LineRenderer(data, xSpark, ySpark); | ||
sparkline.rowWeight(0.3); | ||
|
||
var r1: Component[] = [left, renderer]; | ||
var r2: Component[] = [null, bottomAxis]; | ||
var r3: Component[] = [null, sparkline]; | ||
|
||
var chart = new Table([r1, r2, r3]); | ||
chart.xMargin = 10; | ||
chart.yMargin = 10; | ||
|
||
var brushZoom = new BrushZoomInteraction(sparkline, xScale, yScale); | ||
var toggleClass = function() {return !d3.select(this).classed("selected-point")}; | ||
var cb = (s) => s.classed("selected-point", toggleClass); | ||
var areaInteraction = new AreaInteraction(renderer, null, cb); | ||
|
||
var svg = d3.select("#table"); | ||
chart.anchor(svg); | ||
chart.computeLayout(); | ||
chart.render(); | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<head> | ||
<link href="../style.css" type="text/css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
<h1> Basic TSC </h1> | ||
<svg id="table" width="800px" height="600px"></svg><br><hr><br> | ||
|
||
|
||
<script type="text/javascript"> window.demoName = "tsc-demo"; //HACK HACK </script> | ||
<script src="../Lib/chai/chai.js"></script> | ||
<script src="../Lib/lodash.js"></script> | ||
<script src="../Lib/d3.ascii.js"></script> | ||
<script src="../plottable.js"></script> | ||
<script src="examples.js"></script> | ||
|
||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
///<reference path="../lib/d3.d.ts" /> | ||
|
||
///<reference path="../src/table.ts" /> | ||
///<reference path="../src/renderer.ts" /> | ||
///<reference path="../src/interaction.ts" /> | ||
///<reference path="../src/labelComponent.ts" /> | ||
///<reference path="../src/axis.ts" /> | ||
///<reference path="../src/scale.ts" /> | ||
///<reference path="exampleUtil.ts" /> | ||
|
||
if ((<any> 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(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,194 @@ | ||
///<reference path="../lib/lodash.d.ts" /> | ||
|
||
class DragZoomInteraction { | ||
class Interaction { | ||
/* A general base class for interactions. | ||
It maintains a 'hitBox' which is where all event listeners are attached. Due to cross- | ||
browser weirdness, the hitbox needs to be an opaque but invisible rectangle. | ||
TODO: We should give the interaction "foreground" and "background" elements where it can | ||
draw things, e.g. crosshairs. | ||
*/ | ||
public hitBox: D3.Selection; | ||
|
||
constructor(public componentToListenTo: Component) { | ||
} | ||
|
||
public anchor(hitBox: D3.Selection) { | ||
this.hitBox = hitBox; | ||
} | ||
|
||
public registerWithComponent() { | ||
this.componentToListenTo.registerInteraction(this); | ||
// It would be nice to have a call to this in the Interaction constructor, but | ||
// can't do this right now because that depends on listenToHitBox being callable, which depends on the subclass | ||
// constructor finishing first. | ||
} | ||
} | ||
|
||
interface ZoomInfo { | ||
translate: number[]; | ||
scale: number[]; | ||
} | ||
|
||
class PanZoomInteraction extends Interaction { | ||
private zoom; | ||
constructor(public elementToListenTo: D3.Selection, public renderers: Component[], public xScale: Scale, public yScale: Scale) { | ||
constructor(componentToListenTo: Component, public renderers: Component[], public xScale: QuantitiveScale, public yScale: QuantitiveScale) { | ||
super(componentToListenTo); | ||
this.zoom = d3.behavior.zoom(); | ||
this.zoom(elementToListenTo); | ||
this.zoom.x(this.xScale.scale); | ||
this.zoom.y(this.yScale.scale); | ||
var throttledZoom = _.throttle(() => this.rerenderZoomed(), 30); | ||
var throttledZoom = _.throttle(() => this.rerenderZoomed(), 16); | ||
this.zoom.on("zoom", throttledZoom); | ||
|
||
this.registerWithComponent(); | ||
} | ||
|
||
public anchor(hitBox: D3.Selection) { | ||
super.anchor(hitBox); | ||
this.zoom(hitBox); | ||
} | ||
|
||
private rerenderZoomed() { | ||
var translate = this.zoom.translate(); | ||
console.log(translate); | ||
var scale = this.zoom.scale(); | ||
this.renderers.forEach((r) => { | ||
r.zoom(translate, scale); | ||
}) | ||
} | ||
} | ||
|
||
class AreaInteraction extends Interaction { | ||
/* | ||
This class is responsible for any kind of interaction in which you brush over an area | ||
of a renderer and plan to execute some logic based on the selected area. | ||
Right now it only works for XYRenderers, but we can make the interface more general in | ||
the future. | ||
You pass it a rendererComponent (:XYRenderer) and it sets up events so that you can draw | ||
a rectangle over it. Then, you pass it callbacks that the AreaInteraction will execute on | ||
the selected region. The first callback (areaCallback) will be passed a FullSelectionArea | ||
object which contains info on both the pixel and data range of the selected region. | ||
The selectionCallback will be passed a D3.Selection object that contains the elements bound | ||
to the data in the selection region. You can use this, for example, to change their class | ||
and display properties. | ||
*/ | ||
private static CLASS_DRAG_BOX = "drag-box"; | ||
private dragInitialized = false; | ||
private dragBehavior; | ||
private origin = [0,0]; | ||
private location = [0,0]; | ||
private constrainX: (n: number) => number; | ||
private constrainY: (n: number) => number; | ||
private dragBox: D3.Selection; | ||
|
||
constructor( | ||
private rendererComponent: XYRenderer, | ||
public areaCallback?: (a: FullSelectionArea) => any, | ||
public selectionCallback?: (a: D3.Selection) => any, | ||
public indicesCallback?: (a: number[]) => any | ||
) { | ||
super(rendererComponent); | ||
this.dragBehavior = d3.behavior.drag(); | ||
this.dragBehavior.on("dragstart", () => this.dragstart()); | ||
this.dragBehavior.on("drag", () => this.drag()); | ||
this.dragBehavior.on("dragend", () => this.dragend()); | ||
this.registerWithComponent(); | ||
} | ||
|
||
private dragstart(){ | ||
this.dragBox.attr("height", 0).attr("width", 0); | ||
var availableWidth = parseFloat(this.hitBox.attr("width")); | ||
var availableHeight = parseFloat(this.hitBox.attr("height")); | ||
// the constraint functions ensure that the selection rectangle will not exceed the hit box | ||
var constraintFunction = (min, max) => (x) => Math.min(Math.max(x, min), max); | ||
this.constrainX = constraintFunction(0, availableWidth); | ||
this.constrainY = constraintFunction(0, availableHeight); | ||
} | ||
|
||
private drag(){ | ||
if (!this.dragInitialized) { | ||
this.origin = [d3.event.x, d3.event.y]; | ||
this.dragInitialized = true; | ||
} | ||
|
||
this.location = [this.constrainX(d3.event.x), this.constrainY(d3.event.y)]; | ||
var width = Math.abs(this.origin[0] - this.location[0]); | ||
var height = Math.abs(this.origin[1] - this.location[1]); | ||
var x = Math.min(this.origin[0], this.location[0]); | ||
var y = Math.min(this.origin[1], this.location[1]); | ||
this.dragBox.attr("x", x).attr("y", y).attr("height", height).attr("width", width); | ||
} | ||
|
||
private dragend(){ | ||
if (!this.dragInitialized) { | ||
return; | ||
// It records a tap as a dragstart+dragend, but this can have unintended consequences. | ||
// only trigger logic if we actually did some dragging. | ||
} | ||
this.dragInitialized = false; | ||
var xMin = Math.min(this.origin[0], this.location[0]); | ||
var xMax = Math.max(this.origin[0], this.location[0]); | ||
var yMin = Math.min(this.origin[1], this.location[1]); | ||
var yMax = Math.max(this.origin[1], this.location[1]); | ||
var pixelArea = {xMin: xMin, xMax: xMax, yMin: yMin, yMax: yMax}; | ||
var dataArea = this.rendererComponent.invertXYSelectionArea(pixelArea); | ||
var fullArea = {pixel: pixelArea, data: dataArea}; | ||
if (this.areaCallback != null) { | ||
this.areaCallback(fullArea); | ||
} | ||
if (this.selectionCallback != null) { | ||
var selection = this.rendererComponent.getSelectionFromArea(fullArea); | ||
this.selectionCallback(selection); | ||
} | ||
if (this.indicesCallback != null) { | ||
var indices = this.rendererComponent.getDataIndicesFromArea(fullArea); | ||
this.indicesCallback(indices); | ||
} | ||
} | ||
|
||
public clearBox() { | ||
this.dragBox.attr("height", 0).attr("width", 0); | ||
} | ||
|
||
public anchor(hitBox: D3.Selection) { | ||
super.anchor(hitBox); | ||
var cname = AreaInteraction.CLASS_DRAG_BOX; | ||
var element = this.componentToListenTo.element; | ||
this.dragBox = element.append("rect").classed(cname, true).attr("x", 0).attr("y", 0); | ||
hitBox.call(this.dragBehavior); | ||
} | ||
} | ||
|
||
class BrushZoomInteraction extends AreaInteraction { | ||
/* | ||
This is an extension of the AreaInteraction which is used for zooming into a selected region. | ||
It takes the XYRenderer to initialize the AreaInteraction on, and the xScale and yScale to be | ||
scaled according to the domain of the data selected. Note that the xScale and yScale given to | ||
the BrushZoomInteraction can be distinct from those that the renderer depends on, e.g. if you | ||
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, public indicesCallback?: (a: number[]) => any) { | ||
super(eventComponent); | ||
this.areaCallback = this.zoom; | ||
this.indicesCallback = indicesCallback; | ||
} | ||
|
||
public zoom(area: FullSelectionArea) { | ||
var originalXDomain = this.xScale.domain(); | ||
var originalYDomain = this.yScale.domain(); | ||
var xDomain = [area.data.xMin, area.data.xMax]; | ||
var yDomain = [area.data.yMin, area.data.yMax]; | ||
|
||
var xOrigDirection = originalXDomain[0] > originalXDomain[1]; | ||
var yOrigDirection = originalYDomain[0] > originalYDomain[1]; | ||
var xDirection = xDomain[0] > xDomain[1]; | ||
var yDirection = yDomain[0] > yDomain[1] | ||
// make sure we don't change inversion of the scale by zooming | ||
|
||
if (xDirection != xOrigDirection) {xDomain.reverse();}; | ||
if (yDirection != yOrigDirection) {yDomain.reverse();}; | ||
|
||
|
||
this.xScale.domain(xDomain); | ||
this.yScale.domain(yDomain); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
///<reference path="../lib/d3.d.ts" /> | ||
|
||
class LabelComponent extends Component { | ||
public CLASS_TEXT_LABEL = "text-label"; | ||
|
||
public xAlignment = "CENTER"; | ||
public yAlignment = "CENTER"; | ||
|
||
private textElement: D3.Selection; | ||
private text:string; | ||
private textHeight = 0; | ||
private textWidth = 0; | ||
private isVertical = false; | ||
private rotationAngle = 0; | ||
private orientation = "horizontal"; | ||
|
||
constructor(text: string, orientation?: string) { | ||
super(); | ||
this.classed(this.CLASS_TEXT_LABEL, true); | ||
this.text = text; | ||
if (orientation === "horizontal" || orientation === "vertical-left" || orientation === "vertical-right") { | ||
this.orientation = orientation; | ||
} else if (orientation != null) { | ||
throw new Error(orientation + " is not a valid orientation for LabelComponent"); | ||
} | ||
} | ||
|
||
public rowWeight(): number; | ||
public rowWeight(newVal: number): Component; | ||
public rowWeight(newVal?: number): any { | ||
if (newVal != null) { | ||
throw new Error("Row weight cannot be set on Label."); | ||
return this; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
public colWeight(): number; | ||
public colWeight(newVal: number): Component; | ||
public colWeight(newVal?: number): any { | ||
if (newVal != null) { | ||
throw new Error("Col weight cannot be set on Label."); | ||
return this; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
public rowMinimum(): number; | ||
public rowMinimum(newVal: number): Component; | ||
public rowMinimum(newVal?: number): any { | ||
if (newVal != null) { | ||
throw new Error("Row minimum cannot be directly set on Label."); | ||
return this; | ||
} else { | ||
return this.textHeight; | ||
} | ||
} | ||
|
||
public colMinimum(): number; | ||
public colMinimum(newVal: number): Component; | ||
public colMinimum(newVal?: number): any { | ||
if (newVal != null) { | ||
throw new Error("Col minimum cannot be directly set on Label."); | ||
return this; | ||
} else { | ||
return this.textWidth; | ||
} | ||
} | ||
|
||
public anchor(element: D3.Selection) { | ||
super.anchor(element); | ||
this.textElement = this.element.append("text") | ||
.attr("alignment-baseline", "middle") | ||
.text(this.text); | ||
|
||
var clientHeight = this.textElement.node().clientHeight; | ||
var clientWidth = this.textElement.node().clientWidth; | ||
|
||
if (this.orientation === "horizontal") { | ||
this.textElement.attr("transform", "translate(0 " + clientHeight/2 + ")"); | ||
this.textHeight = clientHeight; | ||
this.textWidth = clientWidth; | ||
} else { | ||
this.textWidth = clientHeight; | ||
this.textHeight = clientWidth; | ||
if (this.orientation === "vertical-right") { | ||
this.textElement.attr("transform", "rotate(90) translate(0 " + (-clientHeight/2) + ")"); | ||
} else if (this.orientation === "vertical-left") { | ||
this.textElement.attr("transform", "rotate(-90) translate(" + (-clientWidth) + " " + clientHeight/2 + ")"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
class TitleLabel extends LabelComponent { | ||
public CLASS_TITLE_LABEL = "title-label"; | ||
constructor(text: string, orientation?: string) { | ||
super(text, orientation); | ||
this.classed(this.CLASS_TITLE_LABEL, true); | ||
} | ||
} | ||
|
||
class AxisLabel extends LabelComponent { | ||
public CLASS_AXIS_LABEL = "axis-label"; | ||
constructor(text: string, orientation?: string) { | ||
super(text, orientation); | ||
this.classed(this.CLASS_AXIS_LABEL, true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
///<reference path="../lib/chai/chai.d.ts" /> | ||
///<reference path="../lib/chai/chai-assert.d.ts" /> | ||
///<reference path="../lib/mocha/mocha.d.ts" /> | ||
///<reference path="../lib/d3.d.ts" /> | ||
|
||
///<reference path="../src/axis.ts" /> | ||
///<reference path="../src/table.ts" /> | ||
///<reference path="../src/renderer.ts" /> | ||
///<reference path="../src/utils.ts" /> | ||
///<reference path="testUtils.ts" /> | ||
|
||
var assert = chai.assert; | ||
|
||
function assertComponentXY(component: Component, x: number, y: number, message: string) { | ||
// use <any> to examine the private variables | ||
var xOffset = (<any> component).xOffset; | ||
var yOffset = (<any> component).yOffset; | ||
assert.equal(xOffset, x, message); | ||
assert.equal(yOffset, y, message); | ||
} | ||
|
||
describe("Component behavior", () => { | ||
it("fixed-width component will align to the right spot", () => { | ||
var svg = generateSVG("300", "300"); | ||
var component = new Component(); | ||
component.rowMinimum(100).colMinimum(100); | ||
component.anchor(svg); | ||
component.computeLayout(); | ||
assertComponentXY(component, 0, 0, "top-left component aligns correctly"); | ||
|
||
component.xAlignment = "CENTER"; | ||
component.yAlignment = "CENTER"; | ||
component.computeLayout(); | ||
assertComponentXY(component, 100, 100, "center component aligns correctly"); | ||
|
||
component.xAlignment = "RIGHT"; | ||
component.yAlignment = "BOTTOM"; | ||
component.computeLayout(); | ||
assertComponentXY(component, 200, 200, "bottom-right component aligns correctly"); | ||
svg.remove(); | ||
}) | ||
it("component defaults are as expected", () => { | ||
var c = new Component(); | ||
assert.equal(c.rowMinimum(), 0, "rowMinimum defaults to 0"); | ||
assert.equal(c.rowWeight() , 0, "rowWeight defaults to 0"); | ||
assert.equal(c.colMinimum(), 0, "colMinimum defaults to 0"); | ||
assert.equal(c.colWeight() , 0, "colWeight defaults to 0"); | ||
assert.equal(c.xAlignment, "LEFT", "xAlignment defaults to LEFT"); | ||
assert.equal(c.yAlignment, "TOP" , "yAlignment defaults to TOP"); | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
function generateSVG(width, height) { | ||
return d3.select("body").append("svg:svg").attr("width", width).attr("height", height); | ||
} |