Responsive Design for Data Visualization

Post on 17-Jul-2015

94 views 0 download

Transcript of Responsive Design for Data Visualization

RESPONSIVE DESIGN

BASICS

STRATEGIES FOR RESPONSIVE DESIGN

1

“Targets a specific experience but makes

allowances for smaller devices” - ZURB

MOBILE LAST GRACEFUL DEGRADATION

Start your design with a single column layout.

One column forces you to focus only on the

most essential goals of your project.

Consider the mobile context when deciding

which features to include and exclude.

MOBILE FIRST PROGRESSIVE ENHANCEMENT

Don’t design mobile for a specific device

(e.g. iPhone style)

Design for features not for screens

PROTIPS

BREAKPOINTS & MEDIA QUERIES FOR RESPONSIVE DESIGN

2

Browser widths that have a media query

declaration to change the layout once the

browser is within the declared range.

BREAKPOINTS

@media only screen and (min-device-width : 320px) and (max-device-width : 480px) { /* Styles */ }

STANDARD BREAKPOINT

MOBILE

@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) { /* Styles */ }

STANDARD BREAKPOINT

TABLET

Select custom breakpoints that are more

suitable for the design

PROTIP

CSS PRE-PROCESSORS & FRONT-END FRAMEWORKS

3

Takes code written in the

preprocessed language and then

converts it into standard CSS

CSS PRE-PROCESSOR

It saves a lot of time because it makes your

CSS easier to maintain.

It allows you to write less redundant code

by using variables and functions.

WHY TO USE ONE

Syntactically Awesome Stylesheets

http://sass-lang.com

$font-stack: Helvetica, sans-serif;$primary-color: #333;

body { font: 100% $font-stack; color: $primary-color;}

SASS CSS

body { font: 100% Helvetica, sans-serif; color: #333;}

nav { ul { margin: 0; padding: 0; list-style: none; }

li { display: inline-block; }

a { display: block; padding: 6px 12px; text-decoration: none; }}

SASS CSSnav ul { margin: 0; padding: 0; list-style: none;}

nav li { display: inline-block;}

nav a { display: block; padding: 6px 12px; text-decoration: none;}

// _reset.scss

html,body,ul,ol { margin: 0; padding: 0;}

SASS CSS

html, body, ul, ol { margin: 0; padding: 0;}

body { font: 100% Helvetica, sans-serif; background-color: #efefef;}

/* base.scss */

@import 'reset';

body { font: 100% Helvetica, sans-serif; background-color: #efefef;}

Leaner CSS

http://lesscss.org/

@base: #f938ab;

.box-shadow(@style, @c) when (iscolor(@c)) { -webkit-box-shadow: @style @c; box-shadow: @style @c;}.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) { .box-shadow(@style, rgba(0, 0, 0, @alpha));}.box { color: saturate(@base, 5%); border-color: lighten(@base, 30%); div { .box-shadow(0 0 5px, 30%) }}

LESS CSS.box { color: #fe33ac; border-color: #fdcdea;}.box div { -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);}

A collection of production ready HTML/CSS/

JavaScript components that can be further

modified to suit custom projects

FRONT-END FRAMEWORK

quick and easy

tested

PROS

hard to customize

sometimes

updating can break

your design

CONS

http://getbootstrap.com/

BOOTSTRAP USING LESS/SASS

http://foundation.zurb.com/

FOUNDATION USING SASS

BOOTSTRAP FOUNDATION

<!-- Foundation Grid Syntax --><div class="row">  <div class="six columns">    <p>Lorem ipsum...</p>  </div>  <div class="six columns">    <p>Lorem ipsum...</p>  </div></div>

<!-- Bootstrap Grid Syntax --><div class="row">  <div class="span6">    <p>Lorem ipsum...</p>  </div>  <div class="span6">    <p>Lorem ipsum...</p>  </div></div>

RESPONSIVE DESIGN FOR DATA VISUALIZATION

4

Size and scale SVG

elements based on their

containers.

Don’t hardcode your sizes!

Use variables instead to make scaling easier.

PROTIP

var margin = {top: 10, left: 10, bottom: 10, right: 10}

, width = parseInt(d3.select('#map').style('width'))

, width = width - margin.left - margin.right

, mapRatio = .5

, height = width * mapRatio;

This gets the container width of the graph

In this case #map is the container div

var margin = {top: 10, left: 10, bottom: 10, right: 10}

, width = parseInt(d3.select('#map').style('width'))

, width = width - margin.left - margin.right

, mapRatio = .5

, height = width * mapRatio;

Remove the margin size from the width

var margin = {top: 10, left: 10, bottom: 10, right: 10}

, width = parseInt(d3.select('#map').style('width'))

, width = width - margin.left - margin.right

, mapRatio = .5

, height = width * mapRatio;

Adjust the height relative to the size of the width

var projection = d3.geo.albersUsa() .scale(width) .translate([width / 2, height / 2]);

var path = d3.geo.path() .projection(projection);

Use the width variable to set the scale

Resize when the window

size changes.

d3.select(window).on('resize', resize);

function resize() { width = parseInt(d3.select('#map').style('width')); width = width - margin.left - margin.right; height = width * mapRatio; projection .translate([width / 2, height / 2]) .scale(width); map .style('width', width + 'px') .style('height', height + 'px');

map.select('.land').attr('d', path); map.selectAll('.state').attr('d', path);}

Catch the window resize event and call resize()

d3.select(window).on('resize', resize);

function resize() { width = parseInt(d3.select('#map').style('width')); width = width - margin.left - margin.right; height = width * mapRatio; projection .translate([width / 2, height / 2]) .scale(width); map .style('width', width + 'px') .style('height', height + 'px');

map.select('.land').attr('d', path); map.selectAll('.state').attr('d', path);}

Adjust things when the window size changes

d3.select(window).on('resize', resize);

function resize() { width = parseInt(d3.select('#map').style('width')); width = width - margin.left - margin.right; height = width * mapRatio; projection .translate([width / 2, height / 2]) .scale(width); map .style('width', width + 'px') .style('height', height + 'px');

map.select('.land').attr('d', path); map.selectAll('.state').attr('d', path);}

Update the projection

d3.select(window).on('resize', resize);

function resize() { width = parseInt(d3.select('#map').style('width')); width = width - margin.left - margin.right; height = width * mapRatio; projection .translate([width / 2, height / 2]) .scale(width); map .style('width', width + 'px') .style('height', height + 'px');

map.select('.land').attr('d', path); map.selectAll('.state').attr('d', path);}

Resize the map container div

d3.select(window).on('resize', resize);

function resize() { width = parseInt(d3.select('#map').style('width')); width = width - margin.left - margin.right; height = width * mapRatio; projection .translate([width / 2, height / 2]) .scale(width); map .style('width', width + 'px') .style('height', height + 'px');

map.select('.land').attr('d', path); map.selectAll('.state').attr('d', path);}

Redraw the map graph

FRAMEWORKS FOR D3.JS

5

d3.chart is a small framework that allows one to

define reusable charts that are repeatable,

configurable, extensible and composable

http://misoproject.com/d3-chart/

http://nvd3.org/

NVD3

http://c3js.org/

C3JS

http://dimplejs.org

DIMPLE

GABRIEL FLORIT ON RESPONSIVE DESIGN & DATA VISUALIZATION

6

Gabriel Florit creates data visualizations at the Boston

Globe, and gave a talk about the surprising difficulties of

bringing the principles of responsive design to data viz at

the OpenVis Conference.

https://www.youtube.com/watch?v=BrmwjVdaxMM