hub.packtpub.com Open in urlscan Pro
2606:4700:10::6816:af  Public Scan

URL: https://hub.packtpub.com/responsive-visualizations-using-d3js-and-bootstrap/
Submission: On May 15 via manual from FR — Scanned from FR

Form analysis 6 forms found in the DOM

GET https://hub.packtpub.com/

<form method="get" class="td-search-form" action="https://hub.packtpub.com/">
  <div class="td-search-close">
    <a href="#"><i class="td-icon-close-mobile"></i></a>
  </div>
  <div role="search" class="td-search-input">
    <span>Search</span>
    <input id="td-header-search-mob" type="text" value="" name="s" autocomplete="off">
  </div>
</form>

GET https://hub.packtpub.com/

<form method="get" class="td-search-form" action="https://hub.packtpub.com/">
  <div role="search" class="td-head-form-search-wrap">
    <input id="td-header-search" type="text" value="" name="s" autocomplete="off"><input class="wpb_button wpb_btn-inverse btn" type="submit" id="td-header-search-top" value="Search">
  </div>
</form>

POST #

<form id="loginForm" action="#" method="post">
  <div class="td-login-inputs"><input class="td-login-input" autocomplete="username" type="text" name="login_email" id="login_email" value="" required=""><label for="login_email">your username</label></div>
  <div class="td-login-inputs"><input class="td-login-input" autocomplete="current-password" type="password" name="login_pass" id="login_pass" value="" required=""><label for="login_pass">your password</label></div>
  <input type="button" name="login_button" id="login_button" class="wpb_button btn td-login-button" value="Login">
</form>

POST #

<form id="forgotpassForm" action="#" method="post">
  <div class="td-login-inputs"><input class="td-login-input" type="text" name="forgot_email" id="forgot_email" value="" required=""><label for="forgot_email">your email</label></div>
  <input type="button" name="forgot_button" id="forgot_button" class="wpb_button btn td-login-button" value="Send My Password">
</form>

POST https://hub.packtpub.com/wp-comments-post.php?wpe-comment-post=packtptn

<form action="https://hub.packtpub.com/wp-comments-post.php?wpe-comment-post=packtptn" method="post" id="commentform" class="comment-form" novalidate="">
  <div class="clearfix"></div>
  <div class="comment-form-input-wrap td-form-comment">
    <textarea placeholder="Comment:" id="comment" name="comment" cols="45" rows="8" aria-required="true"></textarea>
    <div class="td-warning-comment">Please enter your comment!</div>
  </div>
  <div class="comment-form-input-wrap td-form-author">
    <input class="" id="author" name="author" placeholder="Name:*" type="text" value="" size="30" aria-required="true">
    <div class="td-warning-author">Please enter your name here</div>
  </div>
  <div class="comment-form-input-wrap td-form-email">
    <input class="" id="email" name="email" placeholder="Email:*" type="text" value="" size="30" aria-required="true">
    <div class="td-warning-email-error">You have entered an incorrect email address!</div>
    <div class="td-warning-email">Please enter your email address here</div>
  </div>
  <div class="comment-form-input-wrap td-form-url">
    <input class="" id="url" name="url" placeholder="Website:" type="text" value="" size="30">
  </div>
  <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"><label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time
      I comment.</label></p>
  <p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Post Comment"> <input type="hidden" name="comment_post_ID" value="11213" id="comment_post_ID">
    <input type="hidden" name="comment_parent" id="comment_parent" value="0">
  </p>
  <p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="c6151dd4fd"></p>
  <p style="display: none !important;"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js" value="1715805600395">
    <script>
      document.getElementById("ak_js_1").setAttribute("value", (new Date()).getTime());
    </script>
  </p>
</form>

Name: mc-embedded-subscribe-formPOST https://packtpub.us11.list-manage.com/subscribe/post?u=693897ba2220b83ddb807103a&id=07395ea9cf&f_id=00fde3e1f0

<form action="https://packtpub.us11.list-manage.com/subscribe/post?u=693897ba2220b83ddb807103a&amp;id=07395ea9cf&amp;f_id=00fde3e1f0" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank">
  <div class="tdn-email-bar">
    <div class="tdn-input-wrap"><input type="email" name="EMAIL" aria-label="email" placeholder="Your email address" required=""></div>
    <div class="tdn-btn-wrap"><button class="tdn-submit-btn" type="submit" name="subscribe">JOIN</button></div>
  </div>
