
<!--
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, #main1, #main0 {
                width: 100%;
                height: 500px;
            }
        </style>
        <div id="main0"></div>
        <div id="main1"></div>

        <script>

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

                var chart = echarts.init(document.getElementById('main0'), null, {

                });

                var xAxisData = [];
                var data1 = [];
                var data2 = [];
                var data3 = [];

                for (var i = 0; i < 10; i++) {
                    xAxisData.push('类目' + i);
                    data1.push((Math.random() * 2 + 1).toFixed(3));
                    data3.push((Math.random() + 0.5).toFixed(3));
                    data2.push((Math.random() + 0.5).toFixed(3));
                }

                chart.setOption({
                    legend: {
                        data: ['line', 'line2', 'line3']
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'shadow'
                        }
                    },
                    polar: {},
                    angleAxis: {
                        // data: ['类目1', '类目2', '类目3', '类目4', '类目5',]
                        data: xAxisData,
                        startAngle: 30
                    },
                    radiusAxis: {
                        axisLine: {
                            symbol: 'arrow',
                            symbolOffset: [20, -20]
                        }
                    },
                    animationDuration: 5000,
                    series: [{
                        coordinateSystem: 'polar',
                        name: 'line',
                        stack: 'all',
                        type: 'line',
                        symbolSize: 10,
                        label: {
                            show: true
                        },
                        itemStyle: {
                            normal: {
                                areaStyle: {}
                            }
                        },
                        markPoint: {
                            data: [{
                                type: 'max'
                            }]
                        },
                        data: data1
                    }, {
                        coordinateSystem: 'polar',
                        name: 'line2',
                        stack: 'all',
                        type: 'line',
                        symbolSize: 10,
                        label: {
                            show: true
                        },
                        itemStyle: {
                            normal: {
                                areaStyle: {}
                            }
                        },
                        markLine: {
                            data: [[{
                                type: 'max'
                            }, {
                                type: 'min'
                            }]]
                        },
                        data: data2
                    }, {
                        coordinateSystem: 'polar',
                        name: 'line3',
                        stack: 'all',
                        type: 'line',
                        symbolSize: 10,
                        label: {
                            show: true
                        },
                        itemStyle: {
                            normal: {
                                areaStyle: {}
                            }
                        },
                        data: data3
                    }]
                });
            })

        </script>


        <script>

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

                var chart = echarts.init(document.getElementById('main1'), null, {

                });

                var xAxisData = [];
                var data1 = [];
                var data2 = [];
                var data3 = [];

                for (var i = 0; i < 10; i++) {
                    xAxisData.push('类目' + i);
                    data1.push((Math.random() * 2 + 1).toFixed(3));
                    data3.push((Math.random() + 0.5).toFixed(3));
                    data2.push((Math.random() + 0.5).toFixed(3));
                }

                chart.setOption({
                    legend: {
                        data: ['line', 'line2', 'line3']
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'shadow'
                        }
                    },
                    polar: {
                        radius: [40, 200]
                    },
                    angleAxis: {
                        axisLine: {
                            symbol: 'arrow',
                            symbolOffset: [20, -20]
                        }
                    },
                    radiusAxis: {
                        // data: ['类目1', '类目2', '类目3', '类目4', '类目5',]
                        data: xAxisData,
                        startAngle: 30
                    },
                    animationDuration: 5000,
                    series: [{
                        coordinateSystem: 'polar',
                        name: 'line',
                        stack: 'all',
                        type: 'line',
                        symbolSize: 10,
                        label: {
                            show: true
                        },
                        markPoint: {
                            data: [{
                                type: 'max'
                            }]
                        },
                        data: data1
                    }, {
                        coordinateSystem: 'polar',
                        name: 'line2',
                        stack: 'all',
                        type: 'line',
                        symbolSize: 10,
                        label: {
                            show: true
                        },
                        markLine: {
                            data: [[{
                                type: 'max'
                            }, {
                                type: 'min'
                            }]]
                        },
                        data: data2
                    }, {
                        coordinateSystem: 'polar',
                        name: 'line3',
                        stack: 'all',
                        type: 'line',
                        symbolSize: 10,
                        label: {
                            show: true
                        },
                        data: data3
                    }]
                });
            })

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