How to resize Morris.js chart on changes to container dimensions
Asked Answered
C

2

6

I try to put Morris js donut chart in the flex container with 2 flex items, I expect that chart in flex: 1 container will resize, but it does not. Does anyone know how to make the chart to be responsive in flex item?

Here is my example example try to resize it

JS:

$(function () {
    Morris.Donut({
        element: 'container',
        resize: true,
        data: [
            {label: "Download Sales", value: 12},
            {label: "In-Store Sales", value: 30},
            {label: "Mail-Order Sales", value: 20}
        ]
    });

CSS:

html, body {
height: 100%;
margin: 0;
}

body {
    display: -webkit-flex;
}

#container {
  flex: 1;
}

.flex1 {
  flex: 1;
  border: 1px solid red;
}
Crumhorn answered 17/2, 2016 at 23:49 Comment(0)
A
8

Add a $(window).on('resize', ...) event handler then call the graphs redraw() function.

If there is a dynamic UI element that causes the layout to "flex" based on user input, you will want to call redraw() there as well as there is no way to directly listen for the resizing of a div.

Here is your fiddle, updated with the fix.

jsFiddle

Also, here is a note from a developer of Morris.js

Note: I suggest you call redraw() sparingly as it's quite an expensive operation. Try using a setTimeout trick or similar to avoid calling it for intermediate resize events.

A way to heed this advice is below:

$(window).on('resize', function() {
   if (!window.recentResize) {
      window.m.redraw();
      window.recentResize = true;
      setTimeout(function(){ window.recentResize = false; }, 200);
   }
});

Here is a fiddle with this implemented:

jsFiddle

Angell answered 18/2, 2016 at 1:59 Comment(1)
Glad I could help! Also, as it looks like you are new to StackOverflow, I just wanted to remind that there is a grey checkmark to the left of answers. Clicking that will turn it green, and is the way to indicate that an answer has solved your problem. Selecting an answer gives both you and the person who answered reputation points :)Angell
P
1

My solution is to listen to resize events. If you have any resize event in the past second, you resize the chart. In this way you can't miss any window resize.

var haveToResizeCharts = false;

$(window).resize(function() {
    haveToResizeCharts = true;
});

setInterval(function(){ 
    if(haveToResizeCharts) {
        chart1.redraw();
        chart2.redraw();
        haveToResizeCharts = false;
    }
}, 1000);

The answer of thedarklord47 is partially wrong because if you already have an resize in the past 200 miliseconds, the final resize has no effect!

Preposition answered 3/5, 2018 at 12:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.