Skip to content

Instantly share code, notes, and snippets.

@BenHeubl
Last active June 17, 2016 16:21
Show Gist options
  • Save BenHeubl/2ee2c7aad197d13ab280a5c5aea3ddf3 to your computer and use it in GitHub Desktop.
Save BenHeubl/2ee2c7aad197d13ab280a5c5aea3ddf3 to your computer and use it in GitHub Desktop.
responsive d3
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="w.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { width:100%; height: 100% }
text {
font-family: sans-serif;
font-size: 10px;
}
rect {
fill: #ededed;
}
rect:hover {
fill: #000000;
}
path {
fill: none;
stroke: #161616;
}
line {
stroke: #000000;
}
</style>
</head>
<body>
<svg width ="1000" heigth="350">
<g class="chart-wrapper" transform="translate(30,20)">
<g class="bars"></g>
<g class="x axis"></g>
<g class="y axis"> </g>
</svg>
<script>
var maxWidth = 900, rightPadding = 70;
var xScale, yScale, xAxisComponent, yAxisComponent;
var numBars = 2, yMax = 100;
var data = [55, 45],
labels = ["Leave", "Remain"];
var container = d3.select('svg g.chart-wrapper'),
barGroup = container.select('.bars')
xAxis = container.select('.x.axis')
yAxis = container.select('.y.axis');
function intToChar(i) {
return labels[i];
}
function randomData(data) {
for(var i = 0; i < numBars; i++)
data[i] = Math.random() * yMax;
return data;
}
function initChart() {
var width = 400, height = 300;
data = randomData(data);
// Initialise scales
xScale = d3.scale.ordinal()
.domain(data.map(function(d, i) {return intToChar(i);}))
.rangeBands([0, width], 0.04);
yScale = d3.scale.linear()
.domain([0, yMax])
.range([height, 0]);
// Build the x-axis
xAxisComponent = d3.svg.axis()
.scale(xScale)
.orient('bottom');
xAxis.attr('transform', 'translate(0,'+height+')');
// Build the y-axis
yAxisComponent = d3.svg.axis()
.scale(yScale)
.orient('left');
yAxis.call(yAxisComponent);
}
function initEvents() {
// Set up event handler for resizes
W.addListener(update);
// Update data button
d3.select('#update').on('click', function() {
data = randomData(data);
update();
});
}
function update() {
updateScales();
updateAxes();
updateBars();
}
function updateScales() {
var width = d3.min([W.getViewportWidth(), maxWidth]) - rightPadding;
xScale.rangeBands([0, width], 0.04);
}
function updateAxes() {
xAxis.transition().call(xAxisComponent);
}
function updateBars() {
var u = barGroup
.selectAll('rect')
.data(data);
u.enter()
.append('rect')
.classed("rectus", true);
u.exit()
.remove();
u.transition()
.attr('x', function(d, i) {return xScale(intToChar(i));})
.attr('width', xScale.rangeBand())
.attr('y', function(d) {return yScale(d);})
.attr('height', function(d) {return yScale(0) - yScale(d);});
}
initChart();
update();
initEvents();
</script>
</body>
;(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
root.W = factory();
}
}(this, function() {
/*! W 1.6.3 (https://github.com/pyrsmk/W) */
// Prepare
var listeners = [],
resize_trigger = false,
orientationchange = false,
orientationchange_trigger = false;
// Catch window resize event
if(window.addEventListener) {
if('onorientationchange' in window) {
orientationchange = true;
window.addEventListener('orientationchange', function() {
orientationchange_trigger = true;
}, false);
}
window.addEventListener('resize', function() {
resize_trigger = true;
}, false);
}
else{
window.attachEvent('onresize', function() {
resize_trigger = true;
});
}
// Verify resizes every 10ms
setInterval(function() {
var trigger = false;
if(orientationchange) {
if(orientationchange_trigger && resize_trigger) {
trigger = true;
}
}
else if(resize_trigger) {
trigger = true;
}
if(trigger && document.documentElement.clientWidth) {
orientationchange_trigger = false;
resize_trigger = false;
for(var i=0, j=listeners.length; i<j; ++i) {
listeners[i].func();
}
}
}, 10);
// Get screen orientation
function getOrientation() {
var landscape;
if('orientation' in window) {
// Mobiles
var orientation = window.orientation;
landscape = (orientation == 90 || orientation == -90);
}
else {
// Desktop browsers
landscape = window.innerWidth > window.innerHeight;
}
return landscape ? 'landscape' : 'portrait';
}
// Viewport resolution detection
function detectViewport(absolute) {
// Detect screen size
var screen_width = screen.width,
screen_height = screen.height;
if(getOrientation() == 'landscape' && screen_width < screen_height) {
screen_width = screen.height;
screen_height = screen.width;
}
// Absolute mode
if(absolute) {
return {
width: screen_width,
height: screen_height
};
}
// Relative mode
else {
var w = window.innerWidth,
h = window.innerHeight;
if(!w || !h || w > screen_width || h > screen_height || w == 980) {
w = window.outerWidth;
h = window.outerHeight;
}
if(!w || !h || w > screen_width || h > screen_height) {
w = screen.availWidth;
h = screen.availHeight;
}
return {width: w, height: h};
}
}
// Define W object
var W = {
getViewportDimensions: function(absolute) {
return detectViewport(absolute);
},
getViewportWidth: function(absolute) {
return detectViewport(absolute).width;
},
getViewportHeight: function(absolute) {
return detectViewport(absolute).height;
},
getOrientation: function() {
return getOrientation();
},
addListener: function(func, key) {
listeners.push({
func: func,
key: key
});
return func;
},
removeListener: function(key) {
for(var i=0, j=listeners.length; i<j; ++i) {
if(listeners[i].key == key) {
listeners.splice(i, 1);
break;
}
}
},
clearListeners: function() {
listeners = [];
},
trigger: function(key) {
for(var i=0, j=listeners.length; i<j; ++i) {
if(typeof key == 'undefined' || listeners[i].key == key) {
listeners[i].func();
}
}
}
};
return W;
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment