
<!--
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>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
            }
        </style>
        <div id="main"></div>
        <script>

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

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

                var data1 = [];
                var data2 = [];
                var data3 = [];

                var names = [
                    'diamond, red, show inside label only on hover',
                    'green, show top label only on hover',
                    'indigo, show inside label on normal'
                ];

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

                for (var i = 0; i < 50; i++) {
                    data1.push([random(5), random(5), random(2)]);
                    data2.push([random(10), random(10), random(2)]);
                    data3.push([random(15), random(10), random(2)]);
                }

                chart.setOption({
                    aria: {
                        show: true
                    },
                    legend: {
                        data: names.slice()
                    },
                    toolbox: {
                        left: 'left',
                        feature: {
                            dataView: {},
                            saveAsImage: {},
                            dataZoom: {}
                        }
                    },
                    tooltip: {
                        trigger: 'item',
                        position: 'top',
                        borderWidth: 4
                    },
                    xAxis: {
                        type: 'value',
                        splitLine: {
                            show: false
                        },
                        min: 0,
                        max: 15,
                        splitNumber: 30
                    },
                    yAxis: {
                        type: 'value',
                        splitLine: {
                            show: false
                        }
                    },
                    series: [{
                        name: names[0],
                        type: 'scatter',
                        label: {
                            emphasis: {
                                show: true
                            }
                        },
                        symbol: 'diamond',
                        symbolSize: function (val) {
                            return val[2] * 40;
                        },
                        data: data1
                    },
                    {
                        name: names[1],
                        type: 'scatter',
                        emphasis: {
                            scale: 3,
                            label: {
                                show: true,
                                position: 'top',
                                formatter: function (params) {
                                    return params.value;
                                }
                            }
                        },
                        symbolSize: function (val) {
                            return val[2] * 40;
                        },
                        itemStyle: {
                            color: function (params) {
                                return 'rgba(30, 70, 50, ' + (params.value ? params.value[2] : 0) + ')';
                            }
                        },
                        data: data2
                    },
                    {
                        name: names[2],
                        type: 'scatter',
                        label: {
                            show: true
                        },
                        symbolSize: function (val) {
                            return val[2] * 40;
                        },
                        data: data3
                    }],
                    animationDelay: function (idx) {
                        return idx * 20;
                    },
                    animationDelayUpdate: function (idx) {
                        return idx * 20;
                    }
                });

                chart.on('click', function (params) {
                    console.log(params.data);
                });
            })

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