<!DOCTYPE html>
<!--
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">
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="lib/esl.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
        <script src="lib/facePrint.js"></script>
        <script src="lib/testHelper.js"></script>
        <script src="lib/dat.gui.min.js"></script>
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
            body {
                background-color: #eee;
                text-align: center;
                padding-top: 20px;
            }
            .chart {
                border-radius: 5px;
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
                margin: 20px auto;
                width: 360px;
                height: 200px;
                background-color: #fff;
                text-align: left;
            }
            .dg {
                text-align: left;
            }
        </style>



        <div id="main0"></div>









        <script>
        require(['echarts'], function (echarts) {
            const datas = [
                ////////////////////////////////////////
                [
                    { name: '圣彼得堡来客', value: 5.6 },
                    { name: '陀思妥耶夫斯基全集', value: 1 },
                    { name: '史记精注全译（全6册）', value: 0.8 },
                    { name: '加德纳艺术通史', value: 0.5 },
                    { name: '表象与本质', value: 0.5 },
                    { name: '其它', value: 3.8 }
                ],

                // ////////////////////////////////////////
                [
                    { name: '银河帝国5：迈向基地', value: 3.8 },
                    { name: '俞军产品方法论', value: 2.3 },
                    { name: '艺术的逃难', value: 2.2 },
                    { name: '第一次世界大战回忆录（全五卷）', value: 1.3 },
                    { name: 'Scrum 精髓', value: 1.2 },
                    { name: '其它', value: 5.7 }
                ],

                ////////////////////////////////////////
                [
                    { name: '克莱因壶', value: 3.5 },
                    { name: '投资最重要的事', value: 2.8 },
                    { name: '简读中国史', value: 1.7 },
                    { name: '你当像鸟飞往你的山', value: 1.4 },
                    { name: '表象与本质', value: 0.5 },
                    { name: '其它', value: 3.8 }
                ]
            ];

            const charts = [];

            datas.forEach(function (data) {
                const dom = document.createElement('div');
                dom.classList.add('chart');
                document.querySelector('#main0').appendChild(dom);

                const chart = echarts.init(dom);
                chart.setOption({
                    // color: ['#1B2550', '#2A3566', '#2B3C87', '#4853A7', '#858ED8', '#858ED8', '#A3ABEE'],
                    title: {
                        text: '阅读书籍分布',
                        left: 'center',
                        textStyle: {
                            color: '#999',
                            fontWeight: 'normal',
                            fontSize: 14
                        }
                    },
                    series: [{
                        type: 'pie',
                        radius: [20, 60],
                        itemStyle: {
                            borderColor: '#fff',
                            borderWidth: 1
                        },
                        label: {
                            alignTo: 'edge',
                            formatter: '{name|{b}}\n{time|{c} 小时}',
                            minMargin: 5,
                            edgeDistance: 10,
                            lineHeight: 15,
                            rich: {
                                time: {
                                    fontSize: 10,
                                    color: '#999'
                                }
                            }
                        },
                        labelLine: {
                            length: 15,
                            length2: 0,
                            maxSurfaceAngle: 80
                        },
                        labelLayout: function (params) {
                            const isLeft = params.labelRect.x < chart.getWidth() / 2;
                            const points = params.labelLinePoints;
                            // Update the end point.
                            points[2][0] = isLeft
                                ? params.labelRect.x
                                : params.labelRect.x + params.labelRect.width;

                            return {
                                labelLinePoints: points
                            }
                        },
                        data: data
                    }]
                });

                charts.push(chart);
            });

            const gui = new dat.GUI();
            const config = {
                labelLine: {
                    smooth: 0,
                    maxSurfaceAngle: 80
                },
                label: {
                    edgeDistance: 10
                }
            };

            function update() {
                charts.forEach(function (chart) {
                    chart.setOption({
                        series: {
                            label: Object.assign({}, config.label, {
                                edgeDistance: config.label.edgeDistance
                            }),
                            labelLine: config.labelLine
                        }
                    });
                });
            }

            const labelFolder = gui.addFolder('label');
            const labelLineFolder = gui.addFolder('labelLine');
            labelFolder.open();
            labelLineFolder.open();
            labelFolder.add(config.label, 'edgeDistance', 0, 50).onChange(update);
            labelLineFolder.add(config.labelLine, 'maxSurfaceAngle', 0, 90).onChange(update);
            labelLineFolder.add(config.labelLine, 'smooth', 0, 1).onChange(update);
        });
        </script>


    </body>
</html>

