
<!--
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;
            }

            #snapshot {
                width: 150;
                height: 100;
                background: #fff;
                border: 5px solid rgba(0,0,0,0.5);
            }

        </style>

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

        <script>

            function ValueGenerator(baseValue) {
                this._baseValue = baseValue;
            }
            ValueGenerator.prototype.next = function () {
                var value = this._baseValue += Math.random() * 20 - 10;
                return Math.max(0, Math.round(value) + 3000);
            }

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

                var count = 5e5;
                // var count = 1e6;

                var xAxisData = [];
                var data1 = [];
                var data2 = [];
                var generator1 = new ValueGenerator(Math.random() * 1000);
                // var generator2 = new ValueGenerator(Math.random() * 5000);

                for (var i = 0; i < count; i++) {
                    xAxisData.push('category' + i);
                    data1.push(generator1.next().toFixed(2));
                    // data2.push(generator2.next().toFixed(2));
                }

                var option = {
                    title: {
                        text: echarts.format.addCommas(count) + ' Bars',
                        left: 10
                    },
                    legend: {
                        data: ['bar', 'bar2', 'bar3', 'bar4'],
                        align: 'left'
                    },
                    toolbox: {
                        // y: 'bottom',
                        feature: {
                            magicType: {
                                type: ['line', 'bar', 'stack', 'tiled']
                            },
                            dataZoom: {
                                yAxisIndex: false
                            },
                            dataView: {},
                            saveAsImage: {
                                pixelRatio: 2
                            }
                        }
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'shadow'
                        }
                    },
                    dataZoom: [{
                        type: 'inside'
                    }, {
                        type: 'slider'
                    }],
                    xAxis: {
                        data: xAxisData,
                        silent: false,
                        splitLine: {
                            show: false
                        },
                        splitArea: {
                            show: false
                        }
                    },
                    yAxis: {
                        splitArea: {
                            show: false
                        }
                    },
                    series: [{
                        name: 'bar',
                        type: 'bar',
                        // stack: 'one',
                        data: data1,
                        itemStyle: {
                            color: 'green'
                            // borderColor: 'yellow'
                        },
                        large: true
                        // progressiveChunkMode: 'sequential'
                    // }, {
                    //     show: false,
                    //     name: 'bar2',
                    //     type: 'bar',
                    //     stack: 'one',
                    //     data: data[1]
                    }]
                };

                var chart = testHelper.create(echarts, 'main0', {
                    title: [
                        '(1) Check legend click',
                        '(2) Check `progressiveChunkMode: "mod"` render correct',
                        '(3) Check snapshot rendering when "finished"'
                    ],
                    option: option
                });

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

            });
        </script>
    </body>
</html>