<!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/jquery.min.js"></script>
        <script src="lib/facePrint.js"></script>
        <script src="lib/testHelper.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="lib/reset.css">
    </head>
    <body>
        <style>
            h1 {
                line-height: 60px;
                height: 60px;
                background: #146402;
                text-align: center;
                font-weight: bold;
                color: #eee;
                font-size: 14px;
            }
            .chart {
                height: 500px;
            }
        </style>


        <h1>right y: min/max set, should not effect onZero of left y. (pick the first axis that can on zero)</h1>
        <div class="chart" id="a"></div>
        <h1>onZeroAxisIndex specified (onZero on the right y axis)</h1>
        <div class="chart" id="b"></div>




        <script>

            var echarts;
            var chart;
            var myChart;
            var groupCategories = [];
            var groupColors = [];

            require(['echarts'], function (ec) {
                echarts = ec;
                chart = myChart = echarts.init(document.getElementById('a'));

                option = {
                    legend: {
                        data: ['left', 'right']
                    },
                    xAxis : [
                        {
                            type : 'category',
                            data : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                        }
                    ],
                    yAxis : [
                        {
                            type : 'value'
                        },
                        {
                            type: 'value',
                            axisLabel: {
                                formatter: '{value} %'
                            },
                            min: 1,
                            max: 80
                        }
                    ],
                    series : [
                        {
                            name: 'left',
                            type: 'bar',
                            // barWidth: '60%',
                            data:[1000, -520, -2000, -3340, 3900, -330, -5220]
                        },
                        {
                            name: 'right',
                            type: 'line',
                            yAxisIndex: 1,
                            data: [10, 0, 30, 50]
                        }
                    ]
                };

                chart.setOption(option);
            });

        </script>














        <script>

            var echarts;
            var chart;
            var myChart;
            var groupCategories = [];
            var groupColors = [];

            require(['echarts'], function (ec) {
                echarts = ec;
                chart = myChart = echarts.init(document.getElementById('b'));

                option = {
                    legend: {
                        data: ['left', 'right']
                    },
                    xAxis : [
                        {
                            type : 'category',
                            axisLine: {
                                onZero: true,
                                onZeroAxisIndex: 1
                            },
                            data : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                        }
                    ],
                    yAxis : [
                        {
                            type : 'value'
                        },
                        {
                            type: 'value',
                            axisLabel: {
                                formatter: '{value} %'
                            }
                        }
                    ],
                    series : [
                        {
                            name: 'left',
                            type: 'line',
                            data:[1000, -520, -2000, -3340, 3900, -330, -5220]
                        },
                        {
                            name: 'right',
                            type: 'line',
                            yAxisIndex: 1,
                            data: [-10, 0, 30, 50]
                        }
                    ]
                };

                chart.setOption(option);
            });

        </script>






    </body>
</html>