
<!--
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/testHelper.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
            .test-title[title=null] {
                display: none;
            }
        </style>
        <div id="main0"></div>
        <div id="main1"></div>
        <script>

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

                var options = [{
                    title: {
                        text: 'x: default; y: default'
                    },
                    xAxis: {
                        data: ['a', 'b', 'c', 'd', 'e']
                    },
                    yAxis: {
                    },
                    series: [{
                        type: 'line',
                        data: [2, 3, 5, 1, 6]
                    }]
                }, {
                    title: {
                        text: 'x: ["none", "arrow"] symbolOffset: 10; y: "arrow" of size 30x20 symbolOffset: [-10, 10]'
                    },
                    xAxis: {
                        data: ['a', 'b', 'c', 'd', 'e'],
                        axisLine: {
                            symbol: ['none', 'arrow'],
                            lineStyle: {
                                color: 'green'
                            },
                            symbolOffset: 10
                        }
                    },
                    yAxis: {
                        axisLine: {
                            show: true,
                            symbol: 'arrow',
                            symbolSize: [30, 20],
                            symbolOffset: [-10, 10]
                        }
                    },
                    series: [{
                        type: 'line',
                        data: [2, 3, 5, 1, 6]
                    }]
                }, {
                    title: {
                        text: 'x: "none"; y: ["none", "arrow"] symbolOffset: [10, -10] inversed '
                    },
                    xAxis: {
                        data: ['a', 'b', 'c', 'd', 'e'],
                        axisLine: {
                            symbol: 'none'
                        }
                    },
                    yAxis: {
                        axisLine: {
                            show: true,
                            symbol: ['none', 'arrow'],
                            symbolOffset: [10, -10]
                        },
                        inverse: true
                    },
                    series: [{
                        type: 'line',
                        data: [2, 3, 5, 1, 6]
                    }]
                }];

                var main = document.getElementById('main0');
                for (var i = 0; i < options.length; ++i) {
                    var container = document.createElement('div');
                    main.appendChild(container);

                    testHelper.create(echarts, container, {
                        option: options[i]
                    });
                }

            });

        </script>

        <script>
            require(['echarts'], function (echarts) {
                var option = {
                    dataset: {
                        source: [
                            ['水果', '价格'],
                            ['苹果', 1],
                            ['香蕉', 0.5],
                            ['梨', 2],
                            ['菠萝', 4]
                        ]
                    },
                    xAxis: [{
                        type: 'category',
                        inverse: true,
                        axisLine: {
                            symbol: 'arrow'
                        }
                    }],
                    yAxis: {
                        inverse: true,
                        axisLine: {
                            show: true,
                            symbol: 'arrow'
                        }
                    },
                    series: [{
                        type: 'bar'
                    }]
                };

                var chart = testHelper.create(echarts, 'main1', {
                    title: [
                        'The arrows of axis line should be inverted when the axis is inverse',
                        'Case from https://github.com/apache/echarts/issues/17325'
                    ],
                    option: option
                });
            })
        </script>
    </body>
</html>
