From af9fa5a094ca652293a890f06634b59c955e1067 Mon Sep 17 00:00:00 2001
From: fengxiang <110431245@qq.com>
Date: Mon, 30 Jul 2018 09:06:15 +0800
Subject: [PATCH] token刷新

---
 src/app/delon.module.ts                                     |    3 
 src/app/routes/home-page/home-page/home-page.component.ts   |  768 ++++++++++++++++++++++++++++++--------
 src/app/routes/statistics/calendar/calendar.component.ts    |   32 +
 src/app/routes/statistics/statistics.module.ts              |    2 
 src/app/routes/statistics/calendar/calendar.component.html  |   19 
 src/app/app.component.ts                                    |    2 
 src/app/routes/home-page/home-page/home-page.component.html |  346 ++++++++---------
 7 files changed, 816 insertions(+), 356 deletions(-)

diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 105c1b4..9a6c04d 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -29,7 +29,7 @@
   ngOnInit() {
     // ������Token������
     this.tokenService.set({
-      token: 'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsIm9pZCI6NSwibW9kZSI6IldlYiIsInNjb3BlcyI6WyJ0ZW1wIl0sImlzcyI6Imh0dHA6Ly9tb25pdG9yLjdkcmxiLmNvbSIsImlhdCI6MTUzMTQ0ODcwMCwiZXhwIjoxNTMyNzQ0NzAwfQ.a2o1-bruQKjgvYDkA4fdhDmqpwJSbqdlKmK5spz5bk_15VvP0TN1rl1j8nQD7bJxgFQerVT3iouYVBXf3zN67A',
+      token: 'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsIm9pZCI6NSwibW9kZSI6IldlYiIsInNjb3BlcyI6WyJ0ZW1wIl0sImlzcyI6Imh0dHA6Ly9tb25pdG9yLjdkcmxiLmNvbSIsImlhdCI6MTUzMjkxMjY2OSwiZXhwIjoxNTQwNjg4NjY5fQ.nhD_CI4Dd6mU0xWoXlp4qU6yW_P9mjBEWXcidKOujtNelbQF4imVWbleo0tKgYOUWjrYNFjq7neufGYPQW1zrQ',
       name: 'admin',
       email: `admin@qq.com`,
       id: 10000,
diff --git a/src/app/delon.module.ts b/src/app/delon.module.ts
index a0a5c48..b9c5bfd 100644
--- a/src/app/delon.module.ts
+++ b/src/app/delon.module.ts
@@ -181,7 +181,8 @@
 // const MOCKMODULE = !environment.production || environment.chore === true ?
 //                     [ DelonMockModule.forRoot({ data: MOCKDATA }) ] : [];
 // ������ ������ ������ ������mock
-const MOCKMODULE = [ DelonMockModule.forRoot({ data: MOCKDATA }) ];
+const MOCKMODULE = [ DelonMockModule.forRoot({ data: MOCKDATA,
+force: false}) ];
 
 // region: global config functions
 
diff --git a/src/app/routes/home-page/home-page/home-page.component.html b/src/app/routes/home-page/home-page/home-page.component.html
index a503f58..612f176 100644
--- a/src/app/routes/home-page/home-page/home-page.component.html
+++ b/src/app/routes/home-page/home-page/home-page.component.html
@@ -3,36 +3,45 @@
 </div>
 <div nz-row [nzGutter]="24" class="pt-lg">
     <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
-        <div nz-row nzType="flex" nzAlign="middle" class="bg-primary rounded-md">
-            <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
-                <div style="height: 40px;" class="h2 mt0">{{ cardData.api }}</div>
-                <p class="text-nowrap mb0">AQI</p>
+        <nz-spin [nzSpinning]="firstRowLoading">
+            <div nz-row nzType="flex" nzAlign="middle" class="bg-primary rounded-md">
+                <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
+                    <div style="height: 40px;" class="h2 mt0">{{ cardData.aqi }}</div>
+                    <p class="text-nowrap mb0">AQI</p>
+                </div>
+
             </div>
-        </div>
+        </nz-spin>
     </div>
     <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
-        <div nz-row nzType="flex" nzAlign="middle" class="bg-success rounded-md">
-            <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
-                <div style="height: 40px;" class="h2 mt0">{{ cardData.temperature }} ���</div>
-                <p class="text-nowrap mb0">������</p>
+        <nz-spin [nzSpinning]="firstRowLoading">
+            <div nz-row nzType="flex" nzAlign="middle" class="bg-success rounded-md">
+                <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
+                    <div style="height: 40px;" class="h2 mt0">{{ cardData.temperature }} ���</div>
+                    <p class="text-nowrap mb0">������</p>
+                </div>
             </div>
-        </div>
+        </nz-spin>
     </div>
     <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
-        <div nz-row nzType="flex" nzAlign="middle" class="bg-orange rounded-md">
-            <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
-                <div style="height: 40px;" class="h2 mt0">{{ cardData.windDirection }}</div>
-                <p class="text-nowrap mb0">������</p>
+        <nz-spin [nzSpinning]="firstRowLoading">
+            <div nz-row nzType="flex" nzAlign="middle" class="bg-orange rounded-md">
+                <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
+                    <div style="height: 40px;" class="h2 mt0">{{ cardData.windDirection }}</div>
+                    <p class="text-nowrap mb0">������</p>
+                </div>
             </div>
-        </div>
+        </nz-spin>
     </div>
     <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
-        <div nz-row nzType="flex" nzAlign="middle" class="bg-pink rounded-md">
-            <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
-                <div style="height: 40px;" class="h2 mt0">{{ cardData.pm25 }} mg/m��</div>
-                <p class="text-nowrap">PM2.5</p>
+        <nz-spin [nzSpinning]="firstRowLoading">
+            <div nz-row nzType="flex" nzAlign="middle" class="bg-pink rounded-md">
+                <div nz-col nzSpan="24" class="p-md text-white" style="height: 90px;text-align: center;">
+                    <div style="height: 40px;" class="h2 mt0">{{ cardData.pm25 }} mg/m��</div>
+                    <p class="text-nowrap">PM2.5</p>
+                </div>
             </div>
-        </div>
+        </nz-spin>
     </div>
 </div>
 <div nz-row [nzGutter]="24" class="pt-lg">
@@ -56,31 +65,24 @@
     <div nz-col nzXs="24" nzMd="24">
         <nz-card [nzBordered]="false">
             <ng-template #title>
-                AQI��������������� &nbsp;
+                AQI���������������(������24������) &nbsp;
                 <nz-dropdown>
                     <a class="ant-dropdown-link" nz-dropdown>
-                     PM2.5 <i class="anticon anticon-down"></i>
+                        {{ selectedApiItem.name }}
+                        <i class="anticon anticon-down"></i>
                     </a>
                     <ul nz-menu>
-                      <li nz-menu-item>
-                        PM10
-                      </li>
-                      <li nz-menu-item>
-                        ������������
-                      </li>
-                      <li nz-menu-item>
-                        ������������
-                      </li>
-                      <li nz-menu-item>
-                        ������������
-                      </li>
-                      <li nz-menu-item>
-                        ������
-                      </li>
+                        <li *ngFor="let item of aqiItems" [ngClass]="{'ant-dropdown-menu-item-selected':item.selected}" 
+                            (click) ="setSelectedApiItem(item)" nz-menu-item>
+                            {{ item.name }}
+                        </li>
                     </ul>
-                  </nz-dropdown>
+                </nz-dropdown>
             </ng-template>
-            <bar height="275" [data]="salesData"></bar>
+            <nz-spin [nzTip]="'���������...'" [nzSpinning]="aqiDataLoading">   
+                <p class="text-left text-md">������:{{ selectedApiItem.unit }}</p>
+                <bar height="275" [data]="aqiData"></bar>
+            </nz-spin>
         </nz-card>
     </div>
 </div>
@@ -88,152 +90,132 @@
     <div nz-col nzXs="24" nzMd="24">
         <nz-card [nzBordered]="false">
             <ng-template #title>
-               ������������GIS������
-               <small class="text-sm font-weight-normal">������: 128</small>
+                ������������GIS������
+                <small class="text-sm font-weight-normal">������: 128</small>
             </ng-template>
-            <iframe style="width: 100%; height: 500px;" target="_top" src="http://monitor-api2.7drlb.com/screen/map-page?areaCode=320583&accountId=1" frameborder="0"></iframe>
+            <iframe style="width: 100%; height: 500px;" target="_top" src="http://monitor-api2.7drlb.com/screen/map-page?areaCode=320583&accountId=1"
+                frameborder="0"></iframe>
         </nz-card>
     </div>
-  </div>
-  <div nz-row [nzGutter]="24" class="pt-lg">
+</div>
+<div nz-row [nzGutter]="24" class="pt-lg">
     <div nz-col style="display: block;" nzXs="24" nzMd="24">
-       <nz-card [nzBordered]="false">
+        <nz-card [nzBordered]="false">
             <ng-template #title>
-                    ������������������ &nbsp;
-                    <nz-dropdown>
-                        <a class="ant-dropdown-link" nz-dropdown>
-                         PM2.5 <i class="anticon anticon-down"></i>
-                        </a>
-                        <ul nz-menu>
-                          <li nz-menu-item>
-                            PM10
-                          </li>
-                          <li nz-menu-item>
-                            ������������
-                          </li>
-                          <li nz-menu-item>
-                            ������������
-                          </li>
-                          <li nz-menu-item>
-                            ������������
-                          </li>
-                          <li nz-menu-item>
-                            ������
-                          </li>
-                        </ul>
-                      </nz-dropdown>
-                </ng-template>
-            <div echarts style="margin-top: 12px;" class="line-chart" [options]="aqiChartOption" [loading]="aqiChartLoading" (chartInit)="onApiChartInit($event)"></div>
-       </nz-card>
+                ������������������(24������)
+                <nz-dropdown>
+                    <a class="ant-dropdown-link" nz-dropdown>
+                        {{ selectedApiForecastItem.name }}
+                        <i class="anticon anticon-down"></i>
+                    </a>
+                    <ul nz-menu>
+                        <li *ngFor="let item of aqiForecastItems" [ngClass]="{'ant-dropdown-menu-item-selected':item.selected}" 
+                            (click) ="setSelectedApiForecastItem(item)" nz-menu-item>
+                            {{ item.name }}
+                        </li>
+                    </ul>
+                </nz-dropdown>
+            </ng-template>
+            <p class="text-left text-md">������:{{ selectedApiForecastItem.unit }}</p>
+            <div echarts style="margin: 0;height: 300px;" class="line-chart" [options]="aqiChartOption" [loading]="aqiForecastDataLoading" (chartInit)="onApiChartInit($event)"></div>
+        </nz-card>
     </div>
-  </div>
-  <div nz-row [nzGutter]="24" class="pt-lg">
-        <div nz-col style="display: block;" nzXs="24" nzMd="24">
-           <nz-card [nzBordered]="false">
-                <ng-template #title>
-                        ������������ &nbsp;
-                        <nz-dropdown>
-                            <a class="ant-dropdown-link" nz-dropdown>
-                             ������<i class="anticon anticon-down"></i>
-                            </a>
-                            <ul nz-menu>
-                              <li nz-menu-item>
-                                ������
-                              </li>
-                              <li nz-menu-item>
-                                ������
-                              </li>
-                              <li nz-menu-item>
-                                ������
-                              </li>
-                              <li nz-menu-item>
-                                ������
-                              </li>
-                            </ul>
-                          </nz-dropdown>
-                    </ng-template>
-                <div echarts style="margin-top: 12px;" class="line-chart" [options]="meteChartOption" [loading]="meteChartLoading" (chartInit)="onMeteChartInit($event)"></div>
-           </nz-card>
-        </div>
-      </div>
-      <div nz-row [nzGutter]="24">
-            <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="12">
-                <nz-card [nzLoading]="loading" [nzBordered]="false" nzTitle="������������������">
-                    <ng-template #extra>
-                        <nz-dropdown>
-                                <nz-dropdown>
-                                        <a class="ant-dropdown-link" nz-dropdown>
-                                         PM2.5 <i class="anticon anticon-down"></i>
-                                        </a>
-                                        <ul nz-menu>
-                                          <li nz-menu-item>
-                                            PM10
-                                          </li>
-                                          <li nz-menu-item>
-                                            ������������
-                                          </li>
-                                          <li nz-menu-item>
-                                            ������������
-                                          </li>
-                                          <li nz-menu-item>
-                                            ������������
-                                          </li>
-                                          <li nz-menu-item>
-                                            ������
-                                          </li>
-                                        </ul>
-                                      </nz-dropdown>
-                        </nz-dropdown>
-                    </ng-template>
-                    <ng-template #body>
-                        <nz-table #keyTable [nzDataSource]="data.searchData" [nzPageSize]="5" nzSize="small">
-                            <thead nz-thead>
-                                <tr>
-                                    <th nz-th><span>������</span></th>
-                                    <th nz-th><span>������������������</span></th>
-                                    <th nz-th class="text-right">
-                                        <span>������������������</span>
-                                        <nz-table-sort (nzValueChange)="sort('count',$event)"></nz-table-sort>
-                                    </th>
-                                </tr>
-                            </thead>
-                            <tbody nz-tbody>
-                                <tr nz-tbody-tr *ngFor="let i of keyTable.data">
-                                    <td nz-td>{{i.index}}</td>
-                                    <td nz-td><a (click)="msg.success(i.keyword)">{{i.keyword}}</a></td>
-                                    <td nz-td class="text-right">{{i.count}}</td>
-                                </tr>
-                            </tbody>
-                        </nz-table>
-                    </ng-template>
-                </nz-card>
-            </div>
-            <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="12">
-                <nz-card [nzLoading]="loading" [nzBordered]="false" nzTitle="������������������" [nzBodyStyle]="{'padding.px': 24}" class="sales-card" style="min-height: 482px;">
-                    <ng-template #extra>
-                        <div class="sales-card-extra">
-                            <div class="sales-type-radio">
-                                <nz-radio-group [(ngModel)]="salesType" (ngModelChange)="changeSaleType()" [nzSize]="'large'">
-                                    <label nz-radio-button [nzValue]="'all'"><span>������</span></label>
-                                    <label nz-radio-button [nzValue]="'online'"><span>������</span></label>
-                                    <label nz-radio-button [nzValue]="'offline'"><span>������</span></label>
-                                    <label nz-radio-button [nzValue]="'online2'"><span>������</span></label>
-                                </nz-radio-group>
-                            </div>
-                        </div>
-                    </ng-template>
-                    <ng-template #body>
-                        <h4 class="margin:8px 0 32px 0;">������������</h4>
-                        <pie
-                            [hasLegend]="true"
-                            subTitle="������������"
-                            [height]="248"
-                            [lineWidth]="4"
-                            [total]="salesTotal"
-                            [data]="salesPieData"
-                            [valueFormat]="handlePieValueFormat">
-                        </pie>
-                    </ng-template>
-                </nz-card>
-            </div>
-        </div>
+</div>
+<div nz-row [nzGutter]="24" class="pt-lg">
+    <div nz-col style="display: block;" nzXs="24" nzMd="24">
+        <nz-card [nzBordered]="false">
+            <ng-template #title>
+                ������������(24������) &nbsp;
+                <nz-dropdown>
+                    <a class="ant-dropdown-link" nz-dropdown>
+                        {{ selectedMeteItem.name }}
+                        <i class="anticon anticon-down"></i>
+                    </a>
+                    <ul nz-menu>
+                        <li *ngFor="let item of meteItems" [ngClass]="{'ant-dropdown-menu-item-selected':item.selected}" 
+                            (click) ="setSelectedMeteItem(item)" nz-menu-item>
+                            {{ item.name }}
+                        </li>
+                    </ul>
+                </nz-dropdown>
+            </ng-template>
+            <p class="text-left text-md">������:{{ selectedMeteItem.unit }}</p>
+            <div echarts style="margin: 0;height: 300px;" class="line-chart" [options]="meteChartOption" [loading]="meteChartLoading" (chartInit)="onMeteChartInit($event)"></div>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="24">
+    <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="12">
+        <nz-card [nzLoading]="loading" [nzBordered]="false" nzTitle="������������������">
+            <ng-template #extra>
+                <nz-dropdown>
+                    <a class="ant-dropdown-link" nz-dropdown>
+                        {{ selectedApiSortedItem.name }}
+                        <i class="anticon anticon-down"></i>
+                    </a>
+                    <ul nz-menu>
+                        <li *ngFor="let item of apiSortedItems" [ngClass]="{'ant-dropdown-menu-item-selected':item.selected}" 
+                            (click) ="setSelectedApiSortedItem(item)" nz-menu-item>
+                            {{ item.name }}
+                        </li>
+                    </ul>
+                </nz-dropdown>
+            </ng-template>
+            <ng-template #body>
+                <nz-table #keyTable [nzDataSource]="apiSortedTableList" [nzLoading]="apiSortedTableLoading" [nzPageSize]="8" nzSize="small">
+                    <thead nz-thead>
+                        <tr>
+                            <th nz-th>
+                                <span>������</span>
+                            </th>
+                            <th nz-th>
+                                <span>������������������</span>
+                            </th>
+                            <th nz-th class="text-right">
+                                <span>������({{selectedApiSortedItem.unit}})</span>
+                                <nz-table-sort (nzValueChange)="aqiSortedTableSort('sum',$event)"></nz-table-sort>
+                            </th>
+                        </tr>
+                    </thead>
+                    <tbody nz-tbody>
+                        <tr nz-tbody-tr *ngFor="let i of keyTable.data;let j = index">
+                            <td nz-td>{{j + 1}}</td>
+                            <td nz-td><a>{{i.name}}</a></td>
+                            <td nz-td class="text-right">{{i.avg}}</td>
+                        </tr>
+                        </tbody>
+                </nz-table>
+            </ng-template>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="12">
+        <nz-card [nzLoading]="loading" [nzBordered]="false" nzTitle="������������������" [nzBodyStyle]="{'padding.px': 24}" class="sales-card"
+            style="min-height: 482px;">
+            <ng-template #extra>
+                <div class="sales-card-extra">
+                    <div class="sales-type-radio">
+                        <nz-radio-group [(ngModel)]="salesType" (ngModelChange)="changeSaleType()" [nzSize]="'large'">
+                            <label nz-radio-button [nzValue]="'all'">
+                                <span>������</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'online'">
+                                <span>������</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'offline'">
+                                <span>������</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'online2'">
+                                <span>������</span>
+                            </label>
+                        </nz-radio-group>
+                    </div>
+                </div>
+            </ng-template>
+            <ng-template #body>
+                <h4 class="margin:8px 0 32px 0;">������������</h4>
+                <pie [hasLegend]="true" subTitle="������������" [height]="248" [lineWidth]="4" [total]="salesTotal" [data]="salesPieData" [valueFormat]="handlePieValueFormat">
+                </pie>
+            </ng-template>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/home-page/home-page/home-page.component.ts b/src/app/routes/home-page/home-page/home-page.component.ts
index 0535670..e88e860 100644
--- a/src/app/routes/home-page/home-page/home-page.component.ts
+++ b/src/app/routes/home-page/home-page/home-page.component.ts
@@ -1,185 +1,631 @@
 import { Component, OnInit } from "@angular/core";
 import { _HttpClient } from "@delon/theme";
-import { zip } from 'rxjs/observable/zip';
+import { zip } from "rxjs/observable/zip";
+import * as moment from "moment";
+import { ResultBean } from "@business/entity/grid";
 
 @Component({
-  selector: "app-home-page",
-  templateUrl: "./home-page.component.html",
-  styleUrls: ["./home-page.component.less"]
+    selector: "app-home-page",
+    templateUrl: "./home-page.component.html",
+    styleUrls: ["./home-page.component.less"]
 })
 export class HomePageComponent implements OnInit {
-  public cardData: {'api'?:number,'temperature'?:number,'windDirection'?: string,'pm25'?: number} = {};
+    // ������ ������������������������
+    constructor(private http: _HttpClient) {
+        this.reloadAqiChart();
+        this.reloadMeteChart();
+    }
+    salesData: any[] = [];
+    aqiData: any[] = [];
+    ngOnInit() {
+        zip(
+            this.http.get<any>(
+                "http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=condition"
+            ),
+            this.http.get<any>(
+                "http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=aqi"
+            )
+        ).subscribe(([conRes, aqiRes]) => {
+            if (conRes.code == 0 && aqiRes.code == 0) {
+                this.cardData.windDirection = conRes.data.condition.windDir;
+                this.cardData.temperature = conRes.data.condition.temp;
+                this.cardData.aqi = aqiRes.data.aqi.value;
+                this.cardData.pm25 = aqiRes.data.aqi.pm25;
+                setTimeout(() => {
+                    this.firstRowLoading = false;
+                }, 500);
+            }
+        });
 
-  constructor(
-    private http:_HttpClient,
-  ) {
-     this.reloadAqiChart();
-     this.reloadMeteChart()
-  }
-  salesData: any[] =  [ ];
-  ngOnInit() {
-    zip(
-       this.http.get<any>('http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=condition'),
-       this.http.get<any>('http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=aqi')
+        this.http.get("/chart").subscribe((res: any) => {
+            res.offlineData.forEach((item: any) => {
+                item.chart = Object.assign([], res.offlineChartData);
+            });
+            this.data = res;
+            this.salesData = res.salesData;
+            this.loading = false;
+            this.changeSaleType();
+        });
+        this.setSelectedApiItem();
+        this.setSelectedApiForecastItem();
+        this.setSelectedMeteItem();
+        this.setSelectedApiSortedItem();
+    }
 
-     ).subscribe(
-        ([conRes,aqiRes]) => {
-          if( conRes.code == 0 && aqiRes.code == 0 ) {
-            this.cardData.windDirection = conRes.data.condition.windDir;
-            this.cardData.temperature = conRes.data.condition.temp;
-            this.cardData.api = aqiRes.data.aqi.value;
-            this.cardData.pm25 = aqiRes.data.aqi.pm25;
-            this.http.get('/aqi/forecast24hours',{base: this.cardData.pm25,range: 10}).subscribe(
-                (res: any) => {
-                    this.aqiEchartsIntance.setOption(
-                        {
-                           series: [{type: 'line', data: res}]
+    // ---------------- ������������������ -----------------------------------
+    public cardData: {
+        aqi?: number;
+        temperature?: number;
+        windDirection?: string;
+        pm25?: number;
+    } = {};
+    public firstRowLoading = true;
+    // ---------------- AQI���������������(������24������) --------------------------
+    public aqiDataLoading = true;
+    public aqiItems = [
+        {
+            name: "PM2.5",
+            key: "e1",
+            unit: "ug/m��",
+            selected: true
+        },
+        {
+            name: "PM10",
+            key: "e2",
+            unit: "ug/m��",
+            selected: false
+        },
+        {
+            name: "������������",
+            key: "e10",
+            unit: "mg/m��",
+            selected: false
+        },
+        {
+            name: "������������",
+            key: "e11",
+            unit: "ug/m��",
+            selected: false
+        },
+        {
+            name: "������",
+            key: "e15",
+            unit: "ug/m��",
+            selected: false
+        },
+        {
+            name: "������������",
+            key: "e16",
+            unit: "ug/m��",
+            selected: false
+        }
+    ];
+    public get selectedApiItem() {
+        return this.aqiItems.find(item => {
+            return !!item.selected;
+        });
+    }
+    public setSelectedApiItem(item?: any) {
+        if (!!item) {
+            this.aqiItems.forEach(it => {
+                if (item.key === it.key) {
+                    it.selected = true;
+                } else {
+                    it.selected = false;
+                }
+            });
+        }
+        let dValue = 24;
+        const startTime: Date = moment()
+            .subtract(1, "days")
+            .subtract(dValue, "hours")
+            .toDate();
+        const endTime: Date = moment()
+            .subtract(1, "days")
+            .toDate();
+        const key = this.selectedApiItem.key;
+        const lineChartCriteria = {
+            dataConditions: [
+                {
+                    areaRangeId: 320583,
+                    areaRange: 2,
+                    deviceDimension: "NONE",
+                    actualTime: null,
+                    timeUnits: "HOUR"
+                }
+            ],
+            sensorKeys: [key],
+            timePeriod: {
+                startTime: startTime,
+                endTime: endTime,
+                timeUnits: "HOUR"
+            }
+        };
+        this.aqiDataLoading = true;
+        this.http
+            .post("/report/line-chart", lineChartCriteria)
+            .subscribe(
+                (res: ResultBean<{ [key: string]: Array<Array<number>> }>) => {
+                    const data = res.data[key][0];
+                    if (!!data && data.length > 0) {
+                        const mo = moment(startTime);
+                        const aqiData = [];
+                        for (
+                            let index = 0, num = 0;
+                            index < dValue;
+                            index++, num = 1
+                        ) {
+                            aqiData.push({
+                                x: mo.add(num, "hours").hours() + "���",
+                                y: data[index]
+                            });
                         }
-                    )
+                        this.aqiData = aqiData;
+                        this.aqiDataLoading = false;
+                    }
+                    console.log(this.aqiData);
                 }
             );
-            this.http.get('/aqi/forecast24hours',{base: this.cardData.temperature,range: 5}).subscribe(
-               (res: any) => {
-                   this.meteEchartsIntance.setOption(
-                       {
-                          series: [{type: 'line', data: res}]
-                       }
-                   )
-               }
-           );
-          }
-        }
-     );
-     this.http.get('/chart').subscribe((res: any) => {
-        res.offlineData.forEach((item: any) => {
-            item.chart = Object.assign([], res.offlineChartData);
-        });
-        this.data = res;
-        this.salesData = res.salesData;
-        this.loading = false;
-        this.changeSaleType();
-    });
-
-  }
-
-  public aqiChartOption = {};
-  public aqiEchartsIntance;
-  public aqiChartLoading = false;
-  public onApiChartInit(e): void {
-        this.aqiEchartsIntance = e;
-  }
-  public meteChartOption = {};
-  public meteEchartsIntance;
-  public meteChartLoading = false;
-  public onMeteChartInit(e): void {
-      this.meteEchartsIntance = e;
-  }
-  private reloadAqiChart(): void {
-    // const  timeList = this.grid.columns.map(item => item.text);
-     if (!!this.aqiEchartsIntance) {
-         this.aqiChartOption = null;
-         this.aqiEchartsIntance.clear();
-     }
-    //  let series = null;
-    //  if ( this.chartSelectedIndex < this.grid.data.length ) {
-    //     series = [{type: 'line', data: this.grid.data[this.chartSelectedIndex]}];
-    //  }
-
-    //  this.initOpton(chartOption ,{ xAxis : [{data : []}]});
-    //  this.aqiChartOption = true;
-    this.initOpton(this.aqiChartOption ,{ xAxis : [{data : this.newArray(0, 24, null, '���')}]});
-  }
-  private reloadMeteChart(): void {
-     if (!!this.aqiEchartsIntance) {
-         this.aqiChartOption = null;
-         this.aqiEchartsIntance.clear();
-     }
-    this.initOpton(this.meteChartOption ,{ xAxis : [{data : this.newArray(0, 24, null, '���')}]});
-  }
-  private newArray = (startOrLen: number, len?: number, prefix?: string, suffix?: string) => {
-    const result = [];
-    const s = !!len ? startOrLen : 0;
-    len = !!len ? len : startOrLen;
-    suffix = !!suffix ? suffix : '';
-    prefix = !!prefix ? prefix :  '';
-    for (let i = s; result.length < len; i++) {
-        result.push(prefix + i + suffix);
     }
-    return result;
-}
-  private initOpton(chartOption,opt: {[key: string]: object}) {
-     const defaultOption = {
-        title: {
-            left: 'center'
+    // ----------- ������������������(24������) ----------------------------
+    public aqiChartOption = {};
+    public aqiEchartsIntance;
+    public aqiForecastDataLoading = true;
+    public aqiForecastItems = [
+        {
+            name: "PM2.5",
+            key: "e1",
+            unit: "ug/m��",
+            selected: true
         },
-        tooltip : {
-            trigger: 'axis',
-            axisPointer: {
-                type: 'cross',
-                label: {
-                    backgroundColor: '#6a7985'
-                }
-            }
+        {
+            name: "PM10",
+            key: "e2",
+            unit: "ug/m��",
+            selected: false
         },
-        legend: {
-            data: []
+        {
+            name: "������������",
+            key: "e10",
+            unit: "mg/m��",
+            selected: false
         },
-        toolbox: {
-            feature: {
-                saveAsImage: {}
-            }
+        {
+            name: "������������",
+            key: "e11",
+            unit: "ug/m��",
+            selected: false
         },
-        grid: {
-            left: '3%',
-            right: '4%',
-            bottom: '3%',
-            containLabel: true
+        {
+            name: "������",
+            key: "e15",
+            unit: "ug/m��",
+            selected: false
         },
-        xAxis : [
-            {
-                type : 'category',
-                boundaryGap : false
-            }
-        ],
-        yAxis : [
-            {
-                type : 'value'
-            }
-        ],
-        series : [
-        ]
-    };
-    Object.assign( defaultOption, opt);
-    Object.assign(chartOption, defaultOption);
-  }
-  //---------mock-------------------
-  data: any = {
-    salesData: [],
-    offlineData: []
-  };
-  sort(sortName, sortValue) {
-    this.data.searchData = [
-        ...(<any[]>this.data.searchData).sort((a, b) => {
-            if (a[ sortName ] > b[ sortName ]) {
-                return (sortValue === 'ascend') ? 1 : -1;
-            } else if (a[ sortName ] < b[ sortName ]) {
-                return (sortValue === 'ascend') ? -1 : 1;
-            } else {
-                return 0;
-            }
-        })
+        {
+            name: "������������",
+            key: "e16",
+            unit: "ug/m��",
+            selected: false
+        }
     ];
-  }
+    public onApiChartInit(e): void {
+        this.aqiEchartsIntance = e;
+    }
+    public get selectedApiForecastItem() {
+        return this.aqiForecastItems.find(item => {
+            return !!item.selected;
+        });
+    }
+    public setSelectedApiForecastItem(item?: any) {
+        if (!!item) {
+            this.aqiForecastItems.forEach(it => {
+                if (item.key === it.key) {
+                    it.selected = true;
+                } else {
+                    it.selected = false;
+                }
+            });
+        }
+        let dValue = 24;
+        const startTime: Date = moment()
+            .subtract(2, "days")
+            .subtract(dValue, "hours")
+            .toDate();
+        const endTime: Date = moment()
+            .subtract(2, "days")
+            .toDate();
+        const key = this.selectedApiForecastItem.key;
+        const lineChartCriteria = {
+            dataConditions: [
+                {
+                    areaRangeId: 320583,
+                    areaRange: 2,
+                    deviceDimension: "NONE",
+                    actualTime: null,
+                    timeUnits: "HOUR"
+                }
+            ],
+            sensorKeys: [key],
+            timePeriod: {
+                startTime: startTime,
+                endTime: endTime,
+                timeUnits: "HOUR"
+            }
+        };
+        this.aqiForecastDataLoading = true;
+        this.reloadAqiChart();
+        this.http
+            .post("/report/line-chart", lineChartCriteria)
+            .subscribe(
+                (res: ResultBean<{ [key: string]: Array<Array<number>> }>) => {
+                    this.aqiForecastDataLoading = false;
+                    const data = res.data[key][0];
+                    if (!!data && data.length > 0) {
+                        this.aqiEchartsIntance.setOption({
+                            series: [{ type: "line", data: data }]
+                        });
+                    }
+                }
+            );
+    }
+    private reloadAqiChart(): void {
+        // const  timeList = this.grid.columns.map(item => item.text);
+        //  if (!!this.aqiEchartsIntance) {
+        //      this.aqiChartOption = null;
+        //      this.aqiEchartsIntance.clear();
+        //  }
+        //  let series = null;
+        //  if ( this.chartSelectedIndex < this.grid.data.length ) {
+        //     series = [{type: 'line', data: this.grid.data[this.chartSelectedIndex]}];
+        //  }
+
+        //  this.initOpton(chartOption ,{ xAxis : [{data : []}]});
+        //  this.aqiChartOption = true;
+        const hour = moment().hours() + 1;
+        const xList = [
+            ...this.newArray(hour, 24 - hour, null, "���"),
+            ...this.newArray(0, hour, null, "���")
+        ];
+        this.initOpton(this.aqiChartOption, { xAxis: [{ data: xList }] });
+    }
+    private reloadMeteChart(): void {
+        //  if (!!this.aqiEchartsIntance) {
+        //      this.aqiChartOption = null;
+        //      this.aqiEchartsIntance.clear();
+        //  }
+        const hour = moment().hours() + 1;
+        const xList = [
+            ...this.newArray(hour, 24 - hour, null, "���"),
+            ...this.newArray(0, hour, null, "���")
+        ];
+        this.initOpton(this.meteChartOption, { xAxis: [{ data: xList }] });
+    }
+    private newArray = (
+        startOrLen: number,
+        len?: number,
+        prefix?: string,
+        suffix?: string
+    ) => {
+        const result = [];
+        const s = !!len ? startOrLen : 0;
+        len = !!len ? len : startOrLen;
+        suffix = !!suffix ? suffix : "";
+        prefix = !!prefix ? prefix : "";
+        for (let i = s; result.length < len; i++) {
+            result.push(prefix + i + suffix);
+        }
+        return result;
+    };
+    // ----------- ������������(24������) -------------
+    public meteChartOption = {};
+    public meteEchartsIntance;
+    public meteChartLoading = false;
+    public onMeteChartInit(e): void {
+        this.meteEchartsIntance = e;
+    }
+    public meteItems = [
+        {
+            name: "������",
+            key: "windSpeed",
+            unit: "m/s",
+            selected: true
+        },
+        {
+            name: "������",
+            key: "temp",
+            unit: "���",
+            selected: false
+        },
+        {
+            name: "������",
+            key: "qpf",
+            unit: "mm",
+            selected: false
+        },
+        {
+            name: "������",
+            key: "humidity",
+            unit: "%RH",
+            selected: false
+        },
+        {
+            name: "���������",
+            key: "uvi",
+            unit: "������/���������",
+            selected: false
+        },
+        {
+            name: "������",
+            key: "pressure",
+            unit: "Pa",
+            selected: false
+        }
+    ];
+    public get selectedMeteItem() {
+        return this.meteItems.find(item => {
+            return !!item.selected;
+        });
+    }
+    public setSelectedMeteItem(item?: any) {
+        if (!!item) {
+            this.meteItems.forEach(it => {
+                if (item.key === it.key) {
+                    it.selected = true;
+                } else {
+                    it.selected = false;
+                }
+            });
+        }
+        this.reloadMeteChart();
+        this.meteChartLoading = true;
+        const key = this.selectedMeteItem.key;
+        this.http
+            .get(
+                "http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=forecast24hours"
+            )
+            .subscribe((res: any) => {
+                const hourlyData = <any[]>res.data.hourly;
+                if (!!hourlyData && hourlyData.length > 0) {
+                    const selectedData = [];
+                    let windDirsData = [];
+                    hourlyData.forEach((item, index) => {
+                        const itemData = item[key];
+                        selectedData.push(itemData);
+                        let windDirData = item['windDir'];
+                        // windDirData = windDirData.length >  2 ? windDirData.substr(1) : windDirData;
+                        if(index == 0 ) {
+                            const windDirName = this.winToChName(windDirData);
+                            console.log(windDirName);
+                            windDirsData.push(
+                                {
+                                    value: windDirName,
+                                    xAxis: index,
+                                    yAxis: itemData
+                                }
+                            );
+                        } else {
+                            let preWindDirData = hourlyData[index-1]['windDir'];  
+                            // preWindDirData = preWindDirData.length >  2 ? preWindDirData.substr(1) : preWindDirData;                         
+                            if(preWindDirData !== windDirData) {
+                                const windDirName = this.winToChName(windDirData);
+                                windDirsData.push(
+                                    {
+                                        value: windDirName,
+                                        xAxis: index,
+                                        yAxis: itemData
+                                    }
+                                );
+                            }
+                        }
+                    });
+                    if (!!selectedData && selectedData.length > 0) {
+                        this.meteEchartsIntance.setOption({
+                            legend: {
+                                data:['������']
+                            },
+                            series: [
+                                { 
+                                    type: 'line', 
+                                    data: selectedData
+                                },
+                                { 
+                                    name: '������',
+                                    type: 'line',
+                                    itemStyle: {
+                                        color: '#c23531'
+                                    },
+                                    markPoint: {
+                                        data: windDirsData
+                                    }
+                                }
+                        ]
+                        });
+                        this.meteChartLoading = false;
+                    }
+                }
+            });
+    }
+    public winToChName(windDir: string) {
+         let name = '';
+         if(!!windDir) {
+             if(windDir.length >1) {
+                windDir = windDir.split('').reverse().join('');
+             }
+            //  let index = 0;
+             for (let ch of windDir) {
+                switch(ch) {
+                    case 'E':name += '���';break;
+                    case 'S':name += '���';break;
+                    case 'W':name += '���';break;
+                    case 'N':name += '���';break;
+                }
+                // if(windDir.length >2 && index == 1){
+                //     name += '���';
+                // } 
+                // index++;
+             }
+             name += '���';
+         }
+         return name;
+    }
+    // ---------------- echart ��������������� ---------------------------
+    private initOpton(chartOption, opt: { [key: string]: object }) {
+        const defaultOption = {
+            title: {
+                left: "center"
+            },
+            tooltip: {
+                trigger: "axis",
+                axisPointer: {
+                    type: "cross",
+                    label: {
+                        backgroundColor: "#6a7985"
+                    }
+                }
+            },
+            legend: {
+                data: []
+            },
+            toolbox: {
+                feature: {
+                    saveAsImage: {}
+                }
+            },
+            grid: {
+                left: "3%",
+                right: "4%",
+                bottom: "3%",
+                containLabel: true
+            },
+            xAxis: [
+                {
+                    type: "category",
+                    boundaryGap: false
+                }
+            ],
+            yAxis: [
+                {
+                    type: "value"
+                }
+            ],
+            series: []
+        };
+        Object.assign(defaultOption, opt);
+        Object.assign(chartOption, defaultOption);
+    }
+    //---------- ������������������ apiSortedItem ------------------------
+    public apiSortedTableLoading = false;
+    public apiSortedTableList = [];
+    public apiSortedItems = [
+        {
+            name: "PM2.5",
+            key: "e1",
+            unit: "ug/m��",
+            selected: true
+        },
+        {
+            name: "PM10",
+            key: "e2",
+            unit: "ug/m��",
+            selected: false
+        },
+        {
+            name: "������������",
+            key: "e10",
+            unit: "mg/m��",
+            selected: false
+        },
+        {
+            name: "������������",
+            key: "e11",
+            unit: "ug/m��",
+            selected: false
+        },
+        {
+            name: "������",
+            key: "e15",
+            unit: "ug/m��",
+            selected: false
+        },
+        {
+            name: "������������",
+            key: "e16",
+            unit: "ug/m��",
+            selected: false
+        }
+    ];
+    public get selectedApiSortedItem() {
+        return this.apiSortedItems.find(item => {
+            return !!item.selected;
+        });
+    }
+    public setSelectedApiSortedItem(item ?: any) {
+        if (!!item) {
+            this.apiSortedItems.forEach(it => {
+                if (item.key === it.key) {
+                    it.selected = true;
+                } else {
+                    it.selected = false;
+                }
+            });
+        }
+        this.apiSortedTableLoading = true;
+        const params = {sensorKey: this.selectedApiSortedItem.key, dimension: 'monitorPoint', regionCode: '320583', accountId: '1', timeType: 'day'};
+        this.http.get('screen/region_ranking_data',params).subscribe((res: any) => {
+            this.apiSortedTableLoading = false;
+            // console.log(res);
+          this.apiSortedTableList = res.data;
+        });
+    }
+    public aqiSortedTableSort(sortName, sortValue) {
+        this.apiSortedTableList = [
+          ...(<any[]>this.apiSortedTableList).sort((a, b) => {
+            if (a[sortName] > b[sortName]) {
+              return (sortValue === 'ascend') ? 1 : -1;
+            } else if (a[sortName] < b[sortName]) {
+              return (sortValue === 'ascend') ? -1 : 1;
+            } else {
+              return 0;
+            }
+          })
+        ];
+      }
+    //---------mock-------------------
+    data: any = {
+        salesData: [],
+        offlineData: []
+    };
+    sort(sortName, sortValue) {
+        this.data.searchData = [
+            ...(<any[]>this.data.searchData).sort((a, b) => {
+                if (a[sortName] > b[sortName]) {
+                    return sortValue === "ascend" ? 1 : -1;
+                } else if (a[sortName] < b[sortName]) {
+                    return sortValue === "ascend" ? -1 : 1;
+                } else {
+                    return 0;
+                }
+            })
+        ];
+    }
     loading = true;
-    salesType = 'all';
+    salesType = "all";
     salesPieData: any;
     salesTotal = 0;
     changeSaleType() {
-        this.salesPieData = this.salesType === 'all' ? this.data.salesTypeData : (
-            this.salesType === 'online' ? this.data.salesTypeDataOnline : (
-                this.salesType === 'online2' ?  this.data.salesTypeDataOnline2 : this.data.salesTypeDataOffline
-            )
-        );
-        if (this.salesPieData) this.salesTotal = this.salesPieData.reduce((pre, now) => now.y + pre, 0);
+        this.salesPieData =
+            this.salesType === "all"
+                ? this.data.salesTypeData
+                : this.salesType === "online"
+                    ? this.data.salesTypeDataOnline
+                    : this.salesType === "online2"
+                        ? this.data.salesTypeDataOnline2
+                        : this.data.salesTypeDataOffline;
+        if (this.salesPieData)
+            this.salesTotal = this.salesPieData.reduce(
+                (pre, now) => now.y + pre,
+                0
+            );
     }
 }
diff --git a/src/app/routes/statistics/calendar/calendar.component.html b/src/app/routes/statistics/calendar/calendar.component.html
index 35c5175..0fe6701 100644
--- a/src/app/routes/statistics/calendar/calendar.component.html
+++ b/src/app/routes/statistics/calendar/calendar.component.html
@@ -2,12 +2,19 @@
 <div nz-row [nzGutter]="24" style="padding: 20px">
     <div nz-col nzXs="24"   nzMd="24">
         <div nz-form-control nz-col [nzSm]="20">
-            <nz-calendar [nzLocale]="'zh-cn'" style="width: 290px; border: 1px solid rgb(217, 217, 217); border-radius: 4px;">
-                <!-- <ng-template #dateCell let-day>
-                    <div style="width: 22px;height: 22px;display: block;position: absolute; background-color: red;">
-                    </div>
-                </ng-template> -->
-            </nz-calendar>
+            <nz-card [nzBordered]="false">
+                <nz-calendar [nzLocale]="'zh-cn'" >
+                    <ng-template #dateCell let-day>
+                        <div *ngIf="!isExpire(day.date)" style="width: 80px;height: 80px;display: block;position: absolute;" (click)="calendarClick(day.date)">
+                                <nz-badge [nzStatus]="calendarDayCells[day.date|date:'dd']['status']" [nzText]="calendarDayCells[day.date|date:'dd']['statusName']" ></nz-badge>
+                                <!-- <nz-badge [nzStatus]="'success'" [nzText]="'Sunday'" *ngIf="(day.date|date:'EEE')==='Sun'"></nz-badge>
+                                {{day.date|date:'EEE'}}
+                                {{day.date|date:'dd'}}
+                                {{calendarDayCells[day.date|date:'dd']['status']}} -->
+                        </div>
+                    </ng-template>
+                </nz-calendar>
+            </nz-card>
         </div>
     </div>
     <div nz-col nzXs="24" nzSm="12" nzMd="24" nzLg="15">
diff --git a/src/app/routes/statistics/calendar/calendar.component.ts b/src/app/routes/statistics/calendar/calendar.component.ts
index 526fa2c..09e03c1 100644
--- a/src/app/routes/statistics/calendar/calendar.component.ts
+++ b/src/app/routes/statistics/calendar/calendar.component.ts
@@ -14,7 +14,13 @@
 export class CalendarComponent implements OnInit, OnDestroy {
 
     data: any = {};
-
+    public calendarDayCells:{
+       [key : string] : {
+         'status': string,
+         'statusName': string,
+         'data': {}
+       }
+    } = {};
     constructor(
         private deviceService: DeviceService,
         private http: _HttpClient,
@@ -23,12 +29,30 @@
     }
 
     ngOnInit() {
-
+        const day = Number(moment().format('DD'));
+        for(let index = 1;index <= day; index++) {
+            this.calendarDayCells[('0'+index).slice(-2)] = {
+                status: 'processing',
+                statusName: '���������',
+                data: {}
+            }
+        }
+        // console.log(this.calendarDayCells);
     }
 
     ngOnDestroy(): void {
     }
-    calendarClick(event,day) {
-        console.log(day);
+    // ��������������� ���������
+    calendarClick(mo: moment.Moment) {
+        console.log(mo.format('DD'));
+    }
+    public isExpire(mo: moment.Moment):boolean {
+        //  console.log(moment().valueOf());
+        //  console.log(mo.valueOf());
+        //  console.log(moment().valueOf() < mo.valueOf());
+         return moment().valueOf() < mo.valueOf();
+    }
+    loadCalendar(event) {
+        console.log(event);
     }
 }
diff --git a/src/app/routes/statistics/statistics.module.ts b/src/app/routes/statistics/statistics.module.ts
index 239be7a..1b617b1 100644
--- a/src/app/routes/statistics/statistics.module.ts
+++ b/src/app/routes/statistics/statistics.module.ts
@@ -3,7 +3,7 @@
 import { PipeModule } from '@business/pipe/pipe.module';
 import { NzTreeModule } from 'ng-tree-antd';
 import { NgxEchartsModule } from 'ngx-echarts';
-import { CommonModule, DatePipe } from '@angular/common';
+import { CommonModule } from '@angular/common';
 import { RouterModule, Routes } from '@angular/router';
 import { AnalysisComponent } from './analysis/analysis.component';
 import { CalendarComponent } from './calendar/calendar.component';

--
Gitblit v1.8.0