<!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="main0"></div>
        <div id="main1"></div>


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

                // See <https://github.com/ecomfe/echarts/issues/6202>
                // Thanks to <https://github.com/JeffreyRoosendaal>

                var seriesMap = {

                    '6series': [
                        {
                            "name": "Smartphone",
                            "type": "bar",
                            "stack": "metric",
                            "data": [185, 89, 8, 0]
                        },
                        {
                            "name": "Desktop",
                            "type": "bar",
                            "stack": "metric",
                            "data": [104, 51, 9, 1]
                        },
                        {
                            "name": "Tablet",
                            "type": "bar",
                            "stack": "metric",
                            "data": [38, 25, 4, 0]
                        },
                        {
                            "name": "Motorola",
                            "type": "bar",
                            "stack": "metric",
                            "data": [18, 75, 11, 4]
                        },
                        {
                            "name": "Huawei",
                            "type": "bar",
                            "stack": "metric",
                            "data": [21, 15, 61, 14]
                        },
                        {
                            "name": "Overig",
                            "type": "bar",
                            "stack": "metric",
                            "data": [12, 33, 21, 3]
                        }
                    ],

                    '3series': [
                        {
                            "name": "Smartphone",
                            "type": "bar",
                            "stack": "metric",
                            "data": [185, 89, 8, 0]
                        },
                        {
                            "name": "Desktop",
                            "type": "bar",
                            "stack": "metric",
                            "data": [104, 51, 9, 1]
                        },
                        {
                            "name": "Tablet",
                            "type": "bar",
                            "stack": "metric",
                            "data": [38, 25, 4, 0]
                        }
                    ]
                };

                function createOption(name) {
                    var option = {
                        legend: {},
                        dataZoom: [{
                            type: 'slider'
                        }, {
                            type: 'inside'
                        }],
                        "xAxis": {
                            "data": [ "Bezoeken", "Actief", "Winkelwagens", "Bestellingen"]
                        },
                        "yAxis": {
                        },
                        "series": seriesMap[name]
                    };
                    return option;
                }

                var chart = testHelper.create(echarts, 'main0', {
                    title: 'Click the two buttons. Animation should be appropriate, and dataZoom state should be kept.',
                    option: createOption('3series'),
                    buttons: Object.keys(seriesMap).map(function (name) {
                        return {
                            text: 'setOption: ' + name + ' with notMerge mode' ,
                            onClick: function () {
                                chart.setOption(createOption(name), {
                                    notMerge: true
                                });
                            }
                        };
                    })
                });


            });

        </script>

        <script>
            require([
                'echarts'/*, 'map/js/china' */
            ], function (echarts) {
                var option;
                option = {
                    xAxis: {
                        type: 'category',
                        boundaryGap: false,
                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [
                        {
                        data: [820, 932, 901, 934, 1290, 1330, 1320],
                        type: 'line',
                        areaStyle: {}
                        }
                    ]
                };
                var chart = testHelper.create(echarts, 'main1', {
                    title: 'The area polygon should be removed after the button is clicked',
                    option: option,
                    buttons: {
                        text: 'setOption: with notMerge mode' ,
                        onClick: function () {
                            option.series.map(s => {
                                s.step = 'end';
                                delete s.areaStyle;
                            });
                            chart.setOption(option, { notMerge: true });
                        }
                    }
                })
            });
        </script>
    </body>
</html>
