Skip to content

Instantly share code, notes, and snippets.

@d3noob
Last active December 20, 2015 22:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save d3noob/6202580 to your computer and use it in GitHub Desktop.
Save d3noob/6202580 to your computer and use it in GitHub Desktop.
Leanpub book data investigations

This file can be used (in conjunction with the appropriate JavaScript libraries noted in the code) with a copy of the csv of book sales from Leanpub. It is a file designed to be available in conjunction with the blog post on d3noob.org that investigated changes in book downloads.

The csv file should have a search and replace carried out on it to replace all instances of a white space (an ordinary 'space' character) with an underscore '_'.

<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment