
<!--
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>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="lib/reset.css" />
        <script src="lib/testHelper.js"></script>
        <script src="tooltipTestHelper.js"></script>
    </head>
    <body>
        <style>
            h1 {
                line-height: 60px;
                height: 60px;
                background: #ddd;
                text-align: center;
                font-weight: bold;
                font-size: 14px;
            }
            .chart {
                height: 350px;
            }
        </style>

        <h1>dynamic data update tooltip content and keep show</h1>
        <div><a target="_blank" href="dynamicData.html">dynamicData.html</a></div>
        <div><a target="_blank" href="dynamicData2.html">dynamicData2.html</a></div>
        <div><a target="_blank" href="dynamicData3.html">dynamicData3.html</a></div>
        <h1>triggerOn: click, setOption when trigger axis (keep show)</h1>
        <div class="chart" id="click-setOption1"></div>
        <h1>tooltip should auto show and auto disappear when setOption(..., {notMerge: true})</h1>
        <div class="chart" id="setOption2"></div>
        <div class="chart" id="setOption3" style="height: 550px"></div>

        <script>
            require(['echarts'], function (echarts) {
                var option = {
                    legend: {
                        tooltip: {
                            show: true,
                            enterable: true
                        }
                    },
                    tooltip: {
                        trigger: 'axis',
                        triggerOn: 'click',
                        enterable: true,
                        axisPointer: {
                            type: 'cross'
                        },
                        formatter: function () {
                            return '<button onclick="console.log(\'click\');window.ecClickSetOptionAxisChart.setOption({tooltip: {}});">click me</button>';
                        }
                    }
                };
                var baseTop = 90;
                var height = 150;
                var gap = 50;
                makeCategoryGrid(option, {
                    grid: {top: baseTop, height: height},
                    yAxis: {
                        name: 'click show tip',
                        tooltip: {
                            show: true
                        }
                    }
                });
                baseTop += height + gap;

                var chart = createChart('click-setOption1', echarts, option, baseTop);
                window.ecClickSetOptionAxisChart = chart;
            })
        </script>

        <script>
            require([
                'echarts'
            ], function (echarts) {
                function genOption() {
                    return {
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross'
                            }
                        },
                        xAxis: {},
                        yAxis: {},
                        series: [{
                            type: 'scatter',
                            data: [
                                [Math.random(), Math.random() * 100],
                                [Math.random(), Math.random() * 100],
                                [Math.random(), Math.random() * 100]
                            ]
                        }]
                    };
                }

                var chart = echarts.init(document.getElementById('setOption2'));
                chart.setOption(genOption());

                setTimeout(function () {
                    chart.dispatchAction({
                        type: 'showTip',
                        seriesIndex: 0,
                        dataIndex: 0
                    });

                    setTimeout(function () {
                        // chart.clear();
                        chart.dispose();

                        chart = echarts.init(document.getElementById('setOption2'));

                        chart.setOption(genOption());
                    }, 2000)
                }, 100);
            });
        </script>

        <script>
            require(['echarts'], function (echarts) {
                var colors = ['red', 'blue'];
                var option = {
                    color: colors,
                    "tooltip": {
                        "show": true
                    },
                    "xAxis": {
                        "type": "category",
                        "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                    },
                    "yAxis": {
                    },
                    "series": [{
                        "data": [820, 932, 901, 934, 1290, 1330, 1320],
                        "type": 'bar'
                    }, {
                        "data": [620, 532, 501, 734, 1090, 1130, 1220],
                        "type": 'bar'
                    }]
                };

                var myChart = testHelper.create(echarts, 'setOption3', {
                    title: 'Click the blue bar, should no error throw',
                    option: option
                });

                myChart.on('click', function (params) {
                    myChart.clear();
                    myChart.setOption({
                        "tooltip": {
                            "show": true
                        },
                        "xAxis": {
                            "type": "category",
                            "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                        },
                        "yAxis": {
                        },
                        "series": [{
                            "data": [820, 932, 901, 934, 1290, 1330, 1320],
                            "type": 'bar'
                        }]
                    });
                });
            });
        </script>
    </body>
</html>