<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->


<html>
    <head>
        <meta charset="utf-8">
        <script src="lib/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/facePrint.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="lib/reset.css">
    </head>
    <body>
        <style>
            html {
                background: #eee;
            }
            #main-block {
                /* See https://github.com/ecomfe/echarts/issues/3233#issuecomment-220269663 */
                height: 1000px;
                padding: 0;
                top: 100px;
                left: 30px;
            }
            #buttons {
                z-index: 9999;
                position: fixed;
                right: 5px;
                bottom: 5px;
            }
            #above {
                border: 40px solid #aaa;
                height: 400px;
                margin: 10px;
                color: #aaa;
            }
        </style>

        <style>
        </style>
        <div id="buttons">
            <button id="switchAbove" onclick="addAbove();">Remove Above</botton>
            <button id="switchCSSPosition" onclick="switchCSSPosition();">To Fixed</botton>
        </div>
        <div id="above">Pinch grid, zoom should be normal.</div>
        <div id="main-block" style="position:relative"><div id="main" style="position:relative"></div></div>
        <script>

            function addAbove() {
                var aboveEl = document.getElementById('above');
                var btn = document.getElementById('switchAbove');

                if (aboveEl.style.display === 'none') {
                    aboveEl.style.display = 'block';
                    btn.innerHTML = 'Remove Above';
                }
                else {
                    aboveEl.style.display = 'none';
                    btn.innerHTML = 'Add Above';
                }
            }

            function switchCSSPosition() {
                var mainBlockEl = document.getElementById('main-block');
                var btn = document.getElementById('switchCSSPosition');

                if (mainBlockEl.style.position === 'fixed') {
                    mainBlockEl.style.position = 'relative';
                    mainBlockEl.style.top = '0';
                    btn.innerHTML = 'To Fixed';
                }
                else {
                    mainBlockEl.style.position = 'fixed';
                    mainBlockEl.style.top = '-400px';
                    btn.innerHTML = 'To relative';
                }
            }

            for (var i = 0; i < 1000; i++) {
                var d = document.createElement('div');
                d.innerHTML = i;
                document.body.appendChild(d);
            }

            var echarts;
            var chart;
            var myChart;

            require([
                'echarts'
            ], function (ec) {

                echarts = ec;

                chart = myChart = echarts.init(document.getElementById('main'), null, {

                });

// -------------------------------------------------------------------
// -------------------------------------------------------------------
// -------------------------------------------------------------------


option = {
  tooltip : {
            trigger: 'item'
        },
        toolbox: {
            show : true,
            feature : {
                mark : {show: true},
                dataView : {show: true, readOnly: false},
                magicType: {show: true, type: ['line', 'bar']},
                restore : {show: true},
                saveAsImage : {show: true}
            }
        },
        calculable : true,
        legend: {
            data:['Budget 2011', 'Budget 2012'],
            itemGap: 5
        },
        grid: {
            top: 500, // For touch test, make grid rect y more than 500.
            left: '1%',
            right: '10%',
            containLabel: true
        },
        xAxis: [
            {
                type : 'category',
                data : [1,2,3,4,5,6,7,8,9,10,11]
            }
        ],
        yAxis: [
            {
                type : 'value',
                name : 'Budget (million USD)',
                max: 300,
                axisLabel: {
                    formatter: function (a) {
                        return
                    }
                }
            }
        ],
        dataZoom: [
            {
                show: true,
                start: 20,
                end: 70,
                handleSize: 8
            },
            {
                type: 'inside',
                start: 20,
                end: 70
            },
        ],
        series : [
            {
                name: 'Budget 2011',
                type: 'bar',
                data: [34,65,11,44,55,32,76,91,3,21,98]
            },
            {
                name: 'Budget 2012',
                type: 'bar',
                data: [24,35,51,94,35,9,23,56,11,45,64]
            }
        ]
}

// -------------------------------------------------------------------
// -------------------------------------------------------------------
// -------------------------------------------------------------------



                chart.setOption(option);
            });

        </script>
    </body>
</html>