
<!--
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({
                    title: [{
                        text: '多雷达图'
                    }, {
                        text: 'Tooltip series names should not be "-"',
                        left: '25%',
                        top: 320,
                        textAlign: 'center'
                    }],
                    tooltip: {
                        trigger: 'axis'
                    },
                    legend: {
                        x: 'center',
                        data:['某软件','某主食手机','某水果手机','降水量','蒸发量']
                    },
                    radar: [
                        {
                            indicator: [
                                {name: '品牌', max: 100},
                                {name: '内容', max: 100},
                                {name: '可用性', max: 100},
                                // text is deprecated
                                {text: '功能', max: 100}
                            ],
                            center: ['25%',200],
                            radius: 80,
                            axisName: {
                                show: false
                            }
                        },
                        {
                            indicator: [
                                {text: '外观', max: 100},
                                {text: '拍照', max: 100},
                                {text: '系统', max: 100},
                                {text: '性能', max: 100},
                                {text: '屏幕', max: 100}
                            ],
                            radius: 80
                        },
                        {
                            indicator: (function (){
                                var res = [];
                                for (var i = 1; i <= 12; i++) {
                                    res.push({text:i+'月',max:100});
                                }
                                return res;
                            })(),
                            center: ['75%', 200],
                            radius: 80
                        }
                    ],
                    series: [
                        {
                            type: 'radar',
                             tooltip: {
                                trigger: 'item'
                            },
                            itemStyle: {normal: {areaStyle: {type: 'default'}}},
                            data: [
                                {
                                    value: [60,73,85,40],
                                    name: '某软件'
                                }
                            ]
                        },
                        {
                            type: 'radar',
                            radarIndex: 1,
                            data: [
                                {
                                    value: [85, 90, 90, 95, 95],
                                    name: '某主食手机'
                                },
                                {
                                    value: [95, 80, 95, 90, 93],
                                    name: '某水果手机'
                                }
                            ]
                        },
                        {
                            type: 'radar',
                            radarIndex: 2,
                            itemStyle: {normal: {areaStyle: {type: 'default'}}},
                            data: [
                                {
                                    name: '降水量',
                                    value: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 75.6, 82.2, 48.7, 18.8, 6.0, 2.3],
                                },
                                {
                                    name:'蒸发量',
                                    value:[2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 35.6, 62.2, 32.6, 20.0, 6.4, 3.3]
                                }
                            ]
                        }
                    ]
                });
            });

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