</form>

Text Content

 * Subscription
 * News
 * Tutorials


Search

Packt Hub
 * Subscription
 * News
   * 
     Malware Analysis
     
     
     TOP 6 CYBERSECURITY BOOKS FROM PACKT TO ACCELERATE YOUR CAREER
     
     
     Databases
     
     
     YOUR QUICK INTRODUCTION TO EXTENDED EVENTS IN ANALYSIS SERVICES FROM BLOG…
     
     
     Databases
     
     
     LOGGING THE HISTORY OF MY PAST SQL SATURDAY PRESENTATIONS FROM BLOG…
     
     
     Databases
     
     
     STORAGE SAVINGS WITH TABLE COMPRESSION FROM BLOG POSTS – SQLSERVERCENTRAL
     
     
     Databases
     
     
     DAILY COPING 31 DEC 2020 FROM BLOG POSTS – SQLSERVERCENTRAL
     
     
     
 * Tutorials
   * 
     Web Development
     
     
     LEARNING ESSENTIAL LINUX COMMANDS FOR NAVIGATING THE SHELL EFFECTIVELY 
     
     
     Programming
     
     
     EXPLORING THE STRATEGY BEHAVIORAL DESIGN PATTERN IN NODE.JS
     
     
     Web Development
     
     
     HOW TO INTEGRATE A MEDIUM EDITOR IN ANGULAR 8
     
     
     Languages
     
     
     IMPLEMENTING MEMORY MANAGEMENT WITH GOLANG’S GARBAGE COLLECTOR
     
     
     Tutorials
     
     
     HOW TO CREATE SALES ANALYSIS APP IN QLIK SENSE USING DAR…
     
     
     


 * Web Development
   * Front-End Web Development
   * Full-Stack Web Development
   * Server-Side Web Development
   * Web Design
   * CMS & E-Commerce
 * Data
   * Past Issues
   * Tutorials
   * News
   * Interviews
   * Podcasts
 * Mobile
   * Past Issues
   * Tutorials
   * News
   * Interviews
   * Podcasts
 * Programming
   * Application Development
   * Languages
   * Design Patterns
   * High Performance
   * Microservices
 * Cloud & Networking
   * DevOps
   * Cloud Computing
   * Networking
   * Servers
   * Virtualization
 * Security
   * Penetration Testing
   * Cybersecurity
   * Cryptography
   * Forensics
   * Malware Analysis
 * Game Development
   * 3D Game Development
   * 2D Game Development
   * Game AI
   * Game Design
   * Game Optimization
 * IoT & Hardware
   * Home Automation
   * Robotics
   * Single Board Computers
   * 3D Printing
   * Embedded Systems


Sign in
Welcome! Log into your account

your username
your password
Forgot your password? Get help
Password recovery
Recover your password

your email
A password will be e-mailed to you.

Home Data Tutorials Responsive Visualizations Using D3.js and Bootstrap
 * Data
 * Tutorials


RESPONSIVE VISUALIZATIONS USING D3.JS AND BOOTSTRAP

By
Packt
-
March 1, 2016 - 12:00 am
11965
0

21 min read

In this article by Christoph Körner, the author of the book Learning Responsive
Data Visualization, we will design and implement a responsive data visualization
using Bootstrap and Media Queries based on real data. We will cover the
following topics:

 * Absolute and relative units in the browsers
 * Drawing charts with percentage values
 * Adapting charts using JavaScript event listeners
 * Learning to adapt the resolution of the data
 * Using bootstrap’s Media Queries
 * Understanding how to use Media Queries in CSS, LESS and JavaScript
 * Learning how to use bootstrap’s grid system

(For more resources related to this topic, see here.)

First, we will discuss the most important absolute and relative units that are
available in modern browsers. You will learn the difference of absolute pixels,
relative percentages, em, rem, and many more.

In the next section, we will take a look at what is really needed for a chart to
be responsive. Adapting the width to the parent element is one of the
requirements, and you will learn about two different ways to implement this.
After this section, you will know when to use percentage values or JavaScript
event listeners. We will also take a look at adapting the data resolution, which
is another important property of responsive visualizations.

In the next section, we will explore Media Queries, and understand how we can
use them to make viewport depended responsive charts. We will take the advantage
of Bootstrap’s definitions of Media Queries for the most common device
resolutions to integrate them into our responsive chart using CSS or LESS.
Finally, we will also see how to include Media Queries into JavaScript.

In the last section, we will take a look at Bootstrap’s grid system and learn
how to seamlessly integrate it with the charts. This will give us not only some
great flexibility but will also make it easier to combine multiple charts to one
big dashboard application.




UNITS AND LENGTHS IN THE BROWSER

Creating a responsive design, bet it website or graphics, depends strongly on
the units and lengths that a browser can interpret. We can easily create an
element that fills the entire width of a container using the percentage values
that are relative to the parent container; whereas, achieving the same result
width absolute values could be very tricky. Thus, mastering responsive graphics
also means knowing all the absolute and relative units that are available in the
browser.


UNITS FOR ABSOLUTE LENGTHS

The most convenient and popular way in web design and development is to define
and measure lengths and dimensions in absolute units, usually in pixels. The
reason for this is that designers and developers often want to exactly specify
the exact dimensions of an object. The pixel unit called px has been introduced
as a visual unit based on a physical measurement to read from a device in the
distance of approximately one arm length; however, all the modern browsers can
also allow the definitions of lengths based on physical units. The following
list shows the most common absolute units and their relations to each other:

 * cm: centimeters (1 cm = 96px/2.54)
 * mm: millimeters (1 mm = 1/10th of 1 cm)
 * in: inches (1in = 2.54 cm = 96 px)
 * pt: points (1 pt = 1/72th of 1 in)
 * px: pixels (1 px = 1/96th of 1 in)

> More information on the origin and meaning of the pixel unit can be found in
> the CSS3 Specification available at
> http://www.w3.org/TR/css3-values/#viewport-relative-lengths.


UNITS FOR RELATIVE LENGTHS

In addition to Absolute lengths, relative lengths that are expressed as the
percentage of the width or height of a parent element has also been a common
technique to the style dynamic elements of web pages. Traditionally, the % unit
has always been the unit of choice for the preceding reason. However, with CSS3,
a couple of additional relative units have found their way into the browsers,
for example, to define a length relative to the font size of the element.

Here is a list of the relative length units that have been specified in the CSS3
specifications and will soon be available in modern browsers:

 * %: the percentage of the width/height of the absolute container
 * Em: the factor of font size of the element
 * Rem: the factor of font size of the root element
 * Vw: 1% of viewport’s width
 * vh: 1% viewport’s height
 * vmin: 1% of the viewport’s smaller dimension (either vw or vh)
 * vmax: 1% of the viewport’s larger dimension (either vw or vh)

I am aware that as a web developer, we cannot really take the advantage of any
technology that will be supported soon; however, I want to point out one unit
that will play an important role for feature web developers: the rem unit. The
rem unit defines the length of an element based on the font size of the root
node (the html node in this case), rather than the font size of the current
element such as em.

This rem unit is very powerful if we use it to define the lengths and spacings
of a layout because the layout can also adapt when the user increases the font
size of the browser (that is, for readability). I want to mention that Bootstrap
4 will replace all absolute pixel units for Media Queries by the rem units
because of this reason.

If we look at the following figure, we also see that rem units are already
supported in all major browsers. I recommend you to start replacing all your
absolute pixel units of your layout and spacing by the rem units:



Cross-browser compatibility of rem units

However, percentage units are not dead; we can still use them when they are
appropriate. We will use them later to draw SVG elements with dimensions based
on their parent elements’ dimensions.


UNITS FOR RESOLUTION

To round up the section of relative and absolute units, I want to mention that
we can also use resolutions in different units. These resolution units can be
used in Media Queries together with the min-resolution or max-resolution
attribute:

 * Dpi: dots per inch
 * dpcm: dots per centimeter
 * dppx: dots per px unit


MATHEMATICAL EXPRESSIONS

We often have the problem of dealing with rational numbers or expressions in
CSS; just imagine defining a 3-column grid with a width of 33% per column, or
imagine the need of computing a simple expression in the CSS file. CSS3 provides
a simple solution for this:

 * calc(exp): This computes the mathematical expression called exp, which can
   consist of lengths, values, and the operators called +, –, /, and *

> Note that the + and –operators must be surrounded by whitespace. Otherwise,
> they will be interpreted as a sign of the second number rather than the
> operator. Both the other operators called * and / don’t require a whitespace,
> but I encourage you to add them for consistency.

We can use these expression in the following snippets.

.col-4 {
width: calc(100%/3);
}
.col-sp-2 {
width: calc(50% - 2em);
}


The preceding examples look great; however, as we can see in the following
figure, we need to take care of the limitations of the browser compatibility:



Cross-browser compatibility of the calc() expression


RESPONSIVE CHARTS

Now that we know some basics about absolute and relative units, we can start to
define, design, and implement responsive charts. A responsive chart is a chart
that automatically adapts its look and feel to the resolution of the user’s
device; thus, responsive charts need to adapt the following properties:

 * The dimension (width and height)
 * The resolution of data points
 * The interactions and interaction areas.

Adapting the dimensions is most obvious. The chart should always scale and adapt
to the width of its parent element. In the previous section, you learned about
relative and absolute lengths, so one might think that simply using relative
values for the chart’s dimensions would be enough. However, there are multiple
ways with advantages and disadvantages to achieve this; in this section, we will
discuss three of them.

Adapting the resolution of the data is a little less obvious and often
neglected. The resolution of data points (the amount of data point per pixel)
should adapt, so that we can see more points on a device with a higher
resolution and less points on a low resolution screen. In this section we will
see that this can only be achieved using JavaScript event listeners and by
redrawing/updating the whole chart manually.

Adapting interactions and interaction areas is important for not just using
different screen resolutions but also different devices. We interact differently
with a TV than a computer, and we use different input devices on a desktop and
mobile phone. However, the chart will allow interactions and interaction areas
that are appropriate for a given device and screen resolution..


USING RELATIVE LENGTHS IN SVG

The first and most obvious solution for adapting the dimensions of a chart to
its parent container is the use of relative values for lengths and coordinates.
This means that when we define the chart once with relative values and the
browser takes care of recomputing all the values when the dimension of the
parent container has changed, there is no manual redrawing of the chart
required.

First, we will add some CSS styles to scale the SVG element to the full width of
the parent container:

.chart {
height: 16rem;
position: relative;
}
.chart > svg {
width: 100%;
height: 100%;
}


Next, we modify all our scales to work on a range at [0, 100] and subtract a
padding from both sides:

var xScale = d3.scale.ordinal()
.domain(flatData.map(xKey))
.rangeBands([padding, 100 - 2*padding]);

var yScale = d3.scale.linear()
.domain([0, d3.max(flatData, yKey)])
.range([100 - 2*padding, padding]);


Finally, we can draw the chart as before, but simply adding percentage signs %
at the end of the attributes—to indicate the use of percentage units:

$$bars
.attr('x', function(d) { return (xScale(d.x) + i*barWidth ) + '%'; })
.attr('y', function(d) { return yScale(d.y) + '%'; })
.attr('height', function(d) { return (yScale(0) - yScale(d.y)) + '%'; })
.attr('width', barWidth + '%')
.attr('fill', colors(data.key));


Observe that we only slightly modified the code to plot the bars in the bar
chart in order to use percentage values as coordinates for the attributes.
However, the effect of this small change is enormous. In the following figure,
we can see the result of the chart in a browser window:



Bar chart using relative lengths

If we now increase the size of the browser, the bar chart scales nicely to the
full width of the parent container. We can see the scaled chart in the following
figure:



Scaled bar chart using relative lengths

If you are not impressed by it now, you better be. This is awesome in my opinion
because it leaves all the hard work of recomputing the SVG element dimensions to
the browser. We don’t have to care about them, and these native computations
give us some maximal performance.

The previous example shows how to use percentage values to create a simple bar
chart. However, what we didn’t explain so far is why we didn’t add any axis and
labels to the chart. Well, despite the idea that we can exploit native rescaling
of the browser, we need to face the limitations of this technique. Relative
values are only allowed in standard attributes, such as width, height, x, y, cx,
cy—but not in SVG paths or transform functions.


