Uses the DC.JS (http://nickqizhu.github.io/dc.js/) and Crossfilter.js (http://square.github.io/crossfilter/) libraries to create linked charts for comparing ratings given to service journeys.
xxxxxxxxxx
<html lang="en">
<head>
<title>Customer Experience Ratings</title>
<meta charset="UTF-8">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="dc-edit.js"></script>
<script src="https://rawgithub.com/nickqizhu/dc.js/master/web/js/crossfilter.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="dc.css"/>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
</head>
<body>
<div class='container' id='main-container'>
<div class='content'>
<div class='container' style='font: 12px sans-serif;'>
<div class='row'>
<div class='span12'>
<h3>Customer Experience Ratings</h3>
</div>
</div>
<div class='row'>
<div class='span12' id='rowChart'>
<h4>Summary score for each interaction (<a href="javascript:dc.filterAll(); dc.renderAll();">reset</a>)
</h4>
</div>
</div>
<div class='row'>
<div class='span12' id='seriesChart'>
<h4>Summary for the journey</h4>
</div>
</div>
<div class='row'>
<div class='span12' id='datatable'>
<h4>Details</h4>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var rowChart = dc.rowChart("#rowChart");
var seriesChart = dc.seriesChart("#seriesChart");
var datatable = dc.dataTable("#datatable");
var ndx, runDimension, runGroup;
var chartHeight = 200;
var chartWidth = 868;
d3.csv("cem2.csv", function(error, experiments) {
experiments.forEach(function(d) {
d.Step = +d.Step;
});
ndx = crossfilter(experiments);
// row chart
function reduceAddAvg(attr) {
return function(p,v) {
++p.count
p.sum += +v[attr];
p.avg = p.sum/p.count;
return p;
};
}
function reduceRemoveAvg(attr) {
return function(p,v) {
--p.count
p.sum -= +v[attr];
p.avg = p.sum/p.count;
return p;
};
}
function reduceInitAvg() {
return {count:0, sum:0, avg:0};
}
var interactionDim = ndx.dimension(function(d) {return d.Interaction; });
var interactionGroup = interactionDim.group().reduceSum(function(d) { return +d.Outcome; });
var avgInteractionGroup = interactionDim.group().reduce(reduceAddAvg('Outcome'), reduceRemoveAvg('Outcome'), reduceInitAvg);
//print_filter("interactionDim");
rowChart
.width(chartWidth)
.height(300)
.margins({top: 5, left: 50, right: 10, bottom: 50})
.dimension(interactionDim)
.valueAccessor(function(p) { return p.value.avg; })
.group(avgInteractionGroup)
.colors(d3.scale.category10())
.label(function (d){
return d.key ;
})
.title(function(d){return d.value;})
.elasticX(false)
.turnOnControls(true)
//.x(d3.scale.linear().domain([-3,3]))
.xAxis().ticks(4);
rowChart.renderlet(function (chart) {
chart.selectAll("text")
.attr('transform', 'translate(0,0)');
});
// series chart
runDimension = ndx.dimension(function(d) {return [d.Interaction, +d.Step]; });
runGroup = runDimension.group().reduceSum(function(d) { return +d.Outcome; });
var avgRunGroup = runDimension.group().reduce(reduceAddAvg('Outcome'), reduceRemoveAvg('Outcome'), reduceInitAvg);
//runGroup = runDimension.group().reduceSum(function(d) { return +d.Outcome; });
print_filter("avgInteractionGroup");
print_filter("runGroup");
print_filter("avgRunGroup");
seriesChart
.width(chartWidth)
.height(chartHeight)
.chart(function(c) { return dc.lineChart(c).interpolate('linear'); })
.margins({ top: 5, left: 50, right: 10, bottom: 50 })
.x(d3.scale.linear().domain([1,12]))
.y(d3.scale.linear().domain([-3.5,3.5]))
.brushOn(false)
.yAxisLabel("Rating")
.xAxisLabel("Step")
.elasticY(false)
//.turnOnControls(true)
.dimension(runDimension)
.group(avgRunGroup)
//.title(function(d){ return getvalues(d);} )
.mouseZoomable(false)
.seriesAccessor(function(d) {return "Expt: " + d.key[0];})
.keyAccessor(function(d) {return +d.key[1];})
.valueAccessor(function(d) {return +d.value.avg;});
//.legend(dc.legend().x(chartWidth-150).y(0).itemHeight(13).gap(5).horizontal(1).legendWidth(140).itemWidth(70));
seriesChart.renderlet(function (chart) {
chart.selectAll("g.x")
.attr('transform', 'translate(62,71)');
});
//seriesChart.xAxis().attr('transform', 'translate(62,71)');
//data table
datatable
.dimension(interactionDim)
.group(function(d) { return "Details of the journey"})
.size(15) // number of rows to return
.columns([
function(d) { return +d.Step; },
function(d) { return d.Interaction; },
function(d) { return d.Product; },
function(d) { return d.Summary; },
function(d) { return d.Collateral; },
function(d) { return d.Outcome; }
])
.sortBy(function(d){ return d.Step; })
.order(d3.ascending);
dc.renderAll();
//d3.selectAll(".axis x").attr("transform", "translate(-10,-10)");
//d3.select("axis x").attr("transform", "translate(0," + (chartHeight/2) + ")")
function print_filter(filter){
var f=eval(filter);
if (typeof(f.length) != "undefined") {}else{}
if (typeof(f.top) != "undefined") {f=f.top(Infinity);}else{}
if (typeof(f.dimension) != "undefined") {f=f.dimension(function(d) { return "";}).top(Infinity);}else{}
console.log(filter+"("+f.length+") = "+JSON.stringify(f).replace("[","[\n\t").replace(/}\,/g,"},\n\t").replace("]","\n]"));
}
});
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
Updated missing url https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js to https://rawgithub.com/nickqizhu/dc.js/master/web/js/crossfilter.js
https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
https://d3js.org/d3.v3.min.js
https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js
https://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js