
<!--
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 * 100).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 * 100).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>