Skip to content

Instantly share code, notes, and snippets.

@noahpryor
Created October 4, 2013 03:29
Show Gist options
  • Save noahpryor/6820557 to your computer and use it in GitHub Desktop.
Save noahpryor/6820557 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js - Dimensional Charting Javascript Library</title>
<meta charset="UTF-8">
<link rel="https://raw.github.com/NickQiZhu/dc.js/master/web/css/dc.css" style="text/stylesheet">
<link rel="https://raw.github.com/NickQiZhu/dc.js/master/web/css/bootstrap.css" rel="stylesheet" type="text/css" />
<style>
#monthly-volume-chart g.y {
display: none;
}
</style>
</head>
<body>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/jquery.js"></script>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/bootstrap.js"></script>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/d3.js"></script>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js"></script>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/dc.js"></script>
<div class="container">
<div class="row">
<div id="yearly-bubble-chart" class="dc-chart">
<strong>Yearly Performance</strong> (radius: fluctuation/index ratio, color: gain/loss)
<a class="reset" href="javascript:yearlyBubbleChart.filterAll();dc.redrawAll();"
style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div id="gain-loss-chart">
<strong>Days by Gain/Loss</strong>
<a class="reset" href="javascript:gainOrLossChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
<div id="quarter-chart">
<strong>Quarters</strong>
<a class="reset" href="javascript:quarterChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
<div id="day-of-week-chart">
<strong>Day of Week</strong>
<a class="reset" href="javascript:dayOfWeekChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
<div id="fluctuation-chart">
<strong>Days by Fluctuation(%)</strong>
<span class="reset" style="display: none;">range: <span class="filter"></span></span>
<a class="reset" href="javascript:fluctuationChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div id="monthly-move-chart">
<strong>Monthly Index Abs Move & Volume/500,000 Chart</strong>
<span class="reset" style="display: none;">range: <span class="filter"></span></span>
<a class="reset" href="javascript:moveChart.filterAll();volumeChart.filterAll();dc.redrawAll();"
style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div>
<div class="dc-data-count">
<span class="filter-count"></span> selected out of <span class="total-count"></span> records | <a
href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a>
</div>
</div>
<table class="table table-hover dc-data-table">
<thead>
<tr class="header">
<th>Date</th>
<th>Open</th>
<th>Close</th>
<th>Change</th>
<th>Volume</th>
</tr>
</thead>
</table>
</div>
<div class="clearfix"></div>
</div>
</div>
</body>
</html>
var gainOrLossChart = dc.pieChart("#gain-loss-chart");
var quarterChart = dc.pieChart("#quarter-chart");
var dayOfWeekChart = dc.rowChart("#day-of-week-chart");
d3.csv("https://rawgithub.com/NickQiZhu/dc.js/master/web/ndx.csv", function(data) {
/* since its a csv file we need to format the data a bit */
var dateFormat = d3.time.format("%m/%d/%Y");
var numberFormat = d3.format(".2f");
data.forEach(function(e) {
e.dd = dateFormat.parse(e.date);
e.month = d3.time.month(e.dd); // pre-calculate month for better performance
});
//### Create Crossfilter Dimensions and Groups
//See the [crossfilter API](https://github.com/square/crossfilter/wiki/API-Reference) for reference.
var ndx = crossfilter(data);
var all = ndx.groupAll();
var yearlyDimension = ndx.dimension(function(d) {
return d3.time.year(d.dd).getFullYear();
});
var yearlyPerformanceGroup = yearlyDimension.group().reduce(
/* callback for when data is added to the current filter results */
function(p, v) {
++p.count;
p.absGain += +v.close - +v.open;
p.fluctuation += Math.abs(+v.close - +v.open);
p.sumIndex += (+v.open + +v.close) / 2;
p.avgIndex = p.sumIndex / p.count;
p.percentageGain = (p.absGain / p.avgIndex) * 100;
p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100;
return p;
},
/* callback for when data is removed from the current filter results */
function(p, v) {
--p.count;
p.absGain -= +v.close - +v.open;
p.fluctuation -= Math.abs(+v.close - +v.open);
p.sumIndex -= (+v.open + +v.close) / 2;
p.avgIndex = p.sumIndex / p.count;
p.percentageGain = (p.absGain / p.avgIndex) * 100;
p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100;
return p;
},
/* initialize p */
function() {
return {
count: 0,
absGain: 0,
fluctuation: 0,
fluctuationPercentage: 0,
sumIndex: 0,
avgIndex: 0,
percentageGain: 0
};
}
);
var dateDimension = ndx.dimension(function(d) {
return d.dd;
});
/* monthly index avg fluctuation in percentage */
var moveMonths = ndx.dimension(function(d) {
return d.month;
});
var monthlyMoveGroup = moveMonths.group().reduceSum(function(d) {
return Math.abs(+d.close - +d.open);
});
var volumeByMonthGroup = moveMonths.group().reduceSum(function(d) {
return d.volume / 500000;
});
var indexAvgByMonthGroup = moveMonths.group().reduce(
function(p, v) {
++p.days;
p.total += (+v.open + +v.close) / 2;
p.avg = Math.round(p.total / p.days);
return p;
},
function(p, v) {
--p.days;
p.total -= (+v.open + v.close) / 2;
p.avg = (p.days === 0) ? 0 : Math.round(p.total / p.days);
return p;
},
function() {
return {
days: 0,
total: 0,
avg: 0
};
}
);
var gainOrLoss = ndx.dimension(function(d) {
return +d.open > +d.close ? "Loss" : "Gain";
});
var gainOrLossGroup = gainOrLoss.group();
var fluctuation = ndx.dimension(function(d) {
return Math.round((d.close - d.open) / d.open * 100);
});
var fluctuationGroup = fluctuation.group();
var quarter = ndx.dimension(function(d) {
var month = d.dd.getMonth();
if (month <= 2)
return "Q1";
else if (month > 3 && month <= 5)
return "Q2";
else if (month > 5 && month <= 8)
return "Q3";
else
return "Q4";
});
var quarterGroup = quarter.group().reduceSum(function(d) {
return d.volume;
});
var dayOfWeek = ndx.dimension(function(d) {
var day = d.dd.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 dayOfWeekGroup = dayOfWeek.group();
//### Define Chart Attributes
//Define chart attributes using fluent methods. See the [dc API Reference](https://github.com/NickQiZhu/dc.js/blob/master/web/docs/api-1.7.0.md) for more information
//
//#### Bubble Chart
// #### Pie/Donut Chart
// Create a pie chart and use the given css selector as anchor. You can also specify
// an optional chart group for this chart to be scoped within. When a chart belongs
// to a specific group then any interaction with such chart will only trigger redraw
// on other charts within the same chart group.
gainOrLossChart
.width(180) // (optional) define chart width, :default = 200
.height(180) // (optional) define chart height, :default = 200
.radius(80) // define pie radius
.dimension(gainOrLoss) // set dimension
.group(gainOrLossGroup) // set group
/* (optional) by default pie chart will use group.key as it's label
* but you can overwrite it with a closure */
.label(function(d) {
if (gainOrLossChart.hasFilter() && !gainOrLossChart.hasFilter(d.data.key))
return d.data.key + "(0%)";
return d.data.key + "(" + Math.floor(d.data.value / all.value() * 100) + "%)";
});
quarterChart.width(180)
.height(180)
.radius(80)
.innerRadius(30)
.dimension(quarter)
.group(quarterGroup);
dayOfWeekChart.width(180)
.height(180)
.margins({
top: 20,
left: 10,
right: 10,
bottom: 20
})
.group(dayOfWeekGroup)
.dimension(dayOfWeek)
.colors(['#3182bd', '#6baed6', '#9ecae1', '#c6dbef', '#dadaeb'])
.label(function(d) {
return d.key.split(".")[1];
})
.title(function(d) {
return d.value;
})
.elasticX(true)
.xAxis().ticks(4);
dc.dataCount(".dc-data-count")
.dimension(ndx)
.group(all);
dc.dataTable(".dc-data-table")
.dimension(dateDimension)
.group(function(d) {
var format = d3.format("02d");
return d.dd.getFullYear() + "/" + format((d.dd.getMonth() + 1));
})
.size(10)
.columns([
function(d) {
return d.date;
},
function(d) {
return d.open;
},
function(d) {
return d.close;
},
function(d) {
return numberFormat(d.close - d.open);
},
function(d) {
return d.volume;
}
])
.sortBy(function(d) {
return d.dd;
})
.order(d3.ascending)
.renderlet(function(table) {
table.selectAll(".dc-table-group").classed("info", true);
});
dc.renderAll();
});
// Determine the current version of dc with `dc.version`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment