Skip to content

Instantly share code, notes, and snippets.

@biovisualize
Last active November 11, 2015 03:53
Show Gist options
  • Save biovisualize/1d432f2de77544e0fe2e to your computer and use it in GitHub Desktop.
Save biovisualize/1d432f2de77544e0fe2e to your computer and use it in GitHub Desktop.
Datavis pipeline
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
.axis .domain,
.axis line {
stroke: black;
fill: none;
stroke-width: 1;
}
.axis text {
fill: black;
}
.panel {
fill: white;
}
svg {
border: 1px solid silver;
}
.line {
stroke: skyblue;
}
</style>
</head>
<body>
<div class="chart-container"></div>
<script>
// Utilities
//////////////////////////////////////////
var piper = {};
piper.utils = {
pipeline: function(){
var fns = arguments;
var that = this;
return function(config) {
for (var i = 0; i < fns.length; i++) {
console.log(i, 'before', config);
var cache = fns[i].call(this, config);
config = that.mergeAll(config, cache);
console.log(i, 'after', config);
}
};
},
override: function(_objA, _objB){ for(var x in _objB){ if(x in _objA){ _objA[x] = _objB[x]; } } },
merge: function(obj1, obj2) {
for (var p in obj2) {
if (obj2[p] && obj2[p].constructor == Object ) {
if (obj1[p]) {
this.merge(obj1[p], obj2[p]);
continue;
}
}
obj1[p] = obj2[p];
}
},
mergeAll: function(){
var newObj = {};
var objs = arguments;
for(var i = 0; i < objs.length; i++){
this.merge(newObj, objs[i]);
}
return newObj;
}
};
// Modules
//////////////////////////////////////////
var data = function(_config){
var config = {
data: null
};
piper.utils.override(config, _config);
var dataConverted = config.data.map(function(d, i){ return {x: i, y: d}; });
return {
dataConverted: dataConverted
};
};
var scaleX = function(_config){
var config = {
dataConverted: null,
margin: null,
width: null
};
piper.utils.override(config, _config);
var chartWidth = config.width - config.margin.left - config.margin.right;
var dataX = config.dataConverted.map(function(d){ return d.x; });
var scaleX = d3.scale.linear()
.domain(d3.extent(dataX))
.range([0, chartWidth]);
return {
scaleX: scaleX
};
};
var scaleY = function(_config){
var config = {
dataConverted: null,
margin: null,
height: null
};
piper.utils.override(config, _config);
var chartHeight = config.height - config.margin.top - config.margin.bottom;
var dataY = config.dataConverted.map(function(d){ return d.y; });
var scaleY = d3.scale.linear()
.domain(d3.extent(dataY))
.range([0, chartHeight]);
return {
scaleY: scaleY
};
};
var axisX = function(_config){
var config = {
scaleX: null
};
piper.utils.override(config, _config);
var axisX = d3.svg.axis().scale(config.scaleX)
.orient('bottom')
.ticks(10);
return {
axisX: axisX
};
};
var axisY = function(_config){
var config = {
scaleY: null
};
piper.utils.override(config, _config);
var axisY = d3.svg.axis().scale(config.scaleY)
.orient('left')
.ticks(6);
return {
axisY: axisY
};
};
var panelComponent = function(_config){
var config = {
container: null,
width: null,
height: null,
margin: null
};
piper.utils.override(config, _config);
var root = d3.select(config.container)
.append('svg')
.attr({
'class': 'chart',
width: config.width,
height: config.height
});
var panel = root.append('g')
.attr({
'class': 'panel',
transform: 'translate(' + config.margin.left + ',' + config.margin.top + ')'
});
return {
root: root,
panel: panel
};
};
var axisComponentX = function(_config){
var config = {
axisX: null,
height: null,
panel: null,
margin: null
};
piper.utils.override(config, _config);
config.panel.append('g')
.attr({
'class': 'x axis',
transform: 'translate(' + [0, config.height - config.margin.top - config.margin.bottom] + ')'
})
.call(config.axisX);
return {};
};
var axisComponentY = function(_config){
var config = {
axisY: null,
panel: null
};
piper.utils.override(config, _config);
config.panel.append('g')
.attr({'class': 'y axis'})
.call(config.axisY);
return {};
};
var shapes = function(_config){
var config = {
panel: null,
dataConverted: null,
scaleX: null,
scaleY: null
};
piper.utils.override(config, _config);
var line = d3.svg.line()
.x(function(d){ return config.scaleX(d.x); })
.y(function(d){ return config.scaleY(d.y); });
config.panel.datum(config.dataConverted)
.append('path')
.attr({
'class': 'line',
d: line
});
return {};
};
// Pipeline
//////////////////////////////////////////
var lineChart = piper.utils.pipeline(
data,
scaleX,
scaleY,
axisX,
axisY,
panelComponent,
axisComponentX,
axisComponentY,
shapes
);
// Usage
//////////////////////////////////////////
var dataset = d3.range(100).map(function(d, i){ return Math.random()*100; });
var config = {
container: document.querySelector('.chart-container'),
data: dataset,
width: 400,
height: 300,
margin: {top: 20, right: 20, bottom: 40, left: 40}
};
lineChart(config);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment