gvnhvw
Last Updated: January 21, 2017
·
35.64K
· b3rgstrom
Image

Responsive Morris.js graphs in Bootstrap 3 tabs

Morris.js is a javascript graph library based on the very competent raphael.js, I’ve come to include them in many projects lately because they are really dead simple to implement and they now, in the master branch, support the ability to natively resize with the page, in other words they are responsive, which is largely in demand right now.

Now can they be implemented in content that switches between display: block; and display: none; like bootstrap's tabs?

I’ve been working on a prototype for one of my clients who has the need to display data to their users in graphical form. It is easier to digest data in graphical form, easier to spot anomalies etc etc…

One setback with using graphical elements is that they tend to take up a lot of space. Which makes other content less visible, and in data heavy user interfaces, screen real estate is worth a lot in many senses. Thus, developers struggle with the traditional issue of letting users have the cake and eat it at the same time.

Solution -> Tabs. Great stuff, the space issue is resolved, but through implementing tabs we’ve spawned another problem:

Problem -> The tabbed content has the selector attribute display: none;

And why is this a problem? Graphs are generally drawn on document ready, which means the page loads, all elements are in place(except for our background tab) and the javascript starts drawing graphs on the elements it can see, hence our hidden tab will have nothing in it when its clicked.

Example:

http://jsfiddle.net/rbsthlm/cD6dd/2/

Now there is a solution to this, we can use the function redraw() that comes with morris, and we’ll jack it up to the bootstrap event that determines the tab is active, shown.bs.tab. So when the bootstrap tab is shown, we draw some graphs.

We will give each tab the HTML5 data-identifiers of the graphs that are present within them in the HTML. In the javascript we will determine on which tab we are, and take these identifiers and execute the redraw() function on them, this is so we don’t try to redraw graphs that are not suppose to be shown at that time, economy economy…

The complete working solution can be found here:

http://jsfiddle.net/rbsthlm/cD6dd/12/

So there you have it, pretty pretty morris graphs in bootstrap tabs. I’ll include all the code snippets at the end here if you’d rather read it here than on jsFiddle.

Additional resources needed:

  • bootstrap 3 css & js
  • fontawesome
  • jquery

Full source code can be found here:
<a href="http://blog.b3rgstrom.se/post/68081765878/morris-js-charts-in-bootstrap-tabs">Responsive Morris.js graphs in Bootstrap 3 tabs</a>

Enjoy

Say Thanks
Respond

6 Responses
Add your response

12169
Upload normal

Thank you...

Thank you, thank you, thank you, thank you, thank you!

Was really struggling with this.

over 1 year ago ·
12170
Image

I'm glad to hear it was useful to you. Usually when I find solutions like this I imagine that someone else have had or runs in to the same problem eventually... And here we are :) Do you have it implemented somewhere where I can see it in action? :)

over 1 year ago ·
14990
3fa70e061aa8d2638192ce92c1fc6a7c

Solutions show 404 :(

over 1 year ago ·
15064
Image

@brettalton, I'm so sorry, the links were outdated but should be working now :)

over 1 year ago ·
19291
Hgy11yvj normal

please update the scripts
Morris: http://cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js
Raphael: http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js

By the way Thanks a lot for the article it helped me a lot.

over 1 year ago ·
24800
Ruben01 normal

Hi, perhaps a really stupid question, but how do I draw a multiple graph and only display selected values on the y-axis. I have a simple two line graph that spans over 5 years, with a data point for every quarter of every year, but I only want the y-axis to display every year (every 4th data point)? Ideally I would like to retain the hover values for each data point.

over 1 year ago ·