<!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">
        <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>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="lib/reset.css">
    </head>
    <body>
        <style>
            h1 {
                line-height: 60px;
                height: 60px;
                background: #146402;
                text-align: center;
                font-weight: bold;
                color: #eee;
                font-size: 14px;
            }
            #main {
                width: 100%;
                height: 600px;
            }
        </style>

        宽度大于600时显示方块，当前宽度：<span id='wid'></span>
        <div id="main"></div>



        <script>

            var echarts;
            var chart;
            var myChart;
            var groupCategories = [];
            var groupColors = [];

            require([
                'echarts'
            ], function (ec) {
                echarts = ec;

                var option = {
                    graphic: {
                        id: 'text1',
                        type: 'rect',
                        shape: {
                            x: 0,
                            y: 0,
                            width: 100,
                            height: 100,
                        },
                        style: {
                            fill: 'red'
                        }
                    }
                };

                var myChart = echarts.init(document.getElementById('main'));
                myChart.setOption(option);

                setTimeout(function () {
                    // 删除上例中定义的 'text1' 元素。
                    myChart.setOption({
                        graphic: {
                            id: 'text1',
                            $action: 'remove'
                        }
                    });
                    // 已经删除，此步应无效。
                    // myChart.setOption({
                    //     graphic: {
                    //         id: 'text1',
                    //         $action: 'remove'
                    //     }
                    // });
                    // 删除后再添加。
                    myChart.setOption({
                        graphic: {
                            id: 'text1',
                            type: 'rect',
                            shape: {
                                x:0,
                                y:0,
                                width: 100,
                                height: 100,
                            },
                            style: {
                                fill: 'red',
                            }
                        }
                    });
                }, 1000);


                document.getElementById('wid').innerText = window.innerWidth;

                var hasRect;

                window.onresize = function() {
                    document.getElementById('wid').innerText = window.innerWidth;
                    // var option = myChart.getOption();
                    var option = {};

                    if (window.innerWidth < 600) {
                        if (hasRect) {
                            option.graphic = { // 删除上例中定义的 'text1' 元素。
                                id: 'text1',
                                $action: 'remove'
                            }
                            hasRect = false;
                        }
                    }
                    else {
                        option.graphic = {
                            id: 'text1',
                            type: 'rect',
                            shape: {
                                x:0,
                                y:0,
                                width: 100,
                                height: 100,
                            },
                            style: {
                                fill: 'red',
                            }
                        };
                        hasRect = true;
                    }

                    myChart.setOption(option);
                }

                // window.onresize();

            });

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