
<!--
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/esl.js"></script>
        <script src="./lib/config.js"></script>
        <link rel="stylesheet" href="./lib/reset.css">
    </head>
    <body>
        <style>
            #main {
                width: 766px;
                height: 688px;
            }
        </style>
        <div id="main"></div>

        <script>

            // Schema:
            // date,AQIindex,PM2.5,PM10,CO,NO2,SO2
            var schema = [
                {name: 'date', index: 0, text: '日期'},
                {name: 'AQIindex', index: 1, text: 'AQI指数'},
                {name: 'PM25', index: 2, text: 'PM2.5'},
                {name: 'PM10', index: 3, text: 'PM10'},
                {name: 'CO', index: 4, text: '一氧化碳 (CO)'},
                {name: 'NO2', index: 5, text: '二氧化氮 (NO2)'},
                {name: 'SO2', index: 6, text: '二氧化硫 (SO2)'},
                {name: '等级', index: 7, text: '等级'}
            ];

            require([
                'data/aqi/BJdata',
                'data/aqi/GZdata',
                'data/aqi/SHdata',
                // 'zrender/core/util',
                'echarts'
                // 'echarts/chart/parallel',
                // 'echarts/component/legend',
                // 'echarts/component/tooltip',
                // 'echarts/component/visualMap',
                // 'echarts/component/parallel',
            ], function (dataBJ, dataGZ, dataSH, echarts) {
                var zrUtil = echarts.util;

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

                var lineStyle = {
                    normal: {
                        width: 1
                        // opacity: 0.5,
                        // shadowBlur: 10,
                        // shadowOffsetX: 0,
                        // shadowOffsetY: 0,
                        // shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                };

                chart.setOption({
                    animation: true,
                    legend: {
                        bottom: 30,
                        data: ['北京', '上海', '广州'],
                        itemGap: 20,
                        textStyle: {
                            // color: '#fff',
                            fontSize: 16
                        }
                    },
                    tooltip: {
                        padding: 10,
                        backgroundColor: '#222',
                        borderColor: '#777',
                        borderWidth: 1,
                        formatter: function (obj) {
                            var value = obj[0].value;
                            return '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">'
                                + obj[0].seriesName + ' ' + value[0] + '日期：'
                                + value[7]
                                + '</div>'
                                + schema[1].text + '：' + value[1] + '<br>'
                                + schema[2].text + '：' + value[2] + '<br>'
                                + schema[3].text + '：' + value[3] + '<br>'
                                + schema[4].text + '：' + value[4] + '<br>'
                                + schema[5].text + '：' + value[5] + '<br>'
                                + schema[6].text + '：' + value[6] + '<br>';
                        }
                    },
                    // visualMap: {
                    //     show: true,
                    //     min: 0,
                    //     max: 150,
                    //     dimension: 2,
                    //     inRange: {
                    //         color: ['#d94e5d','#eac736','#50a3ba'].reverse()
                    //     },
                    //     outOfRange: {
                    //         color: ['#ccc'],
                    //         opacity: 0.001
                    //     }
                    // },
                    // dataZoom: {
                    //     show: true,
                    //     orient: 'vertical',
                    //     parallelAxisIndex: [0]
                    // },
                    parallelAxis: [
                        {dim: 0, name: schema[0].text, inverse: true, max: 31, nameLocation: 'end'},
                        {dim: 1, name: schema[1].text},
                        {dim: 2, name: schema[2].text},
                        {dim: 3, name: schema[3].text},
                        {dim: 4, name: schema[4].text},
                        {dim: 5, name: schema[5].text},
                        {dim: 6, name: schema[6].text},
                        {dim: 7, name: schema[7].text,
                        type: 'category', data: ['优', '良', '轻度污染', '中度污染', '重度污染', '严重污染']}
                    ],
                    parallel: {
                        bottom: 100,
                        parallelAxisDefault: {
                            type: 'value',
                            name: 'AQI指数',
                            nameLocation: 'end',
                            nameGap: 20,
                            tooltip: {
                                show: true
                            },
                            nameTextStyle: {
                                // color: '#fff',
                                fontSize: 14
                            },
                            axisLine: {
                                lineStyle: {
                                    // color: '#aaa'
                                }
                            },
                            axisTick: {
                                lineStyle: {
                                    // color: '#777'
                                }
                            },
                            splitLine: {
                                show: false
                            },
                            axisLabel: {
                                textStyle: {
                                    // color: '#fff'
                                }
                            }
                        }
                    },
                    series: [{
                        type: 'parallel',
                        data: [
                            {
                                'value': ['韶关','63.37','38.41','72.15','57.33','84.56','82.66'],
                                'lineStyle': {
                                    'normal': {
                                        'color': 'green',
                                        width: 10,
                                        opacity: 1
                                    }
                                }
                            },
                            {'value': ['湛江','31.42','99.18','44.09','3.62','5.65','63.37']}
                        ]
                    }]
                });


                chart.on('axisAreaSelected', function (event) {

                    var indices = chart.getModel().getSeries()[0].getRawIndicesByActiveState('active');
                    console.log('北京: ', indices);

                });
            });

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