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

            require([
                'echarts'
                // 'echarts/chart/radar',
                // 'echarts/component/legend',
                // 'echarts/component/tooltip'
            ], function (echarts) {

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

                chart.setOption({
                    title: {
                        text: '多雷达图'
                    },
                    tooltip: {
                        trigger: 'axis'
                    },
                    legend: {
                        x: 'center',
                        data:['某软件','某主食手机','某水果手机','降水量','蒸发量']
                    },
                    radar: [
                        {
                            indicator: [
                                {text: '品牌', max: 100},
                                {text: '内容', max: 100},
                                {text: '可用性', max: 100},
                                {text: '功能', max: 100}
                            ],
                            center: ['25%',200],
                            radius: 80
                        },
                        {
                            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>