average count on day of week

by Gordon Woodhull

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.9/d3.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.7/crossfilter.js"></script>
<script src=" //cdnjs.cloudflare.com/ajax/libs/dc/1.7.1/dc.js"></script>
<div id="chart1" class="dc-chart">
    <strong>Average count per day of week</strong>
    <div class="clearfix"></div>
</div>

CSS

div.dc-chart {
    float: left;
}
.dc-chart rect.bar {
    stroke: none;
    cursor: pointer;
}
.dc-chart rect.bar:hover {
    fill-opacity: .5;
}
.dc-chart rect.stack1 {
    stroke: none;
    fill: red;
}
.dc-chart rect.stack2 {
    stroke: none;
    fill: green;
}
.dc-chart rect.deselected {
    stroke: none;
    fill: #ccc;
}
.dc-chart .pie-slice {
    fill: white;
    font-size: 12px;
    cursor: pointer;
}
.dc-chart .pie-slice.external {
    fill: black;
}
.dc-chart .pie-slice :hover {
    fill-opacity: .8;
}
.dc-chart .pie-slice.highlight {
    fill-opacity: .8;
}
.dc-chart .selected path {
    stroke-width: 3;
    stroke: #ccc;
    fill-opacity: 1;
}
.dc-chart .deselected path {
    stroke: none;
    fill-opacity: .5;
    fill: #ccc;
}
.dc-chart .axis path, .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
}
.dc-chart .axis text {
    font: 10px sans-serif;
}
.dc-chart .grid-line {
    fill: none;
    stroke: #ccc;
    opacity: .5;
    shape-rendering: crispEdges;
}
.dc-chart .grid-line line {
    fill: none;
    stroke: #ccc;
    opacity: .5;
    shape-rendering: crispEdges;
}
.dc-chart .brush rect.background {
    z-index: -999;
}
.dc-chart .brush rect.extent {
    fill: steelblue;
    fill-opacity: .125;
}
.dc-chart .brush .resize path {
    fill: #eee;
    stroke: #666;
}
.dc-chart path.line {
    fill: none;
    stroke-width: 1.5px;
}
.dc-chart circle.dot {
    stroke: none;
}
.dc-chart g.dc-tooltip path {
    fill: none;
    stroke: grey;
    stroke-opacity: .8;
}
.dc-chart path.area {
    fill-opacity: .3;
    stroke: none;
}
.dc-chart .node {
    font-size: 0.7em;
    cursor: pointer;
}
.dc-chart .node :hover {
    fill-opacity: .8;
}
.dc-chart .selected circle {
    stroke-width: 3;
    stroke: #ccc;
    fill-opacity: 1;
}
.dc-chart .deselected circle {
    stroke: none;
    fill-opacity: .5;
    fill: #ccc;
}
.dc-chart .bubble {
    stroke: none;
    fill-opacity: 0.6;
}
.dc-data-count {
    float: right;
   ...

JavaScript

/****************************************************
*  Random Data Generation
*****************************************************/
// Create a Random Date
function randomDate(start, end) {
    var d = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
    d.setHours(0,0,0,0);
    return d;
}

var start = new Date(2013, 10, 1);
var end = new Date(2013, 11, 1);
var stringLength = 2;

// Generate Random Data [Date, VowelString, Random Number, Random Measure]
var data = [];
for(var i = 0; i < 200; i++) {
    data[i] = [randomDate(start, end), Math.floor(Math.random() * 20), Math.floor(Math.random() * 30000)];   
}

/****************************************************
*  Charts
*****************************************************/
// Default chart sizes
var width = 400;
var height = 200;
var margins = {top: 15, right: 10, bottom: 20, left: 40};

// Crossfilter the data
var ndx = crossfilter(data);

// dimension on day of week
var dim1 = ndx.dimension(function(d) {
    return d[0].getDay();
});

function average_map(m) {
    var sum = 0;
    m.forEach(function(k, v) {
        sum += v;
    });
    return m.size() ? sum / m.size() : 0;
}
    
// group on day of week
var grp1 = dim1.group().reduce(
    function(p, v) { // add
        var day = d3.time.day(v[0]).getTime();
        p.map.set(day, p.map.has(day) ? p.map.get(day) + 1 : 1);
        p.avg = average_map(p.map);
        return p;
    },
    function(p, v) { // remove
        var day = d3.time.day(v[0]).getTime();
        p.map.set(day, p.map.has(day) ? p.map.get(day) - 1 : 0);
        p.avg = average_map(p.map);
        return p;
    },
    function() { // init
        return {map: d3.map(), avg: 0};
    }
);    
var chart1 = dc.barChart("#chart1")
.width(width)
.height(height)
.margins(margins)
.dimension(dim1)
.group(grp1)
.valueAccessor(function(kv) { return kv.value.avg; })
.gap(1)
.round(dc.round.floor)
.renderHorizontalGridLines(true)
.x(d3.scale.linear().domain([0,...