Skip to content

Instantly share code, notes, and snippets.

@1Cr18Ni9
Last active February 9, 2017 02:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1Cr18Ni9/ae2fd1a31642a18256b0a18af676ff06 to your computer and use it in GitHub Desktop.
Save 1Cr18Ni9/ae2fd1a31642a18256b0a18af676ff06 to your computer and use it in GitHub Desktop.
Towards Reusable Charts
license: mit
country income
France 14
Russia 22
Japan 13
South Korea 34
Argentina 28
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.tick line, path.domain{stroke: #555;stroke-width: 1;fill: none;}
.tick text{fill: #555;}
.grid path{stroke-width: 0;fill: none;}
.grid line{stroke: #eee;stroke-width: 1;fill: none;}
</style>
</head>
<body>
<div id="container"></div>
<script>
// Implement D3 with a barchart,
// so that we can reuse it everywhere and
// avoid any global variables contaimination.
d3.svg.myBarchart = function(){
//@STEP1: default properties
var margin = {top: 20, bottom: 50, left: 45, right: 45},
axisPadding = 5,
svgWidth = 600,
svgHeight = 400,
xValue = function(d){ return d.country; },
yValue = function(d){ return +d.income; },
xScale = d3.scale.ordinal(),
yScale = d3.scale.linear(),
xAxis = d3.svg.axis().scale(xScale).orient('bottom'),
yAxis = d3.svg.axis().orient('left'),
barColor = 'steelblue',
textTransform = null; // Example:{transform: 'rotate(90)', x: 10, y: -5,}
//@STEP2.1: main function definition
function barchart(selection){
selection.each(function(data){
data = data.map(function(d,i){
return [xValue(d), yValue(d)];
});
// now updat all scales and axises
var graphWidth = svgWidth - (margin.left + margin.right),
graphHeight = svgHeight - (margin.top + margin.bottom),
xAxisItems = data.map(function(d){ return d[0]; });
xScale
.domain(xAxisItems)
.rangeBands([0, graphWidth], 0.1);
yScale
.domain([0, d3.max(data, function(d){ return d[1]; })])
.range([0, graphHeight]);
// -------- Show Time --------
var svg = d3.select(this) // THIS is the current selection.
.selectAll('svg')
.data([data])
.enter() // if none svg exists, creat a new one.
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight);
var xGroup = svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(' + [margin.left, margin.top + graphHeight + axisPadding] + ')');
var yGroup = svg.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(' + [margin.left - axisPadding, margin.top] + ')');
xGroup.call(xAxis);
yGroup.call(yAxis.scale(yScale.copy().range([graphHeight, 0])));
var graphGroup = svg.append('g')
.attr('class', 'graphGroup')
.attr('transform', 'translate(' + [margin.left, margin.top + graphHeight] + ')');
graphGroup
.selectAll('rect')
.data(data)
.enter()
.append('rect')
.each(function(d,i){
d3.select(this).attr({
width : xScale.rangeBand(),
height: yScale(d[1]),
x : xScale.range()[i],
y : -yScale(d[1]),
fill : barColor,
'stroke-width': 0,
})
});
// grid lines
var yGrid = d3.svg.axis().scale(yScale.copy().range([graphHeight, 0])).orient('left')
.tickSize(-graphWidth, 0)
.tickFormat('');
var gridGroup = svg.append('g')
.attr('class', 'grid')
.attr('transform', 'translate(' + [margin.left, margin.top] + ')');
gridGroup.call(yGrid);
});
// xAxis text transformation if textTransform is not null
if(textTransform) {
d3.selectAll('.x.axis text')
.attr('style', 'text-anchor:start;')
.attr(textTransform);
}
}
//@STEP2.2: setter-getter functions
barchart.margin = function(_){
if(!arguments.length) return margin;
margin = _;
return barchart;
};
barchart.axisPadding = function(_){
if(!arguments.length) return axisPadding;
axisPadding = _;
return barchart;
};
barchart.svgWidth = function(_){
if(!arguments.length) return svgWidth;
svgWidth = _;
return barchart;
};
barchart.svgHeight = function(_){
if(!arguments.length) return svgHeight;
svgHeight = _;
return barchart;
};
barchart.xValue = function(_){
if(!arguments.length) return xValue;
xValue = _;
return barchart;
};
barchart.yValue = function(_){
if(!arguments.length) return yValue;
yValue = _;
return barchart;
};
barchart.xScale = function(_){
if(!arguments.length) return xScale;
xScale = _;
return barchart;
};
barchart.yScale = function(_){
if(!arguments.length) return yScale;
yScale = _;
return barchart;
};
barchart.xAxis = function(_){
if(!arguments.length) return xAxis;
xAxis = _;
return barchart;
};
barchart.yAxis = function(_){
if(!arguments.length) return yAxis;
yAxis = _;
return barchart;
};
barchart.barColor = function(_){
if(!arguments.length) return barColor;
barColor = _;
return barchart;
};
barchart.textTransform = function(_){
if(!arguments.length) return textTransform;
textTransform = _;
return barchart;
};
//@STEP3: return the function object finnaly
return barchart;
}
// -< Implement End >-
// get the data and creat a selection
// which to be set as a container
var chart1 = d3.svg.myBarchart()
// reset some properties as needed
.margin({top: 20, bottom: 80, left: 45, right: 45})
.svgWidth(350)
.svgHeight(400)
.barColor('green')
.textTransform({transform: 'rotate(45)', dx: 5, dy: 5});
chart1.xAxis(chart1.xAxis().tickSize(0,0));
// loading data and creat a brand-new barchart
d3.csv('data.csv', function(error, data){
d3.select('#container')
.datum(data)
.call(chart1);
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment