Created
October 25, 2013 05:47
-
-
Save jfeldstein/7149939 to your computer and use it in GitHub Desktop.
Charts, mah dog.
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
<html> | |
<head> | |
<script src="./js/jquery.js"></script> | |
<script src="./js/underscore.js"></script> | |
<script src="http://code.highcharts.com/highcharts.js"></script> | |
<script src="http://code.highcharts.com/modules/funnel.js"></script> | |
<script type="text/javascript" src="http://www.highcharts.com/highslide/highslide-full.min.js"></script> | |
<script type="text/javascript" src="http://www.highcharts.com/highslide/highslide.config.js" charset="utf-8"></script> | |
<link rel="stylesheet" type="text/css" href="http://www.highcharts.com/highslide/highslide.css" /> | |
<!-- Le styles --> | |
<link href="./css/bootstrap.css" rel="stylesheet"> | |
<style> | |
body { | |
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */ | |
} | |
.chart { | |
width: 100%; | |
height: 150px; | |
} | |
.breakout { | |
margin-top: 20px; | |
} | |
.breakout .chart { | |
height: 350px; | |
} | |
.chartcell:hover, .chartcell.active { | |
background-color: #DDD; | |
cursor: pointer; | |
} | |
.chartcell h3 { | |
padding-left: 5px; | |
} | |
.breakout .chart table th, | |
.breakout .chart table td { | |
padding: 5px 20px; | |
text-align: left; | |
} | |
</style> | |
<link href="./css/bootstrap-responsive.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div class="navbar navbar-inverse navbar-fixed-top"> | |
<div class="navbar-inner"> | |
<div class="container"> | |
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> | |
<span class="icon-bar"></span> | |
<span class="icon-bar"></span> | |
<span class="icon-bar"></span> | |
</button> | |
<a class="brand" href="#">Performance Dashboard</a> | |
<div class="nav-collapse collapse"> | |
<ul class="nav"> | |
<li class="active"><a href="#">Trends</a></li> | |
<li><a href="#about">Correlations</a></li> | |
</ul> | |
</div><!--/.nav-collapse --> | |
</div> | |
</div> | |
</div> | |
<div class="container"> | |
<h1>Trends</h1> | |
<!-- <div class="row"> | |
<div class="span5"> | |
<h3>Filters</h3> | |
<div id="filters"> | |
<form> | |
<fieldset> | |
<label for="start">Start</label> | |
<input name="start" id="start" value="01/01/2013"> | |
<label for="start">End</label> | |
<input name="end" id="end" value="01/31/2013"> | |
<label for="start">Source</label> | |
<select name="source" id="source"><option>All Traffic</option></select> | |
</fieldset> | |
</form> | |
</div> | |
</div> | |
</div> --> | |
<div class="row"> | |
<div class="span4 chartcell unique_visitors" data-reveal-breakout="unique_visitors_breakout"> | |
<h3> | |
Unique Visitors | |
<button class="more">Details</button> | |
</h3> | |
<div class="chart"></div> | |
</div> | |
<div class="span4 chartcell conversion_rate" data-reveal-breakout="conversion_rate_breakout"> | |
<h3> | |
Conversion Rate | |
<button class="more">Details</button> | |
</h3> | |
<div class="chart"></div> | |
</div> | |
<div class="span4 chartcell rev_per_user" data-reveal-breakout="rev_per_user_breakout"> | |
<h3> | |
Rev. per User | |
<button class="more">Details</button> | |
</h3> | |
<div class="chart"></div> | |
</div> | |
</div> | |
<div class="row breakout unique_visitors_breakout"> | |
<div class="span12"> | |
<h3>Unique Visiters by Traffic Source</h3> | |
<div class="chart"></div> | |
</div> | |
</div> | |
<div class="row breakout conversion_rate_breakout"> | |
<div class="span12"> | |
<h3>Conversion Funnel</h3> | |
<div class="chart"></div> | |
</div> | |
</div> | |
<div class="row breakout rev_per_user_breakout"> | |
<div class="span12"> | |
<h3>Retention by Cohort</h3> | |
<div class="chart"> | |
<table> | |
<thead> | |
<th>Cohort</th> | |
<th>Size</th> | |
</thead> | |
<tbody> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
</div> <!-- /container --> | |
<script type="text/javascript"> | |
$('[data-reveal-breakout] .more').click(function(){ | |
var $this = $(this).parents('[data-reveal-breakout]'); | |
var $breakout = $('.breakout.'+$this.data('reveal-breakout')); | |
$('[data-reveal-breakout]').removeClass('active'); | |
$('.breakout').hide(); | |
$this.addClass('active'); | |
$breakout.show(); | |
console.log("CHART ID", $breakout.find('.chart').data('highchartsChart')) | |
console.log("CHART", Highcharts.charts[$breakout.find('.chart').data('highchartsChart')]) | |
Highcharts.charts[$breakout.find('.chart').data('highchartsChart')].redraw(); | |
}) | |
dailyuniques = []; | |
conversionrates = []; | |
revs = []; | |
traffic = [[],[],[]]; | |
conversion_funnel = [1285, 980, 340, 210]; | |
cohorts = [ | |
{ | |
date: '2013-8-19', | |
count: 22, | |
retention: [4,0,0,0,0,0,0,0] | |
},{ | |
date: '2013-8-26', | |
count: 14, | |
retention: [8,1,0,0,0,0,0] | |
},{ | |
date: '2013-9-2', | |
count: 56, | |
retention: [12,4,1,0,0,0] | |
},{ | |
date: '2013-9-9', | |
count: 12, | |
retention: [13,3,1,0,0] | |
},{ | |
date: '2013-9-16', | |
count: 22, | |
retention: [13,4,3,0] | |
},{ | |
date: '2013-9-23', | |
count: 14, | |
retention: [12,4,4] | |
},{ | |
date: '2013-9-30', | |
count: 56, | |
retention: [14,10] | |
},{ | |
date: '2013-10-7', | |
count: 12, | |
retention: [13] | |
} | |
] | |
while(dailyuniques.length < 30) | |
dailyuniques.push(9000+100*Math.sin(dailyuniques.length)*Math.random()+1000*(dailyuniques.length/30)); | |
while(conversionrates.length < 30) | |
conversionrates.push(5*Math.sin(conversionrates.length/15)+conversionrates.length/30*6+20); | |
while(revs.length < 30) | |
revs.push((5*Math.sin(3.4+revs.length/20)+revs.length/30*6+20)/5); | |
while(traffic[0].length < 30) { | |
for(var i=0; i<3; i++) | |
traffic[i].push([ | |
Date.UTC(2013, 0, traffic[0].length+1), | |
Math.floor(9000+100*Math.sin(traffic[i].length))/3/(i+1)*Math.random()+333*(traffic[i].length/30) | |
]); | |
console.log(traffic) | |
} | |
for(var i=0; i<30; i++) { | |
traffic[0][i] = traffic[0][i]*i/15+3000; | |
traffic[1][i] = traffic[1][i]*i/55; | |
} | |
function chartOptions(type, opts){ | |
if(typeof type == 'object') { | |
opts = type; | |
type = 'line'; | |
} | |
var defaults = { | |
chart: { | |
type: type, | |
backgroundColor:'rgba(255, 255, 255, 0.1)' }, | |
title: { text: null }, | |
xAxis: { | |
type: 'datetime', | |
title: { | |
text: null | |
} | |
}, | |
yAxis: { | |
title: { | |
text: null | |
}, | |
}, | |
plotOptions: { | |
line: { | |
lineWidth: 4, | |
states: { | |
hover: { | |
lineWidth: 5 | |
} | |
}, | |
marker: { | |
enabled: false | |
}, | |
}, | |
area: { | |
stacking: 'normal', | |
lineColor: '#666666', | |
lineWidth: 1, | |
marker: { | |
lineWidth: 1, | |
lineColor: '#666666' | |
} | |
} | |
}, | |
legend: { enabled: false } | |
}; | |
return _.extend(defaults, opts); | |
} | |
$('.unique_visitors .chart').highcharts(chartOptions({ | |
series: [{ | |
name: 'Daily', | |
pointInterval: 24 * 3600 * 1000, | |
pointStart: Date.UTC(2013, 0, 01), | |
data: dailyuniques | |
}] | |
})); | |
$('.conversion_rate .chart').highcharts(chartOptions({ | |
yAxis: { | |
labels: { | |
format: '{value}%' | |
}, | |
title: { | |
text: null | |
} | |
}, | |
series: [{ | |
name: 'Conversion Rate', | |
pointInterval: 24 * 3600 * 1000, | |
pointStart: Date.UTC(2013, 0, 01), | |
data: conversionrates | |
}] | |
})); | |
$('.rev_per_user .chart').highcharts(chartOptions({ | |
yAxis: { | |
labels: { | |
format: '${value}' | |
}, | |
title: { | |
text: null | |
} | |
}, | |
series: [{ | |
name: 'Daily', | |
pointInterval: 24 * 3600 * 1000, | |
pointStart: Date.UTC(2013, 0, 01), | |
data: revs | |
}] | |
})); | |
var showMilestoneTooltip = function() { | |
console.log(this.series) | |
if(this.series.name != 'Milestones') return; | |
hs.htmlExpand(null, { | |
pageOrigin: { | |
x: this.pageX, | |
y: this.pageY | |
}, | |
headingText: Highcharts.dateFormat('%A, %b %e, %Y', this.x), | |
maincontentText: 'Received Funding.', | |
width: 200 | |
}); | |
}; | |
$('.unique_visitors_breakout .chart').highcharts(chartOptions('area', { | |
series: [{ | |
name: 'SEO', | |
data: traffic[0] | |
}, { | |
name: 'Blogs', | |
data: traffic[1] | |
}, { | |
name: 'Viral', | |
data: traffic[2] | |
}] | |
})); | |
$('.conversion_rate_breakout .chart').highcharts(chartOptions('column', { | |
xAxis: { | |
categories: [ | |
'Webpage Visit', | |
'Search', | |
'Add to Cart', | |
'Checkout' | |
] | |
}, | |
series: [{ | |
name: 'Conversion Funnel', | |
data: conversion_funnel | |
}] | |
})); | |
longestWeek = _(cohorts).max(function(cohort){ return cohort.retention.length; }); | |
for(var i=1; i<=longestWeek.retention.length; i++) { | |
$('.rev_per_user_breakout table thead tr').append('<th>Week '+i+'</th>'); | |
} | |
_(cohorts).each(function(cohort){ | |
var row = $('<tr></tr>'); | |
row.append('<td>'+cohort.date+'</td><td>'+cohort.count+'</td>'); | |
_(cohort.retention).each(function(retained){ row.append('<td>'+retained+'%</td>')}) | |
$('.rev_per_user_breakout table tbody').append(row); | |
}) | |
$('.breakout').hide(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment