Skip to content

Instantly share code, notes, and snippets.

@jdarling
Last active May 8, 2018 12:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdarling/fb701fcaead21168cb7a to your computer and use it in GitHub Desktop.
Save jdarling/fb701fcaead21168cb7a to your computer and use it in GitHub Desktop.
Graph different parts of data in different DC charts (inbound/outbound as an example)

Really this is a hack that would be better off if it were in the base of crossfilter. As it is it will filter the data up properly but for some reason does not filter the data down properly.

What I mean is if you select something on the Inbound/Outbound chart the Inbound/Outbound Sums charts do not update accordingly but if you select data on any of the Inbound/Outbound Sums charts the other charts update accordingly.

View live at: https://rawgit.com/jdarling/fb701fcaead21168cb7a/raw/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js - Dimensional Charting Javascript Library</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="https://dc-js.github.io/dc.js/css/dc.css"/>
<style>
body, html{
margin: 0;
padding: 0;
}
#monthly-volume-chart g.y {
display: none;
}
.chart-container{
display: block;
height: 220px;
width: 240px;
float: left;
border: 1px dotted silver;
margin: 2px;
text-align: center;
}
.chart{
margin: 0 30px;
}
.chart-container h2{
margin: 0;
padding: 0 5px;
border-bottom: 1px solid silver;
text-align: left;
}
</style>
</head>
<body>
<p>From <a href="https://gist.github.com/jdarling/fb701fcaead21168cb7a">https://gist.github.com/jdarling/fb701fcaead21168cb7a</a></p>
<p>Really this is a hack that would be better off if it were
in the base of crossfilter. As it is it will filter the data
up properly but for some reason does not filter the data down
properly.</p>
<p>What I mean is if you select something on the Inbound/Outbound
chart the Inbound/Outbound Sums charts do not update accordingly
but if you select data on any of the Inbound/Outbound Sums charts
the other charts update accordingly.</p>
<div class="chart-container">
<h2>Inbound/Outbound</h2>
<div class="chart" id="inboundToOutboundChart"></div>
</div>
<div class="chart-container">
<h2>Group</h2>
<div class="chart" id="groupChart"></div>
</div>
<div class="chart-container">
<h2>Sums</h2>
<div class="chart" id="inboundAndOutboundSums"></div>
</div>
<div class="chart-container">
<h2>Inbound Sums</h2>
<div class="chart" id="inboundSums"></div>
</div>
<div class="chart-container">
<h2>Outbound Sums</h2>
<div class="chart" id="outboundSums"></div>
</div>
<div class="chart-container">
<h2>Sums (Pie)</h2>
<div class="chart" id="inboundAndOutboundSumsPie"></div>
</div>
<div class="chart-container">
<h2>Inbound Sums (Pie)</h2>
<div class="chart" id="inboundSumsPie"></div>
</div>
<div class="chart-container">
<h2>Outbound Sums (Pie)</h2>
<div class="chart" id="outboundSumsPie"></div>
</div>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="https://dc-js.github.io/dc.js/js/dc.js"></script>
<script type="text/javascript">
var gainOrLossChart = dc.pieChart('#inboundToOutboundChart');
var groupChart = dc.pieChart('#groupChart');
var inboundAndOutboundSums = dc.rowChart('#inboundAndOutboundSums');
var inboundSumsChart = dc.rowChart('#inboundSums');
var outboundSumsChart = dc.rowChart('#outboundSums');
var inboundAndOutboundSumsPie = dc.pieChart('#inboundAndOutboundSumsPie');
var inboundSumsPie = dc.pieChart('#inboundSumsPie');
var outboundSumsPie = dc.pieChart('#outboundSumsPie');
// This is the magic override method
var filterGroup = function(group, k){
var _all = group.all;
group.all = function(){
var all = _all();
return all.filter(k);
};
return group;
};
var ndx = new crossfilter([
{
duration: 123.000,
direction: 'inbound',
group: 1,
name: 'item 1'
},
{
duration: 53.253,
direction: 'outbound',
group: 2,
name: 'item 2'
},
{
name: 'foobar'
},
{
duration: 198.000,
direction: 'inbound',
group: 1,
name: 'item 3'
},
{
duration: 202.789,
direction: 'inbound',
group: 2,
name: 'item 4'
},
].filter(function(d){
return !!d.duration;
}));
var nameDimension = ndx.dimension(function(d){
return d.name + '-' + d.direction.substr(0, 1);
});
var nameGroup = nameDimension.group().reduceSum(function(d){
return d.duration;
});
var groupDimension = ndx.dimension(function(d){
return 'Group '+d.group;
});
var groupGroup = groupDimension.group().reduceSum(function(d){
return d.duration;
});
var directionDimension = ndx.dimension(function(d){
return d.direction;
});
var directionGroup = directionDimension.group().reduceSum(function(d){
return d.duration;
});
var addDirection = function(direction){
return function(p, v){
if(v.direction===direction){
return p+v.duration;
}
return 0;
};
};
var removeDirection = function(direction){
return function(p, v){
if(v.direction===direction){
return p-v.duration;
}
return 0;
};
};
// Create a custom dimension that retains the information
// to be kept so we can filter the view later on
var seperateDirectionDimension = ndx.dimension(function(d){
return {
name: d.name,
direction: d.direction,
duration: d.duration,
valueOf: function(){
return this.name + '-' + this.direction.substr(0, 1);
}
};
});
var inboundDimension = seperateDirectionDimension;
// Now create a filtered group based on the direction using our overrider
var inboundGroup = filterGroup(seperateDirectionDimension.group(), function(d){
return d.key.direction === 'inbound';
});
var outboundDimension = seperateDirectionDimension;
// Now create a filtered group based on the direction using our overrider
var outboundGroup = filterGroup(seperateDirectionDimension.group(), function(d){
return d.key.direction === 'inbound';
});
gainOrLossChart
.width(180) // (optional) define chart width, :default = 200
.height(180) // (optional) define chart height, :default = 200
.radius(80) // define pie radius
.dimension(directionDimension) // set dimension
.group(directionGroup) // set group
;
groupChart
.width(180) // (optional) define chart width, :default = 200
.height(180) // (optional) define chart height, :default = 200
.radius(80) // define pie radius
.dimension(groupDimension) // set dimension
.group(groupGroup) // set group
;
inboundAndOutboundSums.width(180)
.height(180)
.margins({top: 20, left: 10, right: 10, bottom: 20})
.group(nameGroup)
.dimension(nameDimension)
;
inboundSumsChart.width(180)
.height(180)
.margins({top: 20, left: 10, right: 10, bottom: 20})
.group(inboundGroup)
.dimension(inboundDimension)
.label(function(d){
return d.key.name;
})
.valueAccessor(function(d){
return d.key.duration;
})
;
outboundSumsChart.width(180)
.height(180)
.margins({top: 20, left: 10, right: 10, bottom: 20})
.group(outboundGroup)
.dimension(outboundDimension)
.label(function(d){
return d.key.name;
})
.valueAccessor(function(d){
return d.key.duration;
})
;
inboundAndOutboundSumsPie
.width(180) // (optional) define chart width, :default = 200
.height(180) // (optional) define chart height, :default = 200
.radius(80) // define pie radius
.dimension(nameDimension) // set dimension
.group(nameGroup) // set group
;
inboundSumsPie
.width(180) // (optional) define chart width, :default = 200
.height(180) // (optional) define chart height, :default = 200
.radius(80) // define pie radius
.dimension(inboundDimension) // set dimension
.group(inboundGroup) // set group
.label(function(d){
return d&&d.key?d.key.name:null;
})
.valueAccessor(function(d){
return d&&d.key?d.key.duration:null;
})
;
outboundSumsPie
.width(180) // (optional) define chart width, :default = 200
.height(180) // (optional) define chart height, :default = 200
.radius(80) // define pie radius
.dimension(outboundDimension) // set dimension
.group(outboundGroup) // set group
.label(function(d){
return d&&d.key?d.key.name:null;
})
.valueAccessor(function(d){
return d&&d.key?d.key.duration:null;
})
;
dc.renderAll();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment