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

            require([
                'echarts'
                // 'echarts/chart/heatmap',
                // 'echarts/chart/pie',
                // 'echarts/chart/scatter',
                // 'echarts/chart/effectScatter',
                // 'echarts/chart/graph',
                // 'echarts/component/title',
                // 'echarts/component/legend',
                // 'echarts/component/calendar',
                // 'echarts/component/tooltip'
            ], function (echarts) {

                var chart = echarts.init(document.getElementById('main'));
                var cellSize = [120, 120];

                function getVirtulData() {
                    var date = +echarts.number.parseDate('2017-02-01');
                    var end = +echarts.number.parseDate('2017-03-01');
                    var dayTime = 3600 * 24 * 1000;
                    var data = [];
                    for (var time = date; time < end; time += dayTime) {
                        data.push([
                            echarts.format.formatTime('yyyy-MM-dd', time),
                            Math.floor(Math.random() * 10000)
                        ]);
                    }
                    return data;
                }

                function getPieSeries(scatterData, chart) {
                    return echarts.util.map(scatterData, function (item, index) {
                        var center = chart.convertToPixel('calendar', item);
                        return {
                            id: index + 'pie',
                            type: 'pie',
                            center: center,
                            label: {
                                normal: {
                                    position: 'inside'
                                }
                            },
                            radius: 40,
                            data: [
                                {name: '工作', value: Math.random() * 1000},
                                {name: '娱乐', value: Math.random() * 1000},
                                {name: '睡觉', value: Math.random() * 1000}
                            ]
                        };
                    });
                }

                var scatterData = getVirtulData();

                option = {
                    tooltip : {},
                    legend: {
                        data: ['工作', '娱乐', '睡觉'],
                        bottom: 20
                    },
                    calendar: {
                        top: 'middle',
                        left: 'center',
                        orient: 'vertical',
                        cellSize: cellSize,
                        yearLabel: {
                            show: false,
                            textStyle: {
                                fontSize: 30
                            }
                        },
                        dayLabel: {
                            margin: 20,
                            firstDay: 1,
                            nameMap: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
                        },
                        monthLabel: {
                            show: false
                        },
                        range: ['2017-02']
                    },
                    series: [{
                        id: 'label',
                        type: 'scatter',
                        coordinateSystem: 'calendar',
                        symbolSize: 1,
                        label: {
                            normal: {
                                show: true,
                                formatter: function (params) {
                                    return echarts.format.formatTime('dd', params.value[0]);
                                },
                                offset: [-cellSize[0] / 2 + 10, -cellSize[1] / 2 + 10],
                                textStyle: {
                                    color: '#000',
                                    fontSize: 14
                                }
                            }
                        },
                        data: scatterData
                    }]
                };

                chart.setOption(option);

                chart.setOption({
                    series: getPieSeries(scatterData, chart)
                });

                $(window).resize(function() {
                    chart.resize();
                });
            });


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