
<!--
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>
        <script src="lib/jquery.min.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                padding: 0;
                margin: 0;
                width: 100%;
                height: 550px;
            }
            .operations {
                margin-top: 10px;
                margin-bottom: 30px;
            }
        </style>
        <div class="operations">
            <input type="radio" name="inside" value="radius"/> inside zoom radius
            <input type="radio" name="inside" value="angle" checked="checked"/> inside zoom angle
            <input type="radio" name="inside" value="all"/> inside zoom all
        </div>
        <div id="main"></div>
        <script>

            require([
                'echarts'
                // 'echarts/chart/scatter',
                // 'echarts/component/legend',
                // 'echarts/component/polar',
                // 'echarts/component/dataZoom'
            ], function (echarts) {

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

                });

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

                for (var i = 0; i < 100; i++) {
                    data1.push([Math.random() * 5, Math.random() * 360]);
                    data2.push([Math.random() * 5, Math.random() * 360]);
                    data3.push([Math.random() * 10, Math.random() * 360]);
                }

                chart.setOption({
                    legend: {
                        data: ['scatter', 'scatter2', 'scatter3']
                    },
                    polar: {

                    },
                    angleAxis: {
                        type: 'value'
                    },
                    radiusAxis: {
                        axisAngle: 0
                    },
                    dataZoom: [
                        {
                            id: 'slider-v',
                            show: true,
                            orient: 'vertical',
                            angleAxisIndex: [0]
                        },
                        {
                            id: 'slider-h',
                            show: true,
                            orient: 'horizontal',
                            radiusAxisIndex: [0]
                        }
                    ],
                    series: [{
                        coordinateSystem: 'polar',
                        // FIXME
                        // 现在必须得设置这个，能不能polar和catesian一样，要不然很多特殊处理。
                        angleAxisIndex: 0,
                        radiusAxisIndex: 0,
                        name: 'scatter',
                        type: 'scatter',
                        symbolSize: 10,
                        data: data1
                    }, {
                        coordinateSystem: 'polar',
                        angleAxisIndex: 0,
                        radiusAxisIndex: 0,
                        name: 'scatter2',
                        type: 'scatter',
                        symbolSize: 10,
                        data: data2
                    }, {
                        coordinateSystem: 'polar',
                        angleAxisIndex: 0,
                        radiusAxisIndex: 0,
                        name: 'scatter3',
                        type: 'scatter',
                        symbolSize: 10,
                        data: data3
                    }]
                });

                var radioOption = {
                    radius: {
                        dataZoom: [
                            {
                                disabled: true,
                                id: 'inside-a',
                                type: 'inside',
                                angleAxisIndex: 0
                            },
                            {
                                disabled: false,
                                id: 'inside-r',
                                type: 'inside',
                                radiusAxisIndex: 0
                            }
                        ]
                    },
                    angle: {
                        dataZoom: [
                            {
                                disabled: false,
                                id: 'inside-a',
                                type: 'inside',
                                angleAxisIndex: 0
                            },
                            {
                                disabled: true,
                                id: 'inside-r',
                                type: 'inside',
                                radiusAxisIndex: 0
                            }
                        ]
                    },
                    all: {
                        dataZoom: [
                            {
                                disabled: false,
                                id: 'inside-a',
                                type: 'inside',
                                angleAxisIndex: [0]
                            },
                            {
                                disabled: false,
                                id: 'inside-r',
                                type: 'inside',
                                radiusAxisIndex: [0]
                            }
                        ]
                    }
                };

                initRadio();

                chart.setOption(radioOption.angle);

                function initRadio() {
                    $('.operations').on('click', function () {
                        $('.operations input').each(function (idx, el) {
                            if (el.checked) {
                                chart.setOption(radioOption[el.getAttribute('value')]);
                            }
                        });
                    });
                }


            })



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