
<!--
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" />
    </head>
    <body>
        <style>
            html, body {
                width: 100%;
                height: 100%;
            }
            .chart {
                width: 50%;
                height: 100%;
                float: left;
            }
            .tooltip-content {
                color: #000;
                width: 200px;
                text-align: center;
                margin-left: -100px;
                margin-top: -80px;
            }
            .tooltip-content h4 {
                font-size: 20px;
                color: #999;
            }
            .tooltip-content h5 {
                font-size: 28px;
                color: #666;
            }
        </style>
        <div id="main1" class="chart"></div>
        <div id="main2" class="chart"></div>
        <script>

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

                var chart1 = echarts.init(document.getElementById('main1'), null, {

                });

                chart1.setOption({
                    title: {
                        text: 'hoverOffset: 10'
                    },
                    tooltip: {
                        position: ['50%', '50%'],
                        backgroundColor: 'transparent',
                        formatter: function (params) {
                            return '<div class="tooltip-content">\
                                <h4>' + params.name + '</h4>\
                                <h5>' + params.percent.toFixed(1) + '%</h5>\
                                </div><script>console.log(1111)<\/script>\
                            ';
                        },
                        borderWidth: 0,
                        shadowColor: 'transparent'
                    },
                    series: [{
                        name: 'pie',
                        type: 'pie',
                        selectedMode: 'single',
                        selectedOffset: 30,
                        clockwise: true,
                        radius: ['20%', '40%'],
                        label: {
                            normal: {
                                show: false
                            }
                        },
                        labelLine: {
                            show: false
                        },
                        data:[
                            {value:379.5, name:'前任2：备胎反击战', selected: true},
                            {value:252.7, name:'移动迷宫：烧痕审判'},
                            {value:173.4, name:'绝命海拔'},
                            {value:153.1, name:'剩者为王'},
                            {value:49.4, name:'史努比：花生大电影'},
                            {value:32.2, name:'山河故人'},
                            {value:21.9, name:'蚁人'},
                            {value:19.5, name:'夏洛特烦恼'}
                        ]
                    }]
                });



                var chart2 = echarts.init(document.getElementById('main2'), null, {

                });

                chart2.setOption({
                    title: {
                        text: 'hoverOffset: 50'
                    },
                    tooltip: {
                        position: ['50%', '50%'],
                        backgroundColor: 'transparent',
                        formatter: function (params) {
                            return '<div class="tooltip-content">\
                                <h4>' + params.name + '</h4>\
                                <h5>' + params.percent.toFixed(1) + '%</h5>\
                                </div>\
                            ';
                        },
                        borderWidth: 0,
                        shadowColor: 'transparent'
                    },
                    series: [{
                        name: 'pie',
                        type: 'pie',
                        selectedMode: 'single',
                        selectedOffset: 30,
                        hoverOffset: 50,
                        clockwise: true,
                        radius: ['20%', '40%'],
                        label: {
                            normal: {
                                show: false
                            }
                        },
                        labelLine: {
                            show: false
                        },
                        data:[
                            {value:379.5, name:'前任2：备胎反击战', selected: true},
                            {value:252.7, name:'移动迷宫：烧痕审判'},
                            {value:173.4, name:'绝命海拔'},
                            {value:153.1, name:'剩者为王'},
                            {value:49.4, name:'史努比：花生大电影'},
                            {value:32.2, name:'山河故人'},
                            {value:21.9, name:'蚁人'},
                            {value:19.5, name:'夏洛特烦恼'}
                        ]
                    }]
                });
            });

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