
<!--
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>
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
            #chart1, #chart2 {
                width: 50%;
                height: 500px;
                float: left;
            }
    </style>
        (1) hover on chart1: should no error.
        (2) <button onclick="loadChart2();">Load chart2</button>
        (3) hover on chart1 and chart2: should no error.

        <div>
            <div class="chart" id="chart1"></div>
            <div class="chart" id="chart2"></div>
        </div>
        <script>


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

                var chart1 = echarts.init(document.getElementById('chart1'));
                var chart2 = echarts.init(document.getElementById('chart2'));

                echarts.connect([chart1, chart2]);

                var data1 = [];

                var symbolCount = 6;

                for (var i = 0; i < 100; i++) {
                    data1.push([
                        Math.random() * 5,
                        Math.random() * 4,
                        Math.random() * 20,
                        Math.round(Math.random() * (symbolCount - 1))
                    ]);
                }

                chart1.setOption({
                    legend: {
                        top: 50,
                        data: ['scatter']
                    },
                    tooltip: {
                        formatter: '{c}'
                    },
                    grid: {
                        top: '26%',
                        bottom: '26%'
                    },
                    xAxis: {
                        type: 'value',
                        splitLine: {
                            show: false
                        }
                    },
                    yAxis: {
                        type: 'value',
                        splitLine: {
                            show: false
                        }
                    },
                    visualMap: [
                        {
                            realtime: false,
                            left: 'right',
                            orient: 'horizontal',
                            // selectedMode: 'single',
                            selectedMode: 'multiple',
                            backgroundColor: '#eee',
                            dimension: 2,
                            selected: [],
                            min: 0,
                            max: 24,
                            precision: 0,
                            splitNumber: 0,
                            calculable: true,
                            inRange: { // visual for short cut
                                color: ['#006edd', '#e0ffff']
                            }
                        }
                    ],
                    series: [
                        {
                            name: 'scatter',
                            type: 'scatter',
                            symbolSize: 30,
                            data: data1
                        }
                    ]
                });


                window.loadChart2 = function () {
                    chart2.setOption({
                        legend: {
                            top: 50,
                            data: ['scatter']
                        },
                        tooltip: {
                            formatter: '{c}'
                        },
                        grid: {
                            top: '26%',
                            bottom: '26%'
                        },
                        xAxis: {
                            type: 'value',
                            splitLine: {
                                show: false
                            }
                        },
                        yAxis: {
                            type: 'value',
                            splitLine: {
                                show: false
                            }
                        },
                        visualMap: [
                            {
                                left: 'right',
                                // selectedMode: 'single',
                                selectedMode: 'multiple',
                                orient: 'horizontal',
                                backgroundColor: '#eee',
                                dimension: 2,
                                selected: [],
                                min: 0,
                                max: 24,
                                precision: 0,
                                splitNumber: 0,
                                calculable: true,
                                inRange: { // visual for short cut
                                    color: ['#006edd', '#e0ffff']
                                }
                            }
                        ],
                        series: [
                            {
                                name: 'scatter',
                                type: 'scatter',
                                symbolSize: 30,
                                data: data1
                            }
                        ]
                    });
                }


            });

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