Simple example using W javascript library for responsive development with d3.js
Test by changing browser dimensions or rotating mobile. The rectangle remains the 1:4 ratio of the viewport.
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { font-family: Consolas, monaco, monospace; height: 100%;} | |
svg { width: 100%; height: 100%;} | |
</style> | |
<link href="//s3-us-west-2.amazonaws.com/colors-css/2.2.0/colors.min.css" rel="stylesheet"> | |
<body> | |
<svg id="vis"></svg> | |
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<!-- <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js" charset="utf-8"></script> --> | |
<!-- https://github.com/pyrsmk/W --> | |
<script src="W.js" charset="utf-8"></script> | |
<!-- d3 code --> | |
<script src="script-compiled.js" charset="utf-8"></script> | |
'use strict'; | |
// ensure viewport state is updated before loading elements | |
renderRect(); | |
appendText(); | |
updateText(); | |
// add a listener to catch responsive events | |
W.addListener(update); | |
function update() { | |
renderRect(); | |
updateText(); | |
} | |
function renderRect() { | |
// Get the current viewport width | |
var width = W.getViewportWidth(); | |
// Get the current viewport height | |
var height = W.getViewportHeight(); | |
var svg = d3.select('#vis').attr({ | |
preserveAspectRatio: 'xMidYMid meet', | |
viewBox: '0 0 ' + width + ' ' + height, | |
class: 'bg-silver' | |
}); | |
// render rect (ratio of screen) | |
if (svg.selectAll('.sampleRect').empty()) { | |
initRect(); | |
} | |
// update | |
svg.selectAll('.sampleRect').attr({ | |
width: width / 2, | |
height: height / 2, | |
x: width / 2 - width / 4, | |
y: height / 2 - height / 4 | |
}); | |
function initRect() { | |
svg.append('rect').attr({ | |
class: 'sampleRect fill-yellow', | |
width: width / 4, | |
height: height / 4, | |
x: width / 2 - width / 4, | |
y: height / 2 - height / 4 | |
}); | |
} | |
} | |
function appendText() { | |
var text = ['textOrientation', 'textWidth', 'textHeight']; | |
d3.select('#vis').selectAll('.details').data(text).enter().append('text').attr({ | |
class: 'details', | |
id: function id(d) { | |
return d; | |
}, | |
x: 25, | |
y: function y(d, i) { | |
return (i + 1) * 30; | |
} | |
}); | |
} | |
function updateText() { | |
// get the orientation of the device (return 'portrait' or 'landscape') | |
var orientation = W.getOrientation(); | |
// get the current viewport width | |
var width = W.getViewportWidth(); | |
// get the current viewport height | |
var height = W.getViewportHeight(); | |
var selection = d3.select('#vis'); | |
selection.select('#textOrientation').text('Orientation: ' + orientation); | |
selection.select('#textWidth').text('Viewport width: ' + width); | |
selection.select('#textHeight').text('Viewport height: ' + height); | |
} |
;(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.0 (https://github.com/pyrsmk/W) */ | |
// Prepare | |
var listeners = [], | |
trigger = false; | |
// Catch window resize event | |
if(window.addEventListener) { | |
if('onorientationchange' in window) { | |
window.addEventListener('orientationchange', function(){ | |
trigger = true; | |
}, false); | |
} | |
else{ | |
window.addEventListener('resize', function(){ | |
trigger = true; | |
}, false); | |
} | |
} | |
else{ | |
window.attachEvent('onresize', function() { | |
trigger = true; | |
}); | |
} | |
// Verify resizes every 10ms | |
setInterval(function() { | |
if(trigger && document.documentElement.clientWidth) { | |
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; | |
})); |