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