<!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>


        <script>

            var chart;
            var myChart;
            var option;

            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;
                }

                chart = myChart = 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>
    </body>
</html>