
<!--
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() * 10000)]);
                    }
                }
                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() * 10000)]);
                    }
                }
                for (var i = 1; i <= 29; i++) {
                    datas.push([year + '-2-' + i, Math.floor(Math.random() * 10000)]);
                }
                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({
                    title: {
                        top: 30,
                        left: 'center',
                        text: '2016年某人每天的步数',
                        subtext: '数据纯属虚构'
                    },
                    tooltip : {},
                    visualMap: {
                        min: 0,
                        max: 10000,
                        type: 'piecewise',
                        orient: 'horizontal',
                        left: 'center',
                        top: 260,
                        textStyle: {
                            color: '#000'
                        }
                    },
                    calendar: {
                        top: 100,
                        left: 60,
                        range: '2016'
                    },
                    series: {
                        type: 'heatmap',
                        coordinateSystem: 'calendar',
                        data: getVirtulData(2016)
                    }
                });

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