
<!--
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>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
            }
        </style>
        <div id="main"></div>
        <script>

            var lngRange = [79.781327, 131.48];
            var lngExtent = lngRange[1] - lngRange[0];
            var latRange = [18.252847, 52.33];
            var latExtent = latRange[1] - latRange[0];

            var data = [];
            // var count = 1000000;
            // var count = 450000;
            var count = 1000000;
            // var count = 5000;

            for (var i = 0; i < count; i++) {
                data.push([
                    Math.random() * lngExtent + lngRange[0],
                    Math.random() * latExtent + latRange[0],
                    Math.random() * 1000
                ]);
            }

            require([
                'echarts'
                // 'echarts/chart/map',
                // 'echarts/chart/scatter',
                // 'echarts/component/title',
                // 'echarts/component/legend',
                // 'echarts/component/geo',
                // 'echarts/component/visualMap',
                // 'echarts/component/markPoint',
                // 'echarts/component/tooltip'
            ], function (echarts) {

                require(['map/js/china'], function () {
                    var chart = echarts.init(document.getElementById('main'));

                    chart.setOption({
                        tooltip: {},
                        legend: {
                            orient: 'vertical',
                            left: 'left',
                            data:['categoryA','categoryB','categoryC']
                        },
                        // visualMap: {
                        //     min: 0,
                        //     max: 1500,
                        //     left: 'left',
                        //     top: 'bottom',
                        //     text: ['High','Low'],
                        //     seriesIndex: [1, 2, 3],
                        //     inRange: {
                        //         color: ['#006edd', '#e0ffff']
                        //     },
                        //     calculable : true
                        // },
                        geo: {
                            map: 'china',
                            roam: true,
                            label: {
                                normal: {
                                    show: true,
                                    textStyle: {
                                        color: 'rgba(0,0,0,0.4)'
                                    }
                                }
                            },
                            itemStyle: {
                                normal:{
                                    borderColor: 'rgba(0, 0, 0, 0.2)'
                                },
                                emphasis:{
                                    color: null,
                                    areaColor: null,
                                    shadowOffsetX: 0,
                                    shadowOffsetY: 0,
                                    shadowBlur: 20,
                                    borderWidth: 0,
                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                                }
                            }
                        },
                        series : [{
                            name: 'pm2.5',
                            type: 'scatter',
                            stream: true,
                            coordinateSystem: 'geo',
                            data: data,
                            symbolSize: 4,
                            // symbol: 'rect',
                            itemStyle: {
                                normal: {
                                    // color: '#ddb926'
                                    color: '#dda'
                                }
                            },
                            progressive: 100
                        }]
                    });

                    chart.on('click', function (param) {
                        alert('asdf');
                    });
                });
            });

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