
<!--
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>
        <script src="lib/perlin.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
            }
        </style>
        <div id="main"></div>
        <script>

            require([
                'echarts'
                // 'echarts/chart/heatmap',
                // 'echarts/chart/scatter',
                // 'echarts/component/legend',
                // 'echarts/component/visualMap',
                // 'echarts/component/grid',
                // 'echarts/component/polar',
                // 'echarts/component/tooltip'
            ], function (echarts) {

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

                // function normalDist(theta, x) {
                //     return 1 / (theta * Math.sqrt(2 * Math.PI)) * Math.exp(- x * x / 2 / theta / theta);
                // }

                var xData = [];
                var yData = [];
                noise.seed(Math.random());
                function generateData(theta, min, max) {
                    var data = [];
                    for (var i = 0; i <= 300; i++) {
                        for (var j = 0; j <= 300; j++) {
                            // var x = (max - min) * i / 200 + min;
                            // var y = (max - min) * j / 100 + min;
                            data.push([i, j, noise.perlin2(i / 40, j / 20) + 0.5]);
                            // data.push([i, j, normalDist(theta, x) * normalDist(theta, y)]);
                        }
                        yData.push(i);
                        xData.push(i);
                    }
                    return data;
                }
                var data = generateData(2, -5, 5);

                // console.profile('render');
                console.time('render');
                chart.setOption({
                    tooltip: {},
                    xAxis: {
                        type: 'category',
                        data: xData
                    },
                    yAxis: {
                        type: 'category',
                        data: yData
                    },
                    visualMap: {
                        // type: 'piecewise',
                        min: 0,
                        max: 1,
                        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: {
                            emphasis: {
                                borderColor: '#333',
                                borderWidth: 2
                            }
                        },
                        progressive: 1000,
                        // silent: true,
                        // progressive: 0,
                        // progressiveThreshold: 30000,
                        animation: false
                    }]
                });
                console.timeEnd('render');
                // console.profileEnd('render');
            });

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