
<!--
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>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
            }
        </style>
        <div id="main"></div>
        <script>

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

                var chart = echarts.init(document.getElementById('main'));

                chart.setOption({
                    aria: {
                        show: true
                    },
                    tooltip: {},
                    legend: {
                        data: [{
                            icon: 'circle',
                            name: 'Legend 应为 Circle'
                        }, '实际开销（Actual Spending）含有 "-" 数据', '第一个元素是 null', 'symbol 为 none 的需要用 roundRect']
                    },
                    radar: {
                        radius: [50, '70%'],
                        name: {
                            formatter:'【{value}】',
                            color:'#72ACD1'
                        },
                        triggerEvent: true,
                        // shape: 'circle',
                        indicator: [
                           { text: '销售（sales）', max: 100},
                           { text: '管理（Administration）', max: 16000},
                           { text: '信息技术（Information Techology）', max: 30000},
                           { text: '客服（Customer Support）', max: 38000},
                           { text: '研发（Development）', max: 52000},
                           { text: '市场（Marketing）', max: 25000}
                        ]
                    },
                    series: [{
                        name: '预算 vs 开销（Budget vs spending）',
                        type: 'radar',
                        label: {
                            normal: {
                                show: true
                            }
                        },
                        itemStyle: {
                            borderWidth: 3,
                            borderColor: '#fff'
                        },
                        // areaStyle: {normal: {}},
                        data : [
                            {
                                value : [0, 10000, 28000, 35000, 50000, 19000],
                                name : 'Legend 应为 Circle'
                            },
                             {
                                value : [50, 14000, 28000, 31000, '-', 21000],
                                name : '实际开销（Actual Spending）含有 "-" 数据'
                            },
                            {
                                value: ['-', 8000, 20000, 20000, 40000, 10000],
                                name: '第一个元素是 null'
                            }
                        ],
                        symbol: 'triangle',
                        symbolSize: 20,
                        symbolRotate: function(value, params) {
                            return ~~(360 * Math.random());
                        }
                    }, {
                        name: '2',
                        type: 'radar',
                        label: {
                            normal: {
                                show: true
                            }
                        },
                        data : [
                            {
                                value : [100, 2800, 3500, 5000, 1900, 1000],
                                name : 'symbol 为 none 的需要用 roundRect'
                            }
                        ],
                        symbol: 'none'
                    }]
                });
                var theIndex = 2;
                chart.on('click', function (params) {
                    console.log(params);
                    if (theIndex < 0) {
                        theIndex = 2;
                    }
                    chart.dispatchAction({
                        type: 'showTip',
                        seriesIndex: 0,
                        dataIndex: theIndex
                    });
                    theIndex--;
                });
            });

        </script>
    </body>
</html>
