
<!--
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>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                /*border: 1px solid #000;*/
            }
        </style>
        <div id="main"><div>
        <script>
            require(['echarts'], function (echarts) {

                var chart = echarts.init(document.getElementById('main'), null, {});

                window.onresize = function () {
                    chart.resize();
                };

                let arr1 = [1000000, 630000, 900000, 1250000, 1954000, 2192000, 1835000, 1789000, 2393000, 1750000, 2400000, 2500000];
                let arr2 = [1123180.15, 655552.2, 1347675.87, 1481906.4, 3866326.82, 3147657.91, 2432494.66, 1782080.1, 969800];

                let budget = [0];
                let realIncome = [0];

                for (let i = 0; i < 12; i++) {
                    let tmp = arr1[i] || NaN;
                    tmp = parseFloat((tmp / 10000).toFixed(1));
                    budget.push(tmp + budget[i]);
                }
                for (let i = 0; i < 12; i++) {
                    let tmp = arr2[i] || NaN;
                    tmp = parseFloat((tmp / 10000).toFixed(1));
                    realIncome.push(tmp + realIncome[i]);
                }
                budget = budget.slice(1);
                realIncome = realIncome.slice(1);

                chart.setOption({
                    title: {
                        text: 'When resize the window the width of two markLines should be same',
                    },
                    tooltip: {
                        trigger: 'axis'
                    },
                    legend: {
                        data: ['预算收入', '实际收入']
                    },
                    animation: false,
                    toolbox: {
                        show: true,
                        feature: {
                            dataView: {
                                show: true,
                                readOnly: false
                            },
                            magicType: {
                                show: true,
                                type: ['line', 'bar']
                            },
                            restore: {
                                show: true
                            },
                            saveAsImage: {
                                show: true
                            }
                        }
                    },
                    calculable: true,
                    xAxis: [{
                        type: 'category',
                        splitLine: {
                            show: false
                        },
                        data: function() {
                            var list = [];
                            for (var i = 1; i <= 12; i++) {
                                list.push(i + '月');
                            }
                            return list;
                        }()
                    }],
                    yAxis: [{
                        type: 'value'
                    }],
                    series: [{
                            name: '预算收入',
                            type: 'line',
                            data: budget,
                            markLine: {
                                data: [{
                                    type: 'average',
                                    name: '平均值'
                                }],
                                lineStyle: {
                                    normal: {
                                        color: 'black',
                                        type: 'solid',
                                        width: 1
                                    },
                                },
                            }
                        },
                        {
                            name: '实际收入',
                            type: 'line',
                            data: realIncome,
                            markLine: {
                                lineStyle: {
                                    normal: {
                                        type: 'solid',
                                        width: 1,
                                        color: 'black'
                                    },
                                },
                                data: [{
                                    type: 'average',
                                    name: '平均值'
                                }]
                            }
                        }
                    ]
                })
            });
        </script>
    </body>
</html>