
<!--
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/frameInsight.js"></script>
        <script src="lib/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
        <script src="lib/testHelper.js"></script>
        <script src="lib/facePrint.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
            }

            #snapshot {
                position: fixed;
                right: 10;
                top: 10;
                width: 200;
                height: 200;
                background: #fff;
                border: 5px solid rgba(0,0,0,0.5);
            }

        </style>


        <div id="main"></div>
        <div id="duration"></div>
        <img id="snapshot"/>

        <script>

            var chunkMax = 4;
            var chunkCount = 0;

            function genData1(len, offset) {
                var lngRange = [-10.781327, 131.48];
                var latRange = [18.252847, 52.33];

                var arr = new Float32Array(len * 2);
                var off = 0;

                for (var i = 0; i < len; i++) {
                    var x = +Math.random() * 10;
                    var y = +Math.sin(x) - x * (len % 2 ? 0.1 : -0.1) * Math.random() + (offset || 0) / 10;
                    arr[off++] = x;
                    arr[off++] = y;
                }
                return arr;
            }

            function genData2(count) {
                var lngRange = [-10.781327, 31.48];
                var latRange = [-18.252847, 30.33];
                return genData(count, lngRange, latRange);
            }

            function genData(count, lngRange, latRange) {
                lngRange[1] += 5;
                lngRange[0] -= 10;
                latRange[1] += 4;
                var lngExtent = lngRange[1] - lngRange[0];
                var latExtent = latRange[1] - latRange[0];
                var data = [];
                for (var i = 0; i < count; i++) {
                    data.push([
                        Math.random() * lngExtent + lngRange[0],
                        Math.random() * latExtent + latRange[0],
                        Math.random() * 1000
                    ]);
                }
                return data;
            }

            var series0Data = genData1(5e5);

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

                frameInsight.init(echarts, 'duration');

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

                chart.setOption({
                    tooltip: {},
                    toolbox: {
                        left: 'center',
                        feature: {
                            dataZoom: {}
                        }
                    },
                    legend: {
                        orient: 'vertical',
                        left: 'left',
                        data: ['pm2.5' /* ,'pm10' */]
                    },
                    // ???
                    // visualMap: {
                    //     min: 0,
                    //     max: 1500,
                    //     left: 'left',
                    //     top: 'bottom',
                    //     text: ['High','Low'],
                    //     seriesIndex: [1, 2, 3],
                    //     inRange: {
                    //         color: ['#006edd', '#e0ffff']
                    //     },
                    //     calculable : true
                    // },
                    xAxis: [{
                    }],
                    yAxis: [{
                    }],
                    dataZoom: [{
                        type: 'inside'
                    }, {
                        type: 'slider',
                        showDataShadow: false
                    }],
                    animation: false,
                    series : [{
                        name: 'pm2.5',
                        type: 'scatter',
                        data: series0Data,
                        dimensions: ['x', 'y'],
                        // symbol: 'rect',
                        symbolSize: 3,
                        // symbol: 'rect',
                        itemStyle: {
                            color: '#128de3',
                            opacity: 0.4
                        },
                        large: true,
                        // large: {
                        //     symbolSize: 2
                        // },
                        // large: function (params) {
                        //     if (params.dataCount > 30000) {
                        //         return {symbolSize: 1};
                        //     }
                        //     else if (params.dataCount > 3000) {
                        //         return {symbolSize: 5};
                        //     }
                        // },
                        largeThreshold: 500,
                        progressive: 500
                        // progressive: false
                    // }, {
                    //     name: 'pm10',
                    //     type: 'scatter',
                    //     data: genData2(2001),
                    //     xAxisIndex: 0,
                    //     yAxisIndex: 0,
                    //     symbolSize: 2,
                    //     // symbol: 'rect',
                    //     itemStyle: {
                    //         normal: {
                    //             borderWidth: 0.5,
                    //             borderColor: '#e01',
                    //             color: '#128de3'
                    //         }
                    //     },
                    //     progressive: 3000
                    }]
                });

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

                chart.on('finished', function () {
                    var url = chart.getDataURL();
                    var snapshotEl = document.getElementById('snapshot');
                    snapshotEl.src = url;
                });

                window.onresize = chart.resize;

                // next();

                function next() {
                    if (chunkCount++ < chunkMax) {
                        var newData = genData1(100000, chunkCount);
                        chart.appendData({seriesIndex: 0, data: newData});
                        // console.log('Data loaded');
                        setTimeout(next, 3000);
                    }
                }

            });


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