
<!--
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>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </head>
    <body>
        <style>
            .chart {
                height: 200px;
            }
            h1 {
                font-size: 20px;
                text-align: center;
                background: #bbb;
                padding: 10px 0;
            }
        </style>

        <h1>use the default values </h1>
        <div class="chart" id="main0"></div>
        <h1>only show the animation </h1>
        <div class="chart" id="main1"></div>
        <h1>only show the text </h1>
        <div class="chart" id="main2"></div>
        <h1>fontSzie: 25px, arcRadius: 12, lineWidth: 8</h1>
        <div class="chart" id="main3"></div>
        <h1>fontSzie: 25, arcRadius: 12, lineWidth: 8</h1>
        <div class="chart" id="main4"></div>
        <h1>fontSzie: 25, fontWeight: 'bolder', fontFamily: 'Microsoft YaHei', fontStyle: 'italic'</h1>
        <div class="chart" id="main5"></div>
        <h1>the spinner and text of loading show above the chart</h1>
        <div class="chart" id="main6"></div>
        <script>

            require([
                'echarts'
            ], function (echarts) {

                var chart0 = echarts.init(document.getElementById('main0'));
                chart0.showLoading();

                var chart1 = echarts.init(document.getElementById('main1'));
                chart1.showLoading({
                    text: '',
                    spinnerRadius: 50
                });

                var chart2 = echarts.init(document.getElementById('main2'));
                chart2.showLoading({
                    text: '没有 spinner 时，文字需要居中显示',
                    textColor: '#000',
                    fontSize: 20,
                    showSpinner: false
                });

                var chart3 = echarts.init(document.getElementById('main3'));
                chart3.showLoading({
                    text: '暂时没有数据',
                    textColor: '#000',
                    fontSize: '25px',
                    maskColor: 'rgba(255, 255, 255, 0.8)',
                    color: '#c23531',
                    arcRadius: 20,
                    lineWidth: 8,
                    zlevel: 0
                });

                var chart4 = echarts.init(document.getElementById('main4'));
                chart4.showLoading({
                    text: '暂时没有数据',
                    textColor: '#000',
                    fontSize: 25,
                    maskColor: 'rgba(255, 255, 255, 0.8)',
                    color: '#c23531',
                    arcRadius: 20,
                    lineWidth: 8,
                    zlevel: 0
                });

                var chart5 = echarts.init(document.getElementById('main5'));
                chart5.showLoading({
                    text: '暂时没有数据',
                    textColor: '#000',
                    fontSize: 25,
                    fontWeight: 'bolder', 
                    fontFamily: 'Microsoft YaHei', 
                    fontStyle: 'italic',
                    maskColor: 'rgba(255, 255, 255, 0.8)',
                    color: '#c23531',
                    arcRadius: 20,
                    lineWidth: 8,
                    zlevel: 0
                });

                var chart6 = echarts.init(document.getElementById('main6'));
                chart6.setOption({
                    angleAxis: {
                    },
                    radiusAxis: {
                        type: 'category',
                        data: ['周一', '周二', '周三', '周四'],
                        z: 10
                    },
                    polar: {
                    },
                    series: [{
                        type: 'bar',
                        data: [3, 2, 3, 4],
                        coordinateSystem: 'polar',
                        showBackground: true,
                        name: 'A',
                        stack: 'a',
                        emphasis: {
                            focus: 'series'
                        }
                    }],
                    legend: {
                        show: true,
                        data: ['A', 'B', 'C']
                    }
                });
                chart6.showLoading({
                    text: '暂时没有数据',
                    textColor: '#000',
                    fontSize: 25,
                    fontWeight: 'bolder', 
                    fontFamily: 'Microsoft YaHei', 
                    fontStyle: 'italic',
                    maskColor: 'rgba(255, 255, 255, 0.8)',
                    color: '#c23531',
                    arcRadius: 20,
                    lineWidth: 8,
                    zlevel: 0
                });

                window.onresize = function () {
                    chart0.resize();
                    chart1.resize();
                    chart2.resize();
                    chart3.resize();
                    chart4.resize();
                    chart5.resize();
                    chart6.resize();
                };
            });
        </script>
    </body>
</html>