<!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/esl.js"></script>
        <script src="lib/config.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="lib/reset.css">
    </head>
    <body>
        <style>
        </style>
        <div id="main"></div>
        <script>

            var chart;

            require([
                'echarts',
                // 'echarts/chart/line',
                // 'echarts/chart/bar',
                // 'echarts/chart/scatter',
                // 'echarts/component/legend',
                // 'echarts/component/grid',
                // 'echarts/component/geo',
                'map/js/china',
                // 'echarts/component/tooltip',
                // 'echarts/component/dataZoom',
                // 'echarts/component/markLine'
            ], function (echarts) {

                chart = echarts.init(document.getElementById('main'));

                var option = {
                    grid: {
                        top: '60%'
                    },
                    title : {
                        text: '动态数据',
                        subtext: '纯属虚构'
                    },
                    tooltip : {
                        trigger: 'axis'
                    },
                    legend: {
                        data:['最新成交价']
                    },
                    toolbox: {
                        show : true,
                        feature : {
                            dataView : {show: true, readOnly: false},
                            restore : {show: true},
                            saveAsImage : {show: true}
                        }
                    },
                    dataZoom : [{
                        type: 'inside',
                        start : 0,
                        end : 100
                    },
                    {
                        type: 'slider',
                        start : 0,
                        end : 100
                    }
                    ],
                    xAxis : [
                        {
                            type : 'value',
                            scale: true
                        }
                    ],
                    yAxis : [
                        {
                            type : 'value',
                            scale: true,
                            name : '预购量',
                            boundaryGap: [0.2, 0.2]
                        }
                    ],
                    geo: {
                        map: 'china',
                        height: '50%',
                        top: 0
                    },
                    series : [
                        {
                            type: 'scatter',
                            coordinateSystem: 'geo'
                        },
                        {
                            name:'最新成交价',
                            type:'line',
                            data:(function (){
                                var res = [];
                                var len = 0;
                                while (len < 10) {
                                    var n = [
                                        len,
                                        (Math.random()*10 + 5).toFixed(1)
                                    ];
                                    res.push({name: n[0], value: n});
                                    len++;
                                }
                                return res;
                            })(),
                            animation: true,
                            animationDurationUpdate: 500,
                            animationEasing: 'linear',
                            animationEasingUpdate: 'linear'
                        }
                    ]
                };

                chart.setOption(option);
            });

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