Built with blockbuilder.org
Last active
November 11, 2015 03:53
-
-
Save biovisualize/1d432f2de77544e0fe2e to your computer and use it in GitHub Desktop.
Datavis pipeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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