
<!--
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/simpleRequire.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',
                'echarts'
            ], 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>