iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Modern Web

angular專案開發指南系列 第 17

Angular 專業圖表套件 - Ngx-Echarts

  • 分享至 

  • xImage
  •  

前言

回到網站的首頁,為了量化租戶管理的效能,通常會將資料數據透過圖表的方式呈現,在網路上可以找到許多套件與 Angular 搭配完成各種任務,今天要跟大家介紹的就是 Ngx-Echarts。做為視覺化圖表庫,Apache ECharts 是一個使用 TypeScript 實現的可執行在桌面及行動瀏覽器上,包括 Internet Explorer 8/9/10/11、Google Chrome、Firefox、Safari 等主流瀏覽器的專案。

透過 Ngx-Echarts 將 ECharts 包裝成一個 Angular Directive,我們就可以在 Angular 專案中使用這個視覺化圖表工具。


Ngx-Echarts 安裝方式

Install

# if you use npm
npm install echarts -S
npm install ngx-echarts -S

# or if you use yarn
yarn add echarts
yarn add ngx-echarts

載入 Ngx-Echarts 模組 src\app\app.module.ts

// Ngx-Echart
import * as echarts from 'echarts';
import { NgxEchartsModule } from 'ngx-echarts';

@NgModule({
  imports: [
    ...,
    NgxEchartsModule.forRoot({
      echarts: () => import('echarts')
    })
  ],
})
export class AppModule { }

Ngx-Echarts 使用範例

Component

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-basic-simple',
  templateUrl: './basic-simple.component.html',
  styleUrls: ['./basic-simple.component.scss'],
})
export class BasicSimpleComponent implements OnInit {
  options: any;
  constructor() { }

  ngOnInit(): void {
    const xAxisData = [];
    const data1 = [];
    const data2 = [];

    for (let i = 0; i < 100; i++) {
      xAxisData.push('category' + i);
      data1.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5);
      data2.push((Math.cos(i / 5) * (i / 5 - 10) + i / 6) * 5);
    }

    this.options = {
      legend: {
        data: ['bar', 'bar2'],
        align: 'left',
      },
      tooltip: {},
      xAxis: {
        data: xAxisData,
        silent: false,
        splitLine: {
          show: false,
        },
      },
      yAxis: {},
      series: [
        {
          name: 'bar',
          type: 'bar',
          data: data1,
          animationDelay: (idx: any) => idx * 10,
        },
        {
          name: 'bar2',
          type: 'bar',
          data: data2,
          animationDelay: (idx: any) => idx * 10 + 100,
        },
      ],
      animationEasing: 'elasticOut',
      animationDelayUpdate: (idx: any) => idx * 5,
    };
  }
}

Html

<!-- 使用 @Input 將父元件 Component 的資料傳入子元件 echarts directive 中 -->
<div echarts [options]="options" class="demo-chart"></div>

以上是官方提供的範例,接下來我們在 my-app 中搭配 Mockserver 做個實際應用。


my-app 實際應用範例

建立 chart 的假資料 _mockserver\myapp\tenant\chart.js

module.exports = {
    mansion: [120, 132, 101, 134, 90, 230, 210, 432, 441, 534, 560, 630],
    release: [220, 182, 191, 234, 290, 330, 360, 132, 101, 134, 190, 230],
    buy: [150, 232, 201, 154, 190, 330, 410, 132, 131, 135, 230, 200],
    sell: [320, 332, 301, 334, 390, 330, 220, 132, 161, 134, 180, 230],
    rent: [820, 932, 901, 934, 1290, 1230, 1320, 1302, 2111, 2134, 2300, 2680],
};

設定 Mockserver _mockserver\_db.js

var apiFiles = [
    __dirname + "/myapp/test.js",
    __dirname + "/myapp/hello/world.js",
    __dirname + "/myapp/hello/mockdata.js",
    __dirname + "/myapp/tenant/list.js",
    __dirname + "/myapp/tenant/chart.js",   // 記得加 chart.js
];

...

讀取假資料到 src\app\about\about.component.ts

host = 'http://localhost:3000';

...

/**
 * ### 讀取假資料 `myapp-tenant-chart`
 *
 * @memberof AboutComponent
 */
async getRawDataThenDraw() {
    // 假資料物件
    const resp = await this.httpService.httpGET(this.host + '/myapp-tenant-chart');

    // 畫房屋市場成長趨勢 - 折線圖
    this.drawLineChart(resp);

    // 畫房屋市場成長趨勢 - 柱狀圖
    this.drawBarChart(resp);
}

...

// 初始化頁面內容,顯示數據綁定
ngOnInit(): void {
    this.getRawDataThenDraw();
}

回到 Html 上 src\app\about\about.component.html