CONCLUSION ABOUT USING RELATIVE LENGTHS

While this sounds like an excellent solution (and indeed it is wonderful for
certain use cases), it has two major drawbacks:

 * The percentage values are not accepted for the SVG transform attributes and
   for the d attribute in the path elements, only in standard attributes
 * Due to the fact that the browser is recomputing all the values automatically,
   we cannot adapt the resolution of the data of the charts

The first point is the biggest drawback, which means we can only position
elements using the standard attributes called width, height, x, y, cx, cy, and
more. However, we can still draw a bar chart that seamlessly adapts according to
the parent elements without the use of JavaScript event listeners.

The second argument doesn’t play a huge role anymore compared to the first one,
and it can be circumvented using additional JavaScript event listeners, but I am
sure you get the point.


USING THE JAVASCRIPT RESIZE EVENT

The last option is to use JavaScript event handlers and redraw the chart
manually when the dimensions of the parent container change. Using this
technique, we can always measure the width of the parent container (in absolute
units) and use this length to update and redraw the chart accordingly. This
gives us great flexibility over the data resolution, and we can adapt the chart
to a different aspect ratio when needed as well.


THE NATIVE RESIZE EVENT

Theoretically, this solution sounds brilliant. We simply watch the parent
container or even the SVG container itself (if it uses a width of 100%) for the
resize events, and then redraw the chart when the dimensions of the element
change. However, there does not exist a native resize event on the div or svg
element; modern browsers only support the resize events on the window element.
Hence, it triggers only if the dimensions of the browser window changes. This
means also that we need to clean up listeners once we remove a chart from the
page.

Although this is a limitation, in most cases, we can still use the windowresize
event to adapt the chart to its parent container; we have to just keep this in
our mind.

Let’s always use the parent container’s absolute dimensions for drawing and
redrawing the chart; we need to define the following things inside a redraw
function:

var width = chart.clientWidth;
var height = width / aspectRatio;


Now, we can add a resize event listener to the window element and call the
redraw function whenever the window dimensions change:

window.addEventListener('resize', function(event){
redraw();
});


The benefit of this solution is that we can do everything that we want in the
redraw function, for example, modifying the aspect ratio, adapting the labels of
the axis, or modifying the number of displayed elements.

The following figure shows a resized version of the previous chart; we observe
that this time, the axis ticks adapt nicely and don’t overlap anymore. Moreover,
the axis ticks now take the full available space:



Resized chart with adapted axis ticks


ADAPTING THE RESOLUTION OF THE DATA

However, there is another problem that can be nicely solved using these types of
manual redraws—the problem of data resolution. How much data should be displayed
in a small chart and how much in a bigger chart?



Small chart with high data resolution

I think you agree that in the preceding figure, we display too much data for the
size of the graphic. This is bad and makes the chart useless. Moreover, we
should really adapt the resolution of the data according to the small viewport
in the redrawing process.

Let’s implement a function that returns only ever i-th element of an array:

function adaptResolution(data, resolution) {
resolution = resolution ? Math.ceil(resolution) : 1;
return data.filter(function(d, i) {
return i % resolution === 0;
});
}


Great, let’s define a width depended data resolution and filter the data
accordingly:

var pixelsPerData = 20;
var resolution = pixelsPerData * (flatData.length) / width;


In the previous code, we observed that we can now define the minimum amount of
pixel that one data point should have and remove the amount of values
accordingly by calling the following:

var flatDataRes = adaptResolution(flatData, resolution);

The following image shows a small chart with a low number of values, which is
perfectly readable even though it is very small:



Small chart with a proper data resolution

In the next figure, we can see the same chart based on the same data drawn with
a bigger container. We immediately observe that also the data resolutions adapts
accordingly; and again, the chart looks nice:



Big chart with a proper data resolution


CONCLUSION OF USING RESIZE EVENTS

This is the most flexible solution, and therefore, in many situations, it is the
solution of choice. However, you need to be aware that there are also drawbacks
in using this solution:

 * There is no easy way to listen for resize events of the parent container
 * We need to add event listeners
 * We need to make sure that event listeners are removed properly
 * We need to manually redraw the chart


USING BOOTSTRAP’S MEDIA QUERIES

