dc
Version:
A multi-dimensional charting library built to work natively with crossfilter and rendered using d3.js
147 lines (129 loc) • 5.67 kB
HTML
<html lang="en">
<head>
<title>dc.js - Heatmap Filtering Example</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="../css/dc.css"/>
<style>
</style>
</head>
<body>
<h2>Michelson–Morley experiment</h2>
<div id="heatmap"></div>
<div id="barchart"></div>
<script type="text/javascript" src="../js/d3.js"></script>
<script type="text/javascript" src="../js/crossfilter.js"></script>
<script type="text/javascript" src="../js/dc.js"></script>
<script type="text/javascript">
var chartGroup = "chartGroup";
var heatmapChart = dc.heatMap("#heatmap", chartGroup);
var barChart = dc.barChart("#barchart", chartGroup);
d3.csv("../ndx.csv", function(error, data) {
var dateFormat = d3.time.format("%m/%d/%Y");
data.forEach(function (d) {
d.dd = dateFormat.parse(d.date);
d.month = d3.time.month(d.dd).getMonth(); // pre-calculate month for better performance
d.year = d3.time.year(d.dd).getFullYear();
d.close = +d.close; // coerce to number
d.open = +d.open;
});
var ndx = crossfilter(data),
monthOfTheYearDimension = ndx.dimension(function(d) { return [+d.month, +d.year]; }),
percentageGainByMonthOfYearGroup = monthOfTheYearDimension.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.count ? p.sumIndex / p.count : 0;
p.percentageGain = p.avgIndex ? (p.absGain / p.avgIndex) * 100 : 0;
p.fluctuationPercentage = p.avgIndex ? (p.fluctuation / p.avgIndex) * 100 : 0;
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.count ? p.sumIndex / p.count : 0;
p.percentageGain = p.avgIndex ? (p.absGain / p.avgIndex) * 100 : 0;
p.fluctuationPercentage = p.avgIndex ? (p.fluctuation / p.avgIndex) * 100 : 0;
return p;
},
/* initialize p */
function () {
return {count: 0, absGain: 0, fluctuation: 0, fluctuationPercentage: 0, sumIndex: 0, avgIndex: 0, percentageGain: 0};
}
);
var heatColorMapping = function(d) {
if (d < 0) {
return d3.scale.linear().domain([-23,0]).range(["red", "#e5e5e5"])(d);
}
else {
return d3.scale.linear().domain([0,23]).range(["#e5e5e5", "green"])(d);
}
};
heatColorMapping.domain = function() {
return [-23,23];
};
var fudge = 40;
heatmapChart
.width(window.innerWidth-20)
.height(window.innerHeight/2-fudge)
.dimension(monthOfTheYearDimension)
.group(percentageGainByMonthOfYearGroup)
.keyAccessor(function(d) { return +d.key[0]; })
.valueAccessor(function(d) { return +d.key[1]; })
.colorAccessor(function(d) { return +d.value.percentageGain; })
.title(function(d) {
return " Month: " + d.key[0] + "\n" +
" Year: " + d.key[1] + "\n" +
" Gain: " + d.value.percentageGain + "%";})
.colors(heatColorMapping)
.calculateColorDomain();
heatmapChart.xBorderRadius(0);
heatmapChart.yBorderRadius(0);
heatmapChart.render();
var monthlyDimension = ndx.dimension(function (d) { return +d.month; });
var percentageGainByMonthArrayGroup = monthlyDimension.group().reduce(
function(p,v) {
var absGain = v.close - v.open;
var percentageGain = v.open ? (absGain / v.open) * 100 : 0;
return p + percentageGain;
},
function(p,v) {
var absGain = v.close - v.open;
var percentageGain = v.open ? (absGain / v.open) * 100 : 0;
return p - percentageGain;
},
function() {
return 0;
}
);
barChart
.dimension(monthlyDimension)
.group(percentageGainByMonthArrayGroup)
.width(window.innerWidth-20)
.height(window.innerHeight/2-fudge)
.y(d3.scale.linear().domain([-10.0,100.0]))
.x(d3.scale.linear().domain([-0.5,11.5]))
.elasticY(true)
.centerBar(true);
barChart.render();
// respond to browser resize (not necessary if width/height is static)
window.onresize = function() {
heatmapChart
.width(window.innerWidth-20)
.height(window.innerHeight/2-fudge);
barChart
.width(window.innerWidth-20)
.height(window.innerHeight/2-fudge)
.rescale();
dc.redrawAll(chartGroup);
};
});
</script>
</body>
</html>