
<!--
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='http://api.map.baidu.com/api?v=2.0&ak=KOmVjPVUAey1G2E8zNhPiuQ6QiEmAwZu'></script>
        <meta name='viewport' content='width=device-width, initial-scale=1' />
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
            }
        </style>
        <div id='main'></div>
        <script>

            require([
                'echarts',
                './data/map/json/china.json'
            ], function (echarts, chinaJson) {
                echarts.registerMap('china', chinaJson);

                var myChart = echarts.init(document.getElementById('main'));

                var planePath = 'path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z';

                var option = {

                    geo: {
                        map: 'china',
                        roam: true
                    },

                    legend: {
                        show: true,
                        data: ['a', 'b']
                    },

                    series: [{
                        name: 'a',
                        type: 'lines',
                        coordinateSystem: 'geo',
                        polyline: true,
                        effect: {
                            show: true,
                            period: 8,
                            color: '#4433aa',
                            symbolSize: 20,
                            symbol: planePath
                        },
                        zlevel: 1,
                        lineStyle: {
                            normal: {
                                width: 4,
                                opacity: 0.2
                            }
                        },
                        data: [{
                            coords: [
                                [100.5107, 23.2196],
                                [120.5107, 23.2196]
                            ],
                            lineStyle: {
                                normal: {
                                    curveness: 0.2
                                }
                            }
                        }, {
                            coords: [
                                [100.5107, 30.2196],
                                [100.5107, 32.2196],
                                [110.5107, 34.2196],
                                [112.5107, 38.2196],
                                [104.5107, 30.2196],
                                [100.5107, 30.2196]
                            ]
                        }]
                    },
                    {
                        name: 'b',
                        type: 'lines',
                        coordinateSystem: 'geo',
                        effect: {
                            show: true,
                            period: 4,
                            color: '#4433aa',
                            symbolSize: 20,
                            symbol: planePath
                        },
                        zlevel: 1,
                        data: [{
                            coords: [
                                [100.5107, 23.2196],
                                [120.5107, 23.2196]
                            ],
                            lineStyle: {
                                normal: {
                                    curveness: 0.2,
                                    width: 4,
                                    opacity: 0.4
                                }
                            }
                        }]
                    }]
                }

                myChart.setOption(option);

            });

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