<!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/simpleRequire.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>
        <div id="main3"></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>

        <script>
        require(['echarts'/*, 'map/js/china' */], function (echarts) {
            var option = {
                xAxis: {
                    type: 'category',
                    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                },
                yAxis: {
                    type: 'value'
                },
                series: [{
                    data: [120, 200, 150, 80, 70, 110, 130],
                    type: 'bar'
                }],
                toolbox: {
                    feature: {
                        dataZoom: {
                            yAxisIndex: false,
                            filterMode: 'weakFilter'
                        }
                    }
                }
            };

            var chart = testHelper.create(echarts, 'main3', {
                title: [
                    'Test brush to end: ',
                    'click "区域缩放", brush from the fourth bar to end of chart',
                    'The number of selected bar should be 4'
                ],
                option: option
            });
        });
        </script>




    </body>
</html>