<!DOCTYPE html>
<!--
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">
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="lib/esl.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
        <script src="lib/facePrint.js"></script>
        <script src="lib/testHelper.js"></script>
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
            .test-title {
                background: #146402;
                color: #fff;
            }
        </style>


        <div id="main1"></div>
        <div id="main0"></div>
        <div id="main2"></div>








        <script>

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

                var data = [];
                for (var i = 0; i < 10; i++) {
                    data.push([
                        Math.random() * 10,
                        Math.random() * 10
                    ]);
                }

                var option = {
                    toolbox: {
                        left: 10
                    },
                    brush: {
                        xAxisIndex: 'all',
                        removeOnClick: true,
                        brushMode: 'single'
                    },
                    xAxis: {
                        min: 0,
                        max: 10
                    },
                    yAxis: {
                        min: 0,
                        max: 10
                    },
                    series: {
                        type: 'bar',
                        data: data
                    }
                };

                var chart = testHelper.create(echarts, 'main1', {
                    title: 'removeOnClick',
                    height: 200,
                    option: option
                });

                chart && chart.on('brushSelected', function () {
                    console.log('brushSelecteddd');
                });
            });

        </script>



        <script>

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

                var data = [];
                for (var i = 0; i < 500; i++) {
                    data.push([
                        Math.random() * 10,
                        Math.random() * 10
                    ]);
                }

                var option = {
                    toolbox: {
                        feature: {
                            brush: {
                                type: ['polygon', 'rect', 'lineX', 'lineY', 'keep', 'clear']
                            }
                        }
                    },
                    brush: {
                        xAxisIndex: 'all',
                        brushLink: 'all'
                    },
                    grid: {
                        width: 300,
                        height: 200
                    },
                    xAxis: {
                        min: 0,
                        max: 10
                    },
                    yAxis: {
                        min: 0,
                        max: 10
                    },
                    series: {
                        type: 'scatter',
                        symbolSize: 20,
                        data: data
                    }
                };

                var chart = testHelper.create(echarts, 'main0', {
                    title: 'The highlight symbol should on the top (not be overlapped)',
                    option: option,
                    info: {
                        brush: option.brush
                    }
                });

                chart && chart.dispatchAction({
                    type: 'brush',
                    areas: [
                        {
                            gridIndex: 0,
                            brushType: 'polygon',
                            coordRange: [[3, 2], [7, 2], [7, 6], [4, 3]]
                        }
                    ]
                });
            });

        </script>







        <script>
        require(['echarts'/*, 'map/js/china' */], function (echarts) {
            var option;

            var testGeoJson1 = {
                'type': 'FeatureCollection',
                'features': [
                    {
                        'geometry': {
                            'type': 'Polygon',
                            'coordinates': [
                                [[2000, 3000], [5000, 3000], [5000, 8000], [2000, 8000]]
                            ]
                        },
                        'properties': {
                            'name': 'Some Area',
                            'childNum': 1
                        }
                    }
                ]
            };
            echarts.registerMap('test1', testGeoJson1);

            var data = [];
            var step = 500;
            var lngStart = 1000;
            var latStart = 2000;
            for (var i = 0; i < 10; i++) {
                for (var j = 0; j < 10; j++) {
                    data.push({
                        value: [lngStart + j * step, latStart + i * step],
                        symbolSize: 5 + j * 5
                    });
                }
            }

            var option = {
                geo: [{
                    map: 'test1',
                    zoom: 4,
                    roam: true
                }],
                brush: {
                    geoIndex: 0
                },
                series: [{
                    type: 'scatter',
                    coordinateSystem: 'geo',
                    symbol: 'roundRect',
                    symbolSize: 30,
                    data: data
                }]
            };

            var chart = testHelper.create(echarts, 'main2', {
                title: [
                    'Test updateTransform: ',
                    'click "保持选择", then brush, then roam the scatter',
                    'the "cover" of the brush should be roamed together with the scatter'
                ],
                option: option
            });
        });
        </script>




    </body>
</html>