<!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/simpleRequire.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>

