Skip to content

Instantly share code, notes, and snippets.

@eesur
Created March 13, 2016 20:01
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 eesur/25bb20d5dad7b1f0846f to your computer and use it in GitHub Desktop.
Save eesur/25bb20d5dad7b1f0846f to your computer and use it in GitHub Desktop.
d3js | responsive development with W.js

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;
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment