
<!--
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>
            #main0, #main1 {
                width: 100%;
                height: 1200px;
                margin: 20px 0;
            }
        </style>
        <h3>Polar bar series label positions</h3>
        <div id="main0"></div>
        <div id="main1"></div>
        <script>

            require(['echarts'], function (echarts) {
                function setChart(chartIndex) {
                    var positions = [
                        'start', 'insideStart',
                        'middle',
                        'insideEnd','end',
                        'inside', 'outside'
                    ];

                    var chart = echarts.init(document.getElementById('main' + chartIndex));
                    var rows = 3;
                    var cols = 3;

                    var angleAxis = [];
                    var radiusAxis = [];
                    var polar = [];
                    var series = [];
                    var title = [];
                    var cnt = positions.length;
                    for (var i = 0; i < rows; ++i) {
                        for (var j = 0; j < cols; ++j) {
                            var id = i * cols + j;
                            if (id >= cnt) {
                                break;
                            }
                            angleAxis.push({
                                max: 4,
                                polarIndex: id,
                                startAngle: 75
                            });
                            radiusAxis.push({
                                polarIndex: id,
                                type: 'category',
                                data: ['a', 'b', 'c', 'd'],
                                startAngle: 75
                            });
                            polar.push({
                                center: [
                                    100 / cols * (j + 0.5) + '%',
                                    100 / rows * (i + 0.5) + '%'
                                ],
                                radius: [
                                    chartIndex ? 10 : 30,
                                    100 / rows * 0.75 + '%'
                                ]
                            });
                            series.push({
                                type: 'bar',
                                data: [
                                    chartIndex ? 0.5 : 2,
                                    1.2,
                                    2.4, 3.6
                                ],
                                coordinateSystem: 'polar',
                                polarIndex: id,
                                label: {
                                    show: true,
                                    position: positions[id],
                                    formatter: '{b}: {c}',
                                    borderColor: '#0ff',
                                    borderWidth: 2,
                                    // rotate:
                                }
                            });
                            title.push({
                                text: positions[id],
                                left: 100 / cols * (j + 0.5) + '%',
                                top: 100 / rows * (i + 0.92) + '%',
                                textAlign: 'center'
                            });
                        }
                    }

                    chart.setOption({
                        title: title,
                        angleAxis: chartIndex ? angleAxis : radiusAxis,
                        radiusAxis: chartIndex ? radiusAxis : angleAxis,
                        polar: polar,
                        tooltip: {},
                        series: series,
                        backgroundColor: '#fff',
                        animation: 0
                    });
                }

                setChart(0);
                setChart(1);
            });
        </script>
    </body>
</html>
