<!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="ut/lib/canteen.js"></script> -->
        <script src="lib/dat.gui.min.js"></script>
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
        </style>



        <div id="main-none"></div>
        <div id="main0"></div>
        <div id="main1"></div>
        <div id="main2"></div>








        <script>
        require(['echarts'], function (echarts) {
            var count = 20;
            var data = [];
            var text = '';
            for (var i = 0; i < count; i++) {
                text += 'XY';
                data.push({
                    name: text + i,
                    value: Math.random()
                });
            }

            var optionNone = {
                series: [{
                    type: 'pie',
                    radius: '50%',
                    data: data,

                    labelLine: {
                        length2: 15
                    },
                    label: {
                        edgeDistance: 20,
                        position: 'outer'
                    }
                }]
            };

            var option0 = {
                series: [{
                    type: 'pie',
                    radius: '50%',
                    data: data,

                    labelLine: {
                        length2: 15
                    },
                    label: {
                        edgeDistance: 20,
                        position: 'outer',
                        alignTo: 'labelLine'
                    }
                }]
            };

            var option1 = {
                series: [{
                    type: 'pie',
                    radius: '50%',
                    data: data,

                    labelLine: {
                        length2: 15
                    },
                    label: {
                        edgeDistance: 20,
                        position: 'outer',
                        alignTo: 'edge'
                    }
                }]
            };

            var option2 = {
                series: [{
                    type: 'pie',
                    radius: '25%',
                    center: ['50%', '50%'],
                    data: data,

                    labelLine: {
                        length2: 15
                    },
                    label: {
                        position: 'outer',
                        alignTo: 'edge'
                    },
                    left: 0,
                    right: '50%',
                    top: 0,
                    bottom: '50%'
                }, {
                    type: 'pie',
                    radius: '25%',
                    center: ['50%', '50%'],
                    data: data,

                    labelLine: {
                        length2: 15
                    },
                    label: {
                        edgeDistance: 20,
                        position: 'outer',
                        alignTo: 'labelLine'
                    },
                    left: '50%',
                    right: 0,
                    top: 0,
                    bottom: '50%'
                }, {
                    type: 'pie',
                    radius: '25%',
                    center: ['50%', '50%'],
                    data: data,

                    labelLine: {
                        length2: 15
                    },
                    label: {
                        position: 'outer',
                        alignTo: 'edge'
                    },
                    left: 0,
                    right: '50%',
                    top: '50%',
                    bottom: 0
                }, {
                    type: 'pie',
                    radius: '25%',
                    center: ['50%', '50%'],
                    data: data,

                    labelLine: {
                        length2: 15
                    },
                    label: {
                        edgeDistance: 20,
                        position: 'outer',
                        alignTo: 'labelLine'
                    },
                    left: '50%',
                    right: 0,
                    top: '50%',
                    bottom: 0
                }]
            };

            var chartNone = testHelper.create(echarts, 'main-none', {
                title: 'alignTo: "none"',
                option: optionNone
            });

            var chart0 = testHelper.create(echarts, 'main0', {
                title: 'alignTo: "labelLine"',
                option: option0
            });

            var chart1 = testHelper.create(echarts, 'main1', {
                title: 'alignTo: "edge"',
                option: option1
            });

            var chart2 = testHelper.create(echarts, 'main2', {
                title: 'Multiple charts',
                option: option2
            });

            var gui = new dat.GUI();
            var config = {
                length2: 15,
                edgeDistance: 20,
                overflow: 'truncate'
            };

            function update() {
                const newOpt = {
                    series: [{
                        labelLine: {
                            length2: config.length2
                        },
                        label: {
                            edgeDistance: config.edgeDistance,
                            overflow: config.overflow
                        }
                    }]
                }
                chart0.setOption(newOpt);
                chart1.setOption(newOpt);
                chartNone.setOption(newOpt);

                const newOpt2 = { series: [] };
                for (var i = 0; i < 4; ++i) {
                    newOpt2.series.push({
                        labelLine: {
                            length2: config.length2,
                        },
                        label: {
                            edgeDistance: config.edgeDistance,
                            overflow: config.overflow
                        }
                    })
                }
                chart2.setOption(newOpt2);
            }

            gui.add(config, 'length2', 0, 300).onChange(update);
            gui.add(config, 'edgeDistance', 0, 300).onChange(update);
            gui.add(config, 'overflow', ['truncate', 'break', 'breakAll']).onChange(update);
        });
        </script>
    </body>
</html>

