<!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">
        <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>
        <script src="lib/perlin.js"></script>
        <script src="lib/canteen.js"></script>
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>

        <div id="main0"></div>
        <div id="record"></div>

        <script>

        var recordContainer = document.getElementById('record');
        var chart;

        testHelper.controlFrame({
            pauseAt: 1,
            onFrame: function (frameNumber) {
                testHelper.printCanvasLayerDrawOperationsOnFrame(chart, frameNumber, recordContainer);
            }
        });


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

            const _ctx = {
                dataKind: '9x9',
                hoverLayerThreshold: 1,
                // hoverLayerThreshold: Infinity,
                progressive: 1,
            };

            function createOption() {
                var COUNT;
                var largeSettings1;
                var largeSettings2;

                if (_ctx.dataKind === '9x9') {
                    COUNT = 9;
                }
                else if (_ctx.dataKind === '30x30') {
                    COUNT = 30;
                }
                else if (_ctx.dataKind === '100x100') {
                    COUNT = 100;
                }
                else if (_ctx.dataKind === '200x200') {
                    COUNT = 200;
                }
                else if (_ctx.dataKind === '500x500') {
                    COUNT = 500;
                }
                largeSettings1 = {
                    progressive: _ctx.progressive,
                    progressiveThreshold: 1,
                };
                largeSettings2 = {
                    hoverLayerThreshold: _ctx.hoverLayerThreshold,
                };

                var xData = [];
                var yData = [];
                noise.seed(Math.random());

                function generateData(theta) {
                    var data = [];
                    var min = Infinity;
                    var max = -Infinity;
                    for (var i = 0; i <= COUNT; i++) {
                        for (var j = 0; j <= COUNT; j++) {
                            var val = noise.perlin2(i / 40, j / 20) + 0.5;
                            min = Math.min(min, val);
                            max = Math.max(max, val);
                            data.push([i, j, val]);
                        }
                        yData.push(i);
                        xData.push(i);
                    }
                    return {data, min, max};
                }

                var {data, min, max} = generateData(2);

                var option = {

                    ...largeSettings2,

                    tooltip: {},
                    grid: {
                        left: 150,
                    },
                    xAxis: {
                        type: 'category',
                        data: xData
                    },
                    yAxis: {
                        type: 'category',
                        data: yData
                    },
                    visualMap: {
                        // type: 'piecewise',
                        min: min,
                        max: max,
                        top: 10,
                        right: 0,
                        calculable: true,
                        splitNumber: 8,
                        inRange: {
                            color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
                        }
                    },
                    series: [{
                        name: 'Gaussian',
                        type: 'heatmap',
                        data: data,
                        // itemStyle: {
                        //     borderColor: 'red',
                        //     borderWidth: 2
                        // },
                        emphasis: {
                            itemStyle: {
                                borderColor: '#333',
                                borderWidth: 2
                            }
                        },
                        // silent: true,
                        ...largeSettings1,
                        animation: false
                    }]
                }
                return option;
            }

            function updateChart() {
                chart.setOption(createOption(), {notMerge: true});
            }

            chart = testHelper.create(echarts, 'main0', {
                title: [
                    'Click **Resume**',
                    '(NOTE: hoverLayerThreshold does not affect progressive rendering hovering)'
                ],
                option: createOption(),
                // recordCanvas: true
                height: 350,
                inputsStyle: 'compact',
                inputs: [{
                    type: 'select',
                    text: 'dataKind:',
                    values: [_ctx.dataKind, '30x30', '100x100', '200x200', '500x500'],
                    onchange() {
                        _ctx.dataKind = this.value;
                        updateChart();
                    }
                }, {
                    type: 'select',
                    text: 'hoverLayerThreshold:',
                    values: [_ctx.hoverLayerThreshold, Infinity, undefined],
                    onchange() {
                        _ctx.hoverLayerThreshold = this.value;
                        updateChart();
                    }
                }, {
                    type: 'select',
                    text: 'progressive:',
                    values: [_ctx.progressive, 300, 1000, 0],
                    onchange() {
                        _ctx.progressive = this.value;
                        updateChart();
                    }
                }]
            });



        });
        </script>


    </body>
</html>

