
<!--
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">
        <title>calendar</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="lib/reset.css">
        <script src="lib/esl.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
            }
        </style>
        <div id="main"></div>
        <script>


            var getVirtulData =  function(year) {

                year = year || '2017';

                var datas = [];

                var arr31 = [1, 3, 5, 7, 8, 10, 12];
                var arr30 = [4, 6, 9, 11];
                for (var i = 1; i <= 31; i++) {
                    for (var j = arr31.length - 1; j >= 0; j--) {
                        datas.push([year + '-' + arr31[j] + '-' + i, Math.floor(Math.random() * 1000)]);
                    }
                }
                for (var i = 1; i <= 30; i++) {
                    for (var j = arr30.length - 1; j >= 0; j--) {
                        datas.push([year + '-' + arr30[j] + '-' + i, Math.floor(Math.random() * 1000)]);
                    }
                }
                for (var i = 1; i <= 29; i++) {
                    datas.push([year + '-2-' + i, Math.floor(Math.random() * 1000)]);
                }
                return datas;
            }
            require([
                'echarts'
                // 'echarts/chart/heatmap',
                // 'echarts/chart/scatter',
                // 'echarts/component/title',
                // 'echarts/component/legend',
                // 'echarts/component/calendar',
                // 'echarts/component/tooltip',
                // 'echarts/component/visualMap'
            ], function (echarts) {

                var chart = echarts.init(document.getElementById('main'));

                chart.setOption({
                    tooltip: {
                        position: 'top'
                    },
                    visualMap: {
                        min: 0,
                        max: 1000,
                        calculable: true,
                        orient: 'horizontal',
                        left: 'center',
                        top: 'top'
                    },

                    calendar: [
                    {
                        dayLabel: {
                            position: 'start'
                        },
                        range: '2017-01'
                    },
                    {
                        dayLabel: {
                            position: 'end'
                        },
                        left: 300,
                        range: '2017-02'
                    },
                    {
                        dayLabel: {
                            position: 'start',
                            nameMap: 'cn'
                        },
                        left: 550,
                        range: '2017-03'
                    },
                    {
                        dayLabel: {
                            firstDay: 1,
                            nameMap: 'cn'
                        },
                        left: 750,
                        range: '2017-04'
                    },

                    {
                        dayLabel: {
                            position: 'start'
                        },
                        top: 320,
                        orient: 'vertical',
                        range: '2017-01'
                    },
                    {
                        dayLabel: {
                            position: 'end'
                        },
                        top: 320,
                        left: 300,
                        orient: 'vertical',
                        range: '2017-02'
                    },
                    {
                        dayLabel: {
                            position: 'start',
                            nameMap: ['7', '一', '', '三', '4', 'Fri', '']
                        },
                        top: 320,
                        orient: 'vertical',
                        left: 550,
                        range: '2017-03'
                    },
                    {
                        yearLabel: {
                            margin: 0
                        },
                        dayLabel: {
                            margin: 10,
                            position: 'end',
                            nameMap: 'cn',
                            firstDay: 1
                        },
                        top: 320,
                        orient: 'vertical',
                        left: 750,
                        range: '2017-04'
                    },
                    {
                        yearLabel: {
                            margin: 10
                        },
                        dayLabel: {
                            margin: 20,
                            position: 'end',
                            textStyle: {
                                color: '#009688',
                                fontStyle: 'italic',
                                fontFamily: 'sans-serif',
                                fontWeight: 'bolder',
                                fontSize: 20
                            }
                        },
                        orient: 'vertical',
                        left: 1000,
                        range: ['2017-12-01', '2018-01-31']
                    },
                    {
                        dayLabel: {
                            firstDay: 1
                        },
                        top: 500,
                        range: '2017'
                    }],

                    series: [{
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 0,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 1,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 2,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 3,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 4,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 5,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 6,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 7,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 8,
                        data: getVirtulData(2017)
                    }, {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        calendarIndex: 9,
                        data: getVirtulData(2017)
                    }]

                });

                $(window).resize(function() {
                    chart.resize();
                });
            });
        </script>
    </body>
</html>
