
<!--
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/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/dat.gui.min.js"></script>
        <link rel="stylesheet" href="lib/reset.css">
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
            }
        </style>
        <div id="main"></div>
        <script>

            require([
                '../node_modules/seedrandom/seedrandom.js',
                'echarts',
            ], function (seedrandom, echarts) {
                Math.random = new seedrandom('echarts-random');

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

                var symbolList = [
                    'circle',
                    'triangle',
                    'diamond',
                    'pin',
                    'image://./asset/echarts-logo.png',
                    'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
                    'emptyPath://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891'
                ];

                function random(max) {
                    return (Math.random() * max).toFixed(3);
                }

                var series = symbolList.map(function (symbol, idx) {
                    var seriesData = [];
                    for (var i = 0; i < 20; i++) {
                        seriesData.push([random(10), random(10), (+random(0.5) + 0.2).toFixed(3)]);
                    }
                    return {
                        name: symbol.split('://')[0],
                        type: 'scatter',
                        symbol: symbol,
                        symbolSize: function (val) {
                            if (symbol.indexOf('path') >= 0 || symbol.indexOf('Path') >= 0) {
                                return [val[2] * 60, val[2] * 40];
                            }
                            else {
                                return val[2] * 60;
                            }
                        },
                        label: {
                            emphasis: {
                                show: false
                            }
                        },
                        data: seriesData
                    };
                });

                chart.setOption({
                    legend: {
                        data: series.map(function (series) {return series.name;})
                    },
                    xAxis: {
                        type: 'value',
                        splitLine: {
                            show: false
                        }
                    },
                    yAxis: {
                        type: 'value',
                        splitLine: {
                            show: false
                        }
                    },
                    series: series
                });

                window.addEventListener('resize', chart.resize);

                var symbolScaleValueMap = {
                    'undefined': undefined,
                    'null': null,
                    'true': true,
                    'false': false,
                    '0': 0,
                    '0.5': 0.5,
                    '1': 1,
                    '1.1': 1.1,
                    '2': 2,
                    'NaN': NaN,
                    'Infinity': Infinity,
                    'Negative(-1)': -1,
                    'Empty String': '',
                    'String(\'abc\')': 'abc'
                }

                var config = {
                    hoverScale: 'false',
                    tooltipTrigger: 'item'
                };

                var gui = new dat.GUI();
                gui.add(config, 'hoverScale', Object.keys(symbolScaleValueMap))
                    .onChange(update);
                gui.add(config, 'tooltipTrigger', ['axis', 'item'])
                    .onChange(update);

                update();

                function update() {
                    var activeHoverScale = symbolScaleValueMap[config.hoverScale];
                    console.log('active hoverScale', activeHoverScale);
                    series.forEach(function (series) {
                        series.emphasis = series.emphasis || {};
                        series.emphasis.scale = activeHoverScale;
                    });
                    var tooltip = {
                        trigger: config.tooltipTrigger,
                        axisPointer: config.tooltipTrigger === 'axis'
                            ? { type: 'cross' }
                            : null
                    };
                    console.log(tooltip);
                    chart.setOption({
                        tooltip: tooltip,
                        series: series
                    });
                }
            });

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