Bootstrap is an awesome library that gets you started quickly with new projects.
It not just includes a huge amount of useful HTML components but also normalized
amd standardized CSS styles. One particular style is the implementation of Media
Queries for four typical device types (five types in Bootstrap 4). In this
section, we will take a look at how to make use of these Media Queries in our
styles and scripts. The great thing about Bootstrap is that it successfully
standardizes typical device dimensions for web developers thus, beginners can
simply use them without rethinking over and over which pixel width could be the
most common one for tablets.


MEDIA QUERIES IN CSS

The quickest way to use Bootstrap’s Media Queries is to simply copy them from
the compiled source code. The queries are here:

/* Extra small devices (phones, etc. less than 768px) */
/* No media query since this is the default in Bootstrap */

/* Small devices (tablets, etc.) */
@media (min-width: 768px) { ... }

/* Medium devices (desktops, 992px and up) */
@media (min-width: 992px) { ... }

/* Large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) { ... }


We can easily add these queries to our CSS styles and define certain properties
and styles for our visualizations, such as four predefined widths, aspect
ratios, spacing, and so on in order to adapt the chart appearance to the device
type of the user.

Bootstrap 4 is currently in alpha; however, I think you can already start using
the predefined device types in your CSS. The reason I am strongly arguing for
Bootstrap 4 is because of its shift towards the em units instead of pixels:

// Extra small devices (portrait phones, etc.)
// No media query since this is the default in Bootstrap

// Small devices (landscape phones, etc.)
@media (min-width: 34em) { ... }

// Medium devices (tablets, etc.)
@media (min-width: 48em) { ... }

// Large devices (desktops, etc.)
@media (min-width: 62em) { ... }

// Extra large devices (large desktops, etc.)
@media (min-width: 75em) { ... }


Once again, the huge benefit of this is that the layout can adapt when the user
increases the font size of the browser, for example, to enhance readability.


MEDIA QUERIES IN LESS/SASS

In Bootstrap 3, you can include Media Query mixins to your LESS file, which then
gets compiled to plain CSS.

To use these mixins, you have to create a LESS file instead of CSS and import
the Bootstrap variables.less file. In this file, Bootstrap defines all its
dimensions, colors, and other variables. Let’s create a style.less file and
import variables.less:

// style.less
@import "bower_components/bootstrap/less/variables.less";


Perfect, that’s all. Now, we can go ahead and start using Bootstrap’s device
types in our LESS file.

/* Extra small devices (phones, etc. less than 768px) */
/* No media query since this is the default in Bootstrap */

/* Small devices (tablets, etc.) */
@media (min-width: @screen-sm-min) { ... }

/* Medium devices (desktops, etc.) */
@media (min-width: @screen-md-min) { ... }

/* Large devices (large desktops, etc.) */
@media (min-width: @screen-lg-min) { ... }


Finally, we need to use a LESS compiler to transform our style.less file to
plain CSS. To achieve this, we run the following command from the terminal:

lessc styles.less styles.css

As we can see, the command requires the LESS compiler called lessc being
installed. If it’s not yet installed on your system, go ahead and install it
using the following command:

npm install -g less

> If you are new to LESS, I recommend you to read through the LESS documentation
> on http://lesscss.org/. Once you check out of LESS, you can also look at the
> very similar SASS format, which is favored by Bootstrap 4. You can find the
> SASS documentation at http://sass-lang.com/.

We can use the Bootstrap 4 Media Queries in a SASS file by the following mixins:

@include media-breakpoint-up(xs) { ... }
@include media-breakpoint-up(sm) { ... }
@include media-breakpoint-up(md) { ... }
@include media-breakpoint-up(lg) { ... }
@include media-breakpoint-up(xl) { ... }


In my opinion, including Bootstrap’s LESS/SASS mixins to the styles of your
visualization is the cleanest solution because you always compile your CSS from
the latest Bootstrap source, and you don’t have to copy CSS into your project.


MEDIA QUERIES IN JAVASCRIPT

Another great possibility of using Bootstrap’s Media Queries to adapt your
visualization to the user’s device is to use them directly in JavaScript. The
native window.matchMedia (mediaQuery) function gives you the same control over
your JavaScript as Media Queries gives us over CSS.

Here is a little example on how to use it:

