Skip to content

Instantly share code, notes, and snippets.

@jfeldstein
Created October 25, 2013 05:47
Show Gist options
  • Save jfeldstein/7149939 to your computer and use it in GitHub Desktop.
Save jfeldstein/7149939 to your computer and use it in GitHub Desktop.
Charts, mah dog.
<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