1

So i'm trying to display 3 graphs in the same div, toggled by buttons which show/hide the other divs respectively. I've set the other 2 graphs to

style= "display: none"

To ensure only one graph is shown upon load. This is how the default view looks like:

enter image description here

The default view is the day on day button. However, when I click the other 2 buttons, the width of the graph screws up, and it displays like this.

enter image description here

It shrinks for some reason. I have switched the order of display, and it's always the hidden graphs which have the size problem. I suspect it has something to do with the inline style property, but I cant figure out how to make it show properly.

Code snippet for graph:

<button onclick="showDay('tasks')">Day on Day</button>
<button onclick="showWeek('tasks')">Week on Week</button>
<button onclick="showMonth('tasks')">Month on Month</button>
<div class="portlet-body">
    <div id="tasks"></div>
    <div id="tasksWeek" style="display: none"></div>
    <div id="tasksMonth" style="display: none"></div>
</div>

<script>
new Highcharts.StockChart({{masterDic['tasks']|safe}});
new Highcharts.StockChart({{masterDic['tasksWeek']|safe}});
new Highcharts.StockChart({{masterDic['tasksMonth']|safe}});
</script>

code snippet for calling (hackish right now)

<script>
    function showDay(id) {
        var idDay = "#"+id;
        var idWeek  = "#"+id+"Week";
        var idMonth = "#"+id + "Month";
        $(idWeek).hide(10);
        $(idMonth).hide(10);
        $(idDay).show(10);
    }
    function showWeek(id) {
        var idDay = "#"+id;
        var idWeek  = "#"+id+"Week";
        var idMonth = "#"+id + "Month";
        $(idMonth).hide(10);
        $(idDay).hide(10);
        $(idWeek).show(10);
    }
    function showMonth(id) {
        var idDay = "#"+id;
        var idWeek  = "#"+id+"Week";
        var idMonth = "#"+id + "Month";
        $(idDay).hide(10);
        $(idWeek).hide(10);
        $(idMonth).show(10);
    }
</script>

Anyone have any ideas on how to fix this? Thanks alot! :)

EDIT:

css for portlet body (entire trace when using inspect element):

https://jsfiddle.net/ovnrpnb5/

Wboy
  • 2,452
  • 2
  • 24
  • 45
  • Please provide the css for `portlet-body` and the three charts. – Eddi Jul 15 '16 at 08:40
  • Hey @Eddi, thanks for your reply! I can't really show you the css for the three charts because im generating them using pandas-highcharts library (so no css, apart from the default highcharts css with dark-unica theme) but i've updated the css for portlet body – Wboy Jul 15 '16 at 08:48
  • Oh, i totally skipped that part that you are using a canvas for the charts but it makes sense of of course. I can remind of a situation where there was a similiar problem with charts ( using another library). The problem occured when the chart container was initially hidden (using `display:none`), then the chart was created and after a while the container was shown again but the chart was misplaced. This was due to the initially hidden container of the chart, which was used to calculate the height/width and position of the chart. Maybe it's something similiar here. – Eddi Jul 15 '16 at 08:55
  • Ah that might be it, may I ask, how did you fix that problem? – Wboy Jul 15 '16 at 09:03
  • We fixed that problem by programmatically changing the window size ( and back again to the orgiginal size) because the chart had an event listener on that event. At this event the chart would re-calculate its height/width and position. I don't know HighchartJS but i guess there are some possibilties to redraw the chart. If yes, then try to call that after `show()` – Eddi Jul 15 '16 at 09:06
  • As an addition to Eddi comment, you can find here the topic that may be similar to your issue: http://stackoverflow.com/questions/17206631/why-are-bootstrap-tabs-displaying-tab-pane-divs-with-incorrect-widths-when-using – Grzegorz Blachliński Jul 15 '16 at 09:16
  • I usually use `$("#id").css("display", "none");` instead of the hide function for instant removal because it looks like by setting hide animation speed to 100, you want instantaneous transitioning of elements displayed on the page and this function does just that as opposed to the hide function. – btrballin Jul 15 '16 at 09:56
  • @GrzegorzBlachliński Hey, thanks alot for that link! :) it seems exactly like what I'm going through, but the solution (highest voted one) doesn't seem to work :( – Wboy Jul 15 '16 at 14:55

2 Answers2

0
setTimeout(function(){
    $(window).resize();
})

Call this after show()

beerwin
  • 9,813
  • 6
  • 42
  • 57
Abcd
  • 79
  • 1
  • 6
  • Hey, thanks for your reply! :) I called $(window).resize(); at the end of the show() but there wasn't any difference. I've put the code snippet in my answer for reference – Wboy Jul 15 '16 at 09:30
  • try increasing setTimeout time, it should trigger once chart is plotted – Abcd Jul 15 '16 at 09:52
  • Hello again, it still doesn't work. Am i doing this wrongly? Can you give me an example with my code snippet above? :) – Wboy Jul 15 '16 at 10:03
  • function showDay(id) { var idDay = "#"+id; var idWeek = "#"+id+"Week"; var idMonth = "#"+id + "Month"; $(idWeek).hide(10); $(idMonth).hide(10); $(idDay).show(10); setTimeout(function(){ $(window).resize(); },1000) } – Abcd Jul 15 '16 at 10:18
0

Figured it out if anyone's interested. Tldr: call reflow() on the chart after showing.

I was using hide() and show() instead of tabs as per @Grzegorz Blachliński's comment, so the solution given wasn't working.

I found this link which showed you how to access the element within your HTML http://ahumbleopinion.com/highcharts-tips-accessing-chart-object-from-container-id/

I was using the highcharts CDN, which apparently isnt 3.0.1, so the jquery method wasnt working. Hence, i made the following function and called it after every show()

// HACK TO GET IT TO DISPLAY PROPERLY
function callReflow(id){
    var index = $(id).data('highchartsChart');
    var chart = Highcharts.charts[index];
    chart.reflow();
}

Worked like a charm :)

Wboy
  • 2,452
  • 2
  • 24
  • 45