if (window.matchMedia("(min-width: 1200px)").matches) {
/* the viewport is at least 1200 pixels wide */
} else {
/* the viewport is less than 1200 pixels wide */
}


In the preceding code, we see that this function is quite easy to use and adds
almost infinite customization possibilities to our visualization.

> More information about the matchMedia function can be found on the Mozilla
> Website https://developer.mozilla.org/de/docs/Web/API/Window/matchMedia.

However, apart from using the watchMedia function directly, we could also use a
wrapper around the native API call. I can really recommend the enquire.js
library by Nick Williams, which allows you to declare event listeners for
viewport changes. It can be installed via the package manager bower by running
the following command from the terminal:

bower install enquire

Then, we need to add enquire.js to the website and use in the following snippet:

enquire.register("screen and (min-width:1200px)", {

// triggers when the media query matches.
match : function() {
/* the viewport is at least 1200 pixels wide */
},      

// optional; triggers when the media query transitions
unmatch : function() {
/* the viewport is less than 1200 pixels wide */
},    
});


In the preceding code, we see that we can now can add the match and unmatch
listeners almost in the same way as listening for resize events—just much more
flexible.

> More information about require.js can be found on the GitHub page of the
> project at https://github.com/WickyNilliams/enquire.js.

If we would like to use the Bootstrap device types, we could easily implement
them (as needed) with enquire.js and trigger events for each device type.
However, I prefer being very flexible and using the bare wrapper.


USING BOOTSTRAP’S GRID SYSTEM

Another great and quick way of making your charts responsive and play nicely
together with Bootstrap is to integrate them into Bootstrap’s gird system. It is
the best and cleanest integration however, is to separate concerns—and make the
visualization as general and adaptive as possible.

Let’s take our bar chart example with the custom resize events and integrate it
into a simple grid layout. As usual, you can find the full source code of the
example in the code examples:

<div class="container">
<div class="row">
<div class="col-md-8">
<div class="chart" data-url="…" …>
</div>
</div>
<div class="col-md-4">
<h2>My Dashboard</h2>
<p>This is a simple dashboard</p>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="chart" data-url="…" …>
</div>
</div>
<div class="col-md-4">
<div class="chart" data-url="…" …>
</div>
</div>
<div class="col-md-4">
<div class="chart" data-url="…" …>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="chart" data-url="…" …>
</div>
</div>
<div class="col-md-6">
<div class="chart" data-url="…" …>
</div>
</div>
</div>


We observe that by making use of the parent containers’ width, we can simply add
the charts as the div elements in the columns of the grid. This is the preferred
integration where two components play together nicely but are not depended on
each other.

In the following figure, we can see a screenshot from the simple dashboard that
we just built. We observe that the visualizations already fit nicely into our
grid layout, which makes it easy to compose them together:



A simple dashboard using Bootstrap’s grid layout


SUMMARY

In this article, you learned the essentials about absolute and relative units to
define lengths in a browser. We remember that the em and rem unit plays an
important role because it allows a layout to adapt when a user increases the
font size of the web site.

Then, you learned about how to use relative units and JavaScript resize events
to adapt the chart size and the data resolution according to the current
container size. We looked into Media Queries in CSS, LESS, und JavaScript.

Finally, we saw how to integrate charts with Bootstrap’s grid system and
implemented a simple Google Analytics-like dashboard with multiple charts.


Share

Facebook

Twitter

Linkedin

Packt





LEAVE A REPLY CANCEL REPLY

Please enter your comment!
Please enter your name here
You have entered an incorrect email address!
Please enter your email address here


Save my name, email, and website in this browser for the next time I comment.





Δ





MOBILEPRO

 * Past issues
 * Tutorials
 * News
 * Interviews
 * Podcasts


DATAPRO

 * Past issues
 * Tutorials
 * News
 * Interviews
 * Podcasts


PROGRAMMING

 * Application Development
 * Languages
 * Design patterns
 * High performance
 * Microservices


SUBSCRIBE TO OUR NEWSLETTER

Monthly digest of what's new and exciting from us.

JOIN
ApocryphTechnology news, insights and tutorials from Packt

© 2023 Company, Inc. All rights reserved.

Cookie Policy and Privacy Policy

Facebook
Instagram
Twitter