
<!--
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/esl.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/dat.gui.min.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                background-image: url(old_mathematics.png);
                background-repeat: repeat;
            }
        </style>
        <div id="main"></div>
        <script>

            require([
                'echarts'
                // 'echarts/chart/pie',
                // 'echarts/component/legend',
                // 'echarts/component/grid',
                // 'echarts/component/tooltip',
                // 'echarts/component/toolbox'
            ], function (echarts) {

                var mainEl = document.getElementById('main');
                var chart = echarts.init(mainEl);
                var colorList = [
                    '#c23531', '#2f4554', '#61a0a8',
                    '#d48265', '#91c7ae','#749f83',
                    '#ca8622', '#bda29a','#6e7074',
                    '#546570', '#c4ccd3'
                ];

                var data = [
                    {value: 335, name: '直接访问'},
                    {value: 310, name: '邮件营销'},
                    {value: 234, name: '联盟广告'},
                    {value: 135, name: '视频广告'},
                    {value: 1548, name: '搜索引擎'}
                ];
                var legendData = [];

                echarts.util.each(data, function (item, index) {
                    item.itemStyle = {
                        normal: {color: colorList[index]}
                    };
                    legendData.push(item.name);
                });

                chart.setOption({
                    legend: {
                        data: legendData,
                        formatter: function (name) {
                            return name.replace(/\n/g, ' + ');
                        }
                    },
                    toolbox: {
                        left: 'left',
                        feature: {
                            dataView: {},
                            saveAsImage: {}
                        }
                    },
                    tooltip: {},
                    series: [{
                        name: 'pie',
                        type: 'pie',
                        selectedMode: 'single',
                        selectedOffset: 30,
                        clockwise: true,
                        label: {
                            normal: {
                                textStyle: {
                                    fontSize: 18,
                                    color: '#333'
                                }
                            }
                        },
                        labelLine: {
                            normal: {
                                lineStyle: {
                                    color: '#333'
                                }
                            }
                        },
                        data: data
                    }]
                });

                var dragging;
                var draggingDataIndex;
                var dx;
                var dy;
                var zr = chart.getZr();

                chart.on('mousedown', function (params) {
                    draggingDataIndex = getHoveredDataIndex(params);
                    if (draggingDataIndex != null) {

                        var srcSector = params.event.target;
                        dragging = new echarts.graphic.Sector({
                            shape: echarts.util.extend({}, srcSector.shape),
                            style: {
                                fill: srcSector.style.fill,
                                opacity: 0.5
                            },
                            silent: true,
                            z: 10000
                        });

                        dx = params.event.offsetX - srcSector.shape.cx;
                        dy = params.event.offsetY - srcSector.shape.cy;

                        zr.add(dragging);
                    }
                });

                chart.on('mouseup', function (params) {
                    if (dragging) {
                        var targetDataIndex = getHoveredDataIndex(params);
                        if (targetDataIndex != null
                            && targetDataIndex !== draggingDataIndex
                        ) {
                            data[targetDataIndex].value += data[draggingDataIndex].value;
                            data[targetDataIndex].name += '\n' + data[draggingDataIndex].name;
                            legendData[targetDataIndex] = data[targetDataIndex].name;
                            data.splice(draggingDataIndex, 1);
                            legendData.splice(draggingDataIndex, 1);
                            chart.setOption({
                                legend: {data: legendData},
                                series: {data: data}
                            });
                        }
                    }
                });

                mainEl.addEventListener('mousemove', function (e) {
                    var box = mainEl.getBoundingClientRect();
                    var zrX = e.clientX - box.left;
                    var zrY = e.clientY - box.top;

                    if (dragging) {
                        dragging.setShape({
                            cx: zrX - dx,
                            cy: zrY - dy
                        });
                    }
                });

                document.addEventListener('mouseup', function (e) {
                    if (dragging) {
                        zr.remove(dragging);
                        dragging = null;
                    }
                });

                function getHoveredDataIndex(params) {
                    return params.componentType === 'series'
                        && params.componentSubType === 'pie'
                        && params.dataIndex;
                }

            })

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