<div class="about">
    <!-- 畫房屋市場成長趨勢 - 折線圖 -->
    <div class="chart-block">
        <div echarts [options]="lineOptions"></div>
    </div>
    <br />
    <!-- 畫房屋市場成長趨勢 - 柱狀圖 -->
    <div class="chart-block">
        <div echarts [options]="barOptions"></div>
    </div>
    ...
</div>

美化一下

.about {
    .chart-block {
        background-color: white;
        padding: 2rem;
    }
}

折線圖 src\app\about\about.component.ts

...
/**
 * ### 畫房屋市場成長趨勢 - [折線圖](https://echarts.apache.org/examples/zh/index.html#chart-type-line)
 *
 * @param {*} [rawDataObj={}]
 * @memberof AboutComponent
 */
drawLineChart(rawDataObj: any = {}) {
    const xAxisData = [];
    const data1 = [];
    const data2 = [];

    for (let i = 0; i < 100; i++) {
        xAxisData.push('category' + i);
        data1.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5);
        data2.push((Math.cos(i / 5) * (i / 5 - 10) + i / 6) * 5);
    }

    // 基本配置請參考 Apache ECharts 官網教學範例
    this.lineOptions = {
        title: {
            text: '房屋市場成長趨勢',
        },
        tooltip: {
            trigger: 'axis',
        },
        legend: {
            data: ['豪宅市場', '出租需求', '買房需求', '賣房需求', '租屋需求'],
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true,
        },
        toolbox: {
            feature: {
                saveAsImage: {},
            },
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        },
        yAxis: {
            type: 'value',
        },
        series: [
            {
                name: '豪宅市場',
                type: 'line',
                stack: 'Total',
                data: rawDataObj?.mansion || [],
            },
            {
                name: '出租需求',
                type: 'line',
                stack: 'Total',
                data: rawDataObj?.release || [],
            },
            {
                name: '買房需求',
                type: 'line',
                stack: 'Total',
                data: rawDataObj?.buy || [],
            },
            {
                name: '賣房需求',
                type: 'line',
                stack: 'Total',
                data: rawDataObj?.sell || [],
            },
            {
                name: '租屋需求',
                type: 'line',
                stack: 'Total',
                data: rawDataObj?.rent || [],
            },
        ],
    };
}
...

柱狀圖 src\app\about\about.component.ts

/**
 * ### 畫房屋市場成長趨勢 - [柱狀圖](https://echarts.apache.org/examples/zh/index.html#chart-type-bar)
 *
 * @param {*} [rawDataObj={}]
 * @memberof AboutComponent
 */
drawBarChart(rawDataObj: any = {}) {
    this.barOptions = {
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                // Use axis to trigger tooltip
                type: 'shadow', // 'shadow' as default; can also be 'line' or 'shadow'
            },
        },
        legend: {},
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true,
        },
        xAxis: {
            type: 'value',
        },
        yAxis: {
            type: 'category',
            data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        },
        series: [
            {
                name: '豪宅市場',
                type: 'bar',
                stack: 'total',
                label: {
                    show: true,
                },
                emphasis: {
                    focus: 'series',
                },
                data: rawDataObj?.mansion || [],
            },
            {
                name: '出租需求',
                type: 'bar',
                stack: 'total',
                label: {
                    show: true,
                },
                emphasis: {
                    focus: 'series',
                },
                data: rawDataObj?.release || [],
            },
            {
                name: '買房需求',
                type: 'bar',
                stack: 'total',
                label: {
                    show: true,
                },
                emphasis: {
                    focus: 'series',
                },
                data: rawDataObj?.buy || [],
            },
            {
                name: '賣房需求',
                type: 'bar',
                stack: 'total',
                label: {
                    show: true,
                },
                emphasis: {
                    focus: 'series',
                },
                data: rawDataObj?.sell || [],
            },
            {
                name: '租屋需求',
                type: 'bar',
                stack: 'total',
                label: {
                    show: true,
                },
                emphasis: {
                    focus: 'series',
                },
                data: rawDataObj?.rent || [],
            },
        ],
    };
}

各種圖表的 option 格式,請參考 Apache ECharts


成果畫面

房屋市場成長趨勢 - 折線圖

p117

房屋市場成長趨勢 - 柱狀圖

p118

結論

透過 Ngx-Echarts 的幫忙,讓我們得以 在Angular 專案中使用 Apache ECharts 來視覺化的呈現網站中的資訊,還有其他許多套件能幫助我們在 Angular 中完成各種需求,以後有機會再介紹。

接下來跟大家介紹 Angular 專案中各元件之間資料流的傳遞方式。


參考

ngx-echarts

Apache ECharts

angular-ngx-echarts

stackblitz tree-map


上一篇
Angular 元件的生命週期
下一篇
Angular 組件間資料的傳遞方式
系列文
angular專案開發指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言