<!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">
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <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>
        <link rel="stylesheet" href="lib/reset.css">
    </head>
    <body>
        <style>
            .test-title {
                background: #146402;
                color: #fff;
            }
        </style>


        <div id="main0"></div>


        <script>

            var chart;

            require([
                'echarts'/*, 'map/js/china' */
            ], function (echarts) {

                var provinces = ['shanghai', 'hebei','shanxi','neimenggu','liaoning','jilin','heilongjiang','jiangsu','zhejiang','anhui','fujian','jiangxi','shandong','henan','hubei','hunan','guangdong','guangxi','hainan','sichuan','guizhou','yunnan','xizang','shanxi1','gansu','qinghai','ningxia','xinjiang', 'beijing', 'tianjin', 'chongqing', 'xianggang', 'aomen'];
                var provincesText = ['上海', '河北', '山西', '内蒙古', '辽宁', '吉林','黑龙江',  '江苏', '浙江', '安徽', '福建', '江西', '山东','河南', '湖北', '湖南', '广东', '广西', '海南', '四川', '贵州', '云南', '西藏', '陕西', '甘肃', '青海', '宁夏', '新疆', '北京', '天津', '重庆', '香港', '澳门'];

                function showProvince() {
                    var name = provinces[currentIdx];

                    chart.showLoading();

                    $.get('./data/map/json/province/' + name + '.json', function (geoJson) {

                        chart.hideLoading();

                        echarts.registerMap(name, geoJson);

                        chart.setOption({
                            backgroundColor: '#404a59',
                            title: {
                                text: provincesText[currentIdx],
                                left: 'center',
                                textStyle: {
                                    color: '#fff'
                                }
                            },
                            series: [
                                {
                                    type: 'map',
                                    mapType: name,
                                    label: {
                                        emphasis: {
                                            textStyle: {
                                                color: '#fff'
                                            }
                                        }
                                    },
                                    itemStyle: {
                                        normal: {
                                            borderColor: '#389BB7',
                                            areaColor: '#fff',
                                        },
                                        emphasis: {
                                            areaColor: '#389BB7',
                                            borderWidth: 0
                                        }
                                    },
                                    animation: false
                                    // animationDurationUpdate: 1000,
                                    // animationEasingUpdate: 'quinticInOut'
                                }
                            ]
                        });

                    });
                }

                var currentIdx = 0;

                var option = {
                    graphic: [{
                        id: 'left-btn',
                        type: 'circle',
                        shape: { r: 20 },
                        style: {
                            text: '<',
                            fill: '#eee'
                        },
                        left: 10,
                        top: 'middle',
                        onclick: function () {
                            currentIdx -= 1;
                            if (currentIdx < 0) {
                                currentIdx += provinces.length;
                            }
                            showProvince();
                        }
                    }, {
                        id: 'right-btn',
                        type: 'circle',
                        shape: { r: 20 },
                        style: {
                            text: '>',
                            fill: '#eee'
                        },
                        top: 'middle',
                        right: 10,
                        onclick: function () {
                            currentIdx = (currentIdx + 1) % provinces.length;
                            showProvince();
                        }
                    }],

                    series: []
                };

                chart = testHelper.create(echarts, 'main0', {
                    option: option
                });

                showProvince();

            });

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