
<!--
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">
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="lib/esl.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>
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
            .chart {
                height: 400px;
            }
        </style>

        <div id="chart-1" class="chart"></div>
        <div id="main1"></div>


        <script>

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

                var chart = echarts.init(document.getElementById('chart-1'));

                var xCnt = 500;
                var data = [];
                var xAxis = [];
                for (var i = 0; i < xCnt; ++i) {
                    data.push(
                        Math.round(Math.random() * 100 * i) / 100
                            * (Math.random() < 0.6 ? 1 : -1)
                    );
                    xAxis.push((i + 1) + '');
                }

                chart.setOption({
                    dataZoom: [{
                        type: 'inside',
                        startValue: '20',
                        endValue: '50'
                    }, {
                        type: 'slider',
                        startValue: '20',
                        endValue: '50'
                    }],
                    toolbox: {
                        show: true,
                        feature: {
                            dataZoom: {
                                show: true
                            },
                            restore: {
                                show: true
                            }
                        }
                    },
                    tooltip: {
                        show: true
                    },
                    xAxis: {
                        data: xAxis
                    },
                    yAxis: {
                        min: function (value) {
                            return value.min - 20;
                        },
                        max: function (value) {
                            return value.max + 20;
                        }
                    },
                    series: [{
                        type: 'bar',
                        data: data,
                        markPoint: {
                            symbol: 'pin',
                            label: {
                                normal: {
                                    show: true
                                }
                            },
                            itemStyle: {
                                normal: {
                                    color: 'green'
                                }
                            },
                            data: [{
                                name: 'max',
                                type: 'max'
                            }, {
                                name: 'min',
                                type: 'min'
                            }]
                        }
                    }]
                });
            });
        </script>




        <script>

            require([
                'echarts'
            ], function (echarts) {
                function xAxisData() { return ['a', 'b', 'c']; };
                function seriesData() { return [12, 32, 44]; };
                var gridWidth = 100;
                var gridBottom = 80;
                var gridGap = 50;
                var gridCurrLeft = gridGap;
                var nameTextStyle = {align: 'left'};

                function getGridLeft() {
                    var left = gridCurrLeft;
                    gridCurrLeft += gridWidth + gridGap;
                    return left;
                }

                var option = {
                    dataZoom: [
                        {type: 'inside', yAxisIndex: 1},
                        {type: 'inside', yAxisIndex: 3}
                    ],
                    grid: [
                        {width: gridWidth, bottom: gridBottom, left: getGridLeft()},
                        {width: gridWidth, bottom: gridBottom, left: getGridLeft()},
                        {width: gridWidth, bottom: gridBottom, left: getGridLeft()},
                        {width: gridWidth, bottom: gridBottom, left: getGridLeft()}
                    ],
                    xAxis: [
                        {gridIndex: 0, data: xAxisData()},
                        {gridIndex: 1, data: xAxisData()},
                        {gridIndex: 2, data: xAxisData()},
                        {gridIndex: 3, data: xAxisData()}
                    ],
                    yAxis: [{
                        gridIndex: 0,
                        name: 'y min/max:\nfunction return null\nno dataZoom',
                        nameTextStyle: nameTextStyle,
                        min: function (param) {
                            return null;
                        },
                        max: function (param) {
                            return null;
                        }
                    }, {
                        gridIndex: 1,
                        name: 'y min/max:\nfunction return null\ny inside dataZoom',
                        nameTextStyle: nameTextStyle,
                        min: function (param) {
                            return null;
                        },
                        max: function (param) {
                            return null;
                        }
                    }, {
                        gridIndex: 2,
                        name: 'y min/max:\nnull\nno dataZoom',
                        nameTextStyle: nameTextStyle,
                        min: null,
                        max: null
                    }, {
                        gridIndex: 3,
                        name: 'y min/max:\nnull\ny inside dataZoom',
                        nameTextStyle: nameTextStyle,
                        min: null,
                        max: null
                    }],
                    series: [
                        {type: 'scatter', data: seriesData(), xAxisIndex: 0, yAxisIndex: 0},
                        {type: 'scatter', data: seriesData(), xAxisIndex: 1, yAxisIndex: 1},
                        {type: 'scatter', data: seriesData(), xAxisIndex: 2, yAxisIndex: 2},
                        {type: 'scatter', data: seriesData(), xAxisIndex: 3, yAxisIndex: 3},
                    ]
                };

                var chart = testHelper.create(echarts, 'main1', {
                    title: [
                        'Y range should be all the same',
                        'dataZoom should be normal'
                    ],
                    option: option
                });

            });

        </script>



    </body>
</html>