|
<!DOCTYPE html> |
|
<html lang='en'> |
|
<head> |
|
<meta charset='utf-8'> |
|
|
|
<title>dc.js Experiment</title> |
|
|
|
<script src='js/d3.v3.js' type='text/javascript'></script> |
|
<script src='js/crossfilter.js' type='text/javascript'></script> |
|
<script src='js/dc2.js' type='text/javascript'></script> |
|
<script src='js/jquery-1.9.1.min.js' type='text/javascript'></script> |
|
<script src='js/bootstrap.min.js' type='text/javascript'></script> |
|
|
|
<link href='css/bootstrap.min.css' rel='stylesheet' type='text/css'> |
|
<link href='css/dc.css' rel='stylesheet' type='text/css'> |
|
|
|
<style type="text/css"></style> |
|
|
|
<style> |
|
h4 span { |
|
font-size:14px; |
|
font-weight:normal; |
|
} |
|
h2 { |
|
float: right; |
|
} |
|
h2 span { |
|
font-size:14px; |
|
font-weight:normal; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
|
|
<div class='container' style='font: 12px sans-serif;'> |
|
<div class="dc-data-count" style="float: left;"> |
|
<h2>Leanpub Book Downloads |
|
<span> |
|
<span class="filter-count"></span> |
|
selected out of |
|
<span class="total-count"></span> |
|
records | |
|
<a href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a> |
|
</span> |
|
</h2> |
|
</div> |
|
|
|
<div class='row'> |
|
<div class='span12' id='dc-downloads-chart'> |
|
<h4> |
|
Downloads per day |
|
<span> |
|
<a class="reset" |
|
href="javascript:downloadsPerDayChart.filterAll();dc.redrawAll();" |
|
style="display: none;"> |
|
reset |
|
</a> |
|
</span> |
|
</h4> |
|
</div> |
|
</div> |
|
|
|
<div class='row'> |
|
<div class='span12' id='dc-sales-chart'> |
|
<h4> |
|
Sales per day |
|
<span> |
|
<a class="reset" |
|
href="javascript:salesPerDayChart.filterAll();dc.redrawAll();" |
|
style="display: none;"> |
|
reset |
|
</a> |
|
</span> |
|
</h4> |
|
</div> |
|
</div> |
|
|
|
<div class='row'> |
|
<div class='span12' id='dc-royalties-chart'> |
|
<h4> |
|
Royalties per day |
|
<span> |
|
<a class="reset" |
|
href="javascript:royaltiesPerDayChart.filterAll();dc.redrawAll();" |
|
style="display: none;"> |
|
reset |
|
</a> |
|
</span> |
|
</h4> |
|
</div> |
|
</div> |
|
|
|
<div class='row'> |
|
<div class='span4' id='dc-dayweekdown-chart'> |
|
<h4> |
|
Downlaods per DoW |
|
<span> |
|
<a class="reset" |
|
href="javascript:dayOfWeekChartDown.filterAll();dc.redrawAll();" |
|
style="display: none;"> |
|
reset |
|
</a> |
|
</span> |
|
</h4> |
|
</div> |
|
<div class='span4' id='dc-dayweekroyal-chart'> |
|
<h4> |
|
Royalties per DoW |
|
<span> |
|
<a class="reset" |
|
href="javascript:dayOfWeekChartRoyal.filterAll();dc.redrawAll();" |
|
style="display: none;"> |
|
reset |
|
</a> |
|
</span> |
|
</h4> |
|
</div> |
|
<div class='span4' id='dc-dayweeksales-chart'> |
|
<h4> |
|
Sales per DoW |
|
<span> |
|
<a class="reset" |
|
href="javascript:dayOfWeekChartSales.filterAll();dc.redrawAll();" |
|
style="display: none;"> |
|
reset |
|
</a> |
|
</span> |
|
</h4> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script type="text/javascript"> |
|
|
|
// Create the dc.js chart objects & link to div |
|
var dayOfWeekChartDown = dc.rowChart("#dc-dayweekdown-chart"); |
|
var dayOfWeekChartRoyal = dc.rowChart("#dc-dayweekroyal-chart"); |
|
var dayOfWeekChartSales = dc.rowChart("#dc-dayweeksales-chart"); |
|
var downloadsPerDayChart = dc.lineChart("#dc-downloads-chart"); |
|
var salesPerDayChart = dc.lineChart("#dc-sales-chart"); |
|
var royaltiesPerDayChart = dc.lineChart("#dc-royalties-chart"); |
|
|
|
// load data from a csv file |
|
d3.csv("data/leanpub-D3-Tips-and-Tricks-sales-20130804_2.csv", function (data) { |
|
|
|
// format our data |
|
var dtgFormat = d3.time.format("%Y-%m-%d"); |
|
|
|
data.forEach(function(d) { |
|
d.dtg = dtgFormat.parse(d.Date_Purchased); |
|
d.value = +d.Author_and_Cause_Royalties.substr(1); |
|
if (d.value > 0) {return d.sales = 1;} |
|
else {return d.sales = 0;} |
|
}); |
|
|
|
// Run the data through crossfilter and load our 'facts' |
|
var facts = crossfilter(data); |
|
var all = facts.groupAll(); |
|
|
|
// time chart |
|
// var volumeByHour = facts.dimension(function(d) { return d3.time.hour(d.dtg); }); |
|
var volumeByDay = facts.dimension(function(d) { return d3.time.day(d.dtg); }); |
|
var volumeByDayGroupCount = volumeByDay.group().reduceCount(function(d) { return d.dtg; }); |
|
var volumeByDayGroupSum = volumeByDay.group().reduceSum(function(d) { return d.value; }); |
|
var volumeByDayGroupSales = volumeByDay.group().reduceSum(function(d) { return d.sales; }); |
|
|
|
// row chart Day of Week |
|
var dayOfWeek = facts.dimension(function (d) { |
|
var day = d.dtg.getDay(); |
|
switch (day) { |
|
case 0: |
|
return "0.Sun"; |
|
case 1: |
|
return "1.Mon"; |
|
case 2: |
|
return "2.Tue"; |
|
case 3: |
|
return "3.Wed"; |
|
case 4: |
|
return "4.Thu"; |
|
case 5: |
|
return "5.Fri"; |
|
case 6: |
|
return "6.Sat"; |
|
} |
|
}); |
|
var dayOfWeekGroupCount = dayOfWeek.group(); |
|
var dayOfWeekGroupSum = dayOfWeek.group().reduceSum(function(d) { return d.value; }); |
|
var dayOfWeekGroupSales = dayOfWeek.group().reduceSum(function(d) { return d.sales; }); |
|
|
|
// Create datatable dimension |
|
var timeDimension = facts.dimension(function (d) { |
|
return d.dtg; |
|
}); |
|
|
|
// Setup the charts |
|
|
|
// count all the facts |
|
dc.dataCount(".dc-data-count") |
|
.dimension(facts) |
|
.group(all); |
|
|
|
// downloads per day graph |
|
downloadsPerDayChart.width(960) |
|
.height(120) |
|
.transitionDuration(500) |
|
.margins({top: 10, right: 10, bottom: 20, left: 40}) |
|
.dimension(volumeByDay) |
|
.group(volumeByDayGroupCount) |
|
.elasticY(true) |
|
.x(d3.time.scale().domain(d3.extent(data, function(d) { return d.dtg; }))) |
|
.xAxis(); |
|
|
|
// sales per day graph /// NOT ACTUALLY DONE YET |
|
salesPerDayChart.width(960) |
|
.height(120) |
|
.transitionDuration(500) |
|
.margins({top: 10, right: 10, bottom: 20, left: 40}) |
|
.dimension(volumeByDay) |
|
.group(volumeByDayGroupSales) |
|
.elasticY(true) |
|
.x(d3.time.scale().domain(d3.extent(data, function(d) { return d.dtg; }))) |
|
.xAxis(); |
|
|
|
// royalties per day graph |
|
royaltiesPerDayChart.width(960) |
|
.height(120) |
|
.transitionDuration(500) |
|
.margins({top: 10, right: 10, bottom: 20, left: 40}) |
|
.dimension(volumeByDay) |
|
.group(volumeByDayGroupSum) |
|
.elasticY(true) |
|
.x(d3.time.scale().domain(d3.extent(data, function(d) { return d.dtg; }))) |
|
.xAxis() |
|
; |
|
|
|
// row chart downloads per day of week |
|
dayOfWeekChartDown.width(300) |
|
.height(220) |
|
.margins({top: 5, left: 10, right: 10, bottom: 20}) |
|
.dimension(dayOfWeek) |
|
.group(dayOfWeekGroupCount) |
|
.colors(d3.scale.category10()) |
|
.label(function (d){ |
|
return d.key.split(".")[1]; |
|
}) |
|
.title(function(d){return d.value;}) |
|
.elasticX(true) |
|
.xAxis().ticks(4); |
|
|
|
// row chart royalties per day of week |
|
dayOfWeekChartRoyal.width(300) |
|
.height(220) |
|
.margins({top: 5, left: 10, right: 10, bottom: 20}) |
|
.dimension(dayOfWeek) |
|
.group(dayOfWeekGroupSum) |
|
.colors(d3.scale.category10()) |
|
.label(function (d){ |
|
return d.key.split(".")[1]; |
|
}) |
|
.title(function(d){return d.value;}) |
|
.elasticX(true) |
|
.xAxis().ticks(4); |
|
|
|
// row chart sales per day of week |
|
dayOfWeekChartSales.width(300) |
|
.height(220) |
|
.margins({top: 5, left: 10, right: 10, bottom: 20}) |
|
.dimension(dayOfWeek) |
|
.group(dayOfWeekGroupSales) |
|
.colors(d3.scale.category10()) |
|
.label(function (d){ |
|
return d.key.split(".")[1]; |
|
}) |
|
.title(function(d){return d.value;}) |
|
.elasticX(true) |
|
.xAxis().ticks(4); |
|
|
|
|
|
// Render the Charts |
|
dc.renderAll(); |
|
|
|
}); |
|
|
|
</script> |
|
|
|
</body> |
|
</html> |