0

I have a webpage with a left side menu and a canvas chart.

The left side menu takes up the first 155 pixels of the width.

The chart is then set to a width of 100% (100 % of what is left after the left menu have occupied the first 155 pixels)

The problem is that when I close the left menu, the chart is not refreshed, and now it does not take up 100% of the available window width, I can only get it to refresh when resizing the window manually with the mouse.

I use the following code:-

<html>
<title>Test1</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

<body>
    <div class="w3-sidebar w3-light-grey w3-card-4 w3-animate-left" style="width:155px; line-height:16px;" id="mySidebar">
        <div class="w3-bar w3-dark-grey">
            <span class="w3-bar-item w3-padding-16">Menu</span>
            <button onclick="w3_close_left_menu()" class="w3-bar-item w3-button w3-right w3-padding-16" title="close Sidebar">&times;</button>
        </div>
        <div class="w3-bar-block">
            <a class="w3-bar-item w3-button w3-border-bottom" href="regn.html">Test</a>
        </div>
    </div>
    <div id="main" style="margin-left:155px">
        <div class="w3-container w3-display-container">
            <span title="open Sidebar" style="display:none" id="openNav" class="w3-button w3-transparent w3-display-topleft w3-xlarge" onclick="w3_open_left_menu()">&#9776;</span>
        </div>
        <div style="padding-top:20px; padding-left:40px; width:100%;">
            DivFirst
        </div>
        <div style="padding-top:5px; padding-left:10px; padding-bottom:10px; width:98%; background-color: #11ffcc;">
            DivSecond
            <script type="text/javascript">
            window.onload = function() {;
                var chart0 = new CanvasJS.Chart("chartContainer0", {
                    legend: {
                        fontSize: 4
                    },
                    zoomEnabled: true,
                    toolTip: {
                        content: "{y} grader <br>{x}",
                        shared: false
                    },
                    axisX: {
                        gridColor: "Black",
                        gridThickness: 1,
                        interval: 1,
                        intervalType: "day",
                        interlacedColor: "#FCFCFF",
                        valueFormatString: "HH:mm - DD MMM",
                        labelFontSize: 14,
                        labelFontColor: "black"
                    },
                    theme: "theme1",
                    axisY: {
                        includeZero: false,
                        labelFontSize: 14,
                        labelFontColor: "black"
                    },
                    data: [{
                        type: "line",
                        lineThickness: 2,
                        showInLegend: true,
                        markerType: "square",
                        color: "#F08080",
                        xValueFormatString: "HH:mm - DD MMM YYYY",
                        legendText: "Inde temp",
                        dataPoints: [{
                            x: new Date(2017, 10, 3, 6, 30),
                            y: 22.15
                        }, {
                            x: new Date(2017, 10, 3, 7, 00),
                            y: 22.10
                        }, {
                            x: new Date(2017, 10, 3, 7, 30),
                            y: 21.89
                        }, ]
                    }, ],
                    legend: {
                        cursor: "pointer"
                    }
                });
                chart0.render();
            }
            </script>
            <script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
            <div id="chartContainer0" style="height: 400px; width: 99%;"></div>
        </div>
    </div>
    <script>
    function w3_open_left_menu() {
        document.getElementById("main").style.marginLeft = "155px";
        document.getElementById("mySidebar").style.width = "155px";
        document.getElementById("mySidebar").style.display = "block";
        document.getElementById("openNav").style.display = 'none';
    }

    function w3_close_left_menu() {
        document.getElementById("main").style.marginLeft = "0";
        document.getElementById("mySidebar").style.display = "none";
        document.getElementById("openNav").style.display = "inline-block";

        document.getElementById("chartContainer0").reload(false);
    }
    </script>
</body>

</html>

In the function 'w3_close_left_menu' I have tried to add the line:-

 document.getElementById("chartContainer0").reload(false);

But that does not force the canvas to be refreshed

halfer
  • 19,824
  • 17
  • 99
  • 186
kfj
  • 3
  • 3
  • 1
    You need to call `resize` event on element where is your chart created and create it again. – Aleksa Arsić Nov 04 '17 at 06:58
  • Hmm, how do I do that? – kfj Nov 04 '17 at 07:09
  • ES5: ``var chartElem = document.getElementByID('chartContainer0'); chartElem.addEventListener('resize', function() { chart.render() });`` ES6: ``let chartElem = document.getElementByID('chartContainer0'); chartElem.addEventListener('resize', () => chart.render());`` – Aleksa Arsić Nov 04 '17 at 07:15
  • Possible duplicate of [Get Canvas to dynamically resize when browser window is resized](https://stackoverflow.com/questions/32119012/get-canvas-to-dynamically-resize-when-browser-window-is-resized) – jonny Nov 04 '17 at 07:23
  • Sorry for being a dummy here :-) What is this ES5 and ES6, do you mean you can either do it with the code in ES5 or the code in ES6. I tried the code below, but it doesn't work, maybe I misunderstood something: function w3_close_left_menu() { document.getElementById("main").style.marginLeft = "0"; document.getElementById("mySidebar").style.display = "none"; document.getElementById("openNav").style.display = "inline-block"; var chartElem = document.getElementByID('chartContainer0'); chartElem.addEventListener('resize', function() { chart.render() }); chartElem.resize(); } – kfj Nov 04 '17 at 07:26
  • Jonathan indicated that this was a duplicate of another question, I tried to read the other thread, but I don't see how the solutions in there can solve my problem, and I still haven't found a working solution to my problem – kfj Nov 04 '17 at 11:28
  • I looked some more at the code, and found out what you mean by ES5 and ES6. I guess that I shouldn't call resize myself, since the eventhandler you created will be called when the left menu is closed and the div is resized. But where do I add these two lines of code, in the w3_close_left_menu function or in the code block where chartContainer0 is created and populated, I tried both, but couldn't get any of them to work – kfj Nov 04 '17 at 13:30

1 Answers1

1

Without testing the code, I'm almost sure that what you need is to trigger render() manually on your chart after you close the menu in your w3_close_left_menu().

Resize events on DOM elements are not widely implemented, although there are libraries that add cross-browser support for that.

Here's your handler:

var menuButton = document.getElementById("openNav");
menuButton.addEventListener('click', function () {
    document.getElementById("main").style.marginLeft = "155px";
    document.getElementById("mySidebar").style.width = "155px";
    document.getElementById("mySidebar").style.display = "block";
    document.getElementById("openNav").style.display = 'none';
    chart0.render();
}, true);

Note that in your example, the w3.css will attach transitions to closing and opening the menu. In that case you need to listen to transitionend / animationend on the animating element.

Sami Hult
  • 3,052
  • 1
  • 12
  • 17
  • But how do I trigger the chart.render() from the w3_close_left_menu function, since I guess the chart is out of scope in this function? – kfj Nov 05 '17 at 09:02
  • Just put your `w3_close_left_menu` and `w3_close_left_menu` inside `window.onload` handler, where you define `chart`. You can then assign them to handle click events for the menu open/close buttons in script. In many ways that is anyways a better way than defining the functions in a script block, because they pollute the global (window) namespace. – Sami Hult Nov 05 '17 at 09:05
  • Thanks, sounds reasonable, but unfurtunately I can't get it to work, I have added an answer to this thread instead of a comment, so I can show the new code more detailed than in comments – kfj Nov 05 '17 at 15:14
  • Thanks a lot for your help, now it works. I made a quick and dirty solution for the last problem, I just waited 200 milliseconds before calling chart0.render() Maybe not a pretty solution, but it works and get the job done, without redesigning everything from scratch – kfj Nov 06 '17 at 19:05