三大圖表庫:ECharts 、 BizCharts 和 G2,該如何選擇?

ECharts 、 BizCharts 和 G2,該如何選擇?

最近阿里正式開源的BizCharts圖表庫基於React技術棧,各個圖表項皆採用了組件的形式,貼近React的使用特點。同時BizCharts基於G2進行封裝,Bizcharts也繼承了G2相關特性。公司目前統一使用的是ECharts圖表庫,下文將對3種圖表庫進行分析比對。


BizCharts

文檔地址:BizCharts

一、安裝

通過 npm/yarn 引入

npm install bizcharts --save

yarn add bizcharts  --save

二、引用

成功安裝完成之後,即可使用 import 或 require 進行引用。

例子:

import { Chart, Geom, Axis, Tooltip, Legend } from 'bizcharts';
import chartConfig from './assets/js/chartConfig';

<div className="App">
    <Chart width={600} height={400} data={chartConfig.chartData} scale={chartConfig.cols}>
      <Axis name="genre" title={chartConfig.title}/>
      <Axis name="sold" title={chartConfig.title}/>
      <Legend position="top" dy={-20} />
      <Tooltip />
      <Geom type="interval" position="genre*sold" color="genre" />
    </Chart>
</div>


該示例中,圖表的數據配置單獨存入了其他js文件中,避免頁面太過冗雜

module.exports = {
    chartData : [
        { genre: 'Sports', sold: 275, income: 2300 },
        { genre: 'Strategy', sold: 115, income: 667 },
        { genre: 'Action', sold: 120, income: 982 },
        { genre: 'Shooter', sold: 350, income: 5271 },
        { genre: 'Other', sold: 150, income: 3710 }
    ],
    // 定義度量
    cols : {
        sold: { alias: '銷售量' }, // 數據字段別名映射
        genre: { alias: '遊戲種類' }
    },
    title : {
        autoRotate: true, // 是否需要自動旋轉,默認爲 true
        textStyle: {
          fontSize: '12',
          textAlign: 'center',
          fill: '#999',
          fontWeight: 'bold',
          rotate: 30
        }, // 座標軸文本屬性配置
        position:'center', // 標題的位置,**新增**
    }
}

效果預覽:
BizCharts示例

三、DataSet

BizCharts中可以通過dataset(數據處理模塊)來對圖標數據進行處理,該方法繼承自G2,在下文中將對此進行詳細分析。

快速跳轉


G2

BizCharts基於G2進行開發,在研究BizCharts的過程中也一起對G2進行了實踐。

一、安裝

和BizCharts一樣,可以通過 npm/yarn 引入

npm install @antv/g2 --save

yarn add @antv/g2 --save

與BizCharts不同,G2初始化數據並非以組件的形式引入,而是需要獲取需要在某個DOM下初始化圖表。獲取該DOM的唯一屬性id之後,通過chart()進行初始化。

示例:

import React from 'react';
import G2 from '@antv/g2';
    class g2 extends React.Component {constructor(props) {
        super(props);
        this.state = {
          data :[
            { genre: 'Sports', sold: 275 },
            { genre: 'Strategy', sold: 115 },
            { genre: 'Action', sold: 120 },
            { genre: 'Shooter', sold: 350 },
            { genre: 'Other', sold: 150 }
          ]
        };
    }

    componentDidMount() {
        const chart = new G2.Chart({
          container: 'c1', // 指定圖表容器 ID
          width: 600, // 指定圖表寬度
          height: 300 // 指定圖表高度
        });
        chart.source(this.state.data);
        chart.interval().position('genre*sold').color('genre');
        chart.render();
    }
    render() {
        return (
          <div id="c1" className="charts">
          </div>
        );
    }
}
export default g2;

效果圖:
G2示例

<div id="Mark"></div>三、DataSet

DataSet 主要有兩方面的功能,解析數據(Connector)&加工數據(Transform)。

官方文檔描述得比較詳細,可以參考官網的分類:

源數據的解析,將csv, dsv,geojson 轉成標準的JSON,查看Connector
加工數據,包括 filter,map,fold(補數據) 等操作,查看Transform
統計函數,彙總統計、百分比、封箱 等統計函數,查看 Transform
特殊數據處理,包括 地理數據、矩形樹圖、桑基圖、文字雲 的數據處理,查看 Transform
// step1 創建 dataset 指定狀態量
const ds = new DataSet({
 state: {
    year: '2010'
 }
});

// step2 創建 DataView
const dv = ds.createView().source(data);

dv.transform({
 type: 'filter',
 callback(row) {
    return row.year === ds.state.year;
 }
});

// step3 引用 DataView
chart.source(dv);
// step4 更新狀態量
ds.setState('year', '2012');

以下采用官網文檔給出的示例進行分析

示例一

該表格裏面的數據是美國各個州不同年齡段的人口數量,表格數據存放在類型爲CVS的文件中
數據鏈接(該鏈接中爲json類型的數據)

State 小於5歲 5至13歲 14至17歲 18至24歲 25至44歲 45至64歲 65歲及以上
WY 38253 60890 29314 53980 137338 147279 65614
DC 36352 50439 25225 75569 193557 140043 70648
VT 32635 62538 33757 61679 155419 188593 86649
... ... ... ... ... ... ... ...

初始化數據處理模塊

import DataSet from '@antv/data-set';

const ds = new DataSet({
//state表示創建dataSet的狀態量,可以不進行設置
 state: {
    currentState: 'WY'
    }
});

const dvForAll = ds
// 在 DataSet 實例下創建名爲 populationByAge 的數據視圖
    .createView('populationByAge') 
// source初始化圖表數據,data可爲http請求返回的數據結果
    .source(data, {
      type: 'csv', // 使用 CSV 類型的 Connector 裝載 data,如果是json類型的數據,可以不進行設置,默認爲json類型
});

/**
trnasform對數據進行加工處理,可通過type設置加工類型,具體參考上文api文檔
加工過後數據格式爲
[
{state:'WY',key:'小於5歲',value:38253},
{state:'WY',key:'5至13歲',value:60890},
]
*/ 
dvForAll.transform({
    type: 'fold',
    fields: [ '小於5歲','5至13歲','14至17歲','18至24歲','25至44歲','45至64歲','65歲及以上' ],
    key: 'age',
     value: 'population'
});

//其餘transform操作
const dvForOneState = ds
    .createView('populationOfOneState')
    .source(dvForAll); // 從全量數據繼承,寫法也可以是.source('populationByAge')
 dvForOneState
     .transform({ // 過濾數據,篩選出state符合的地區數據
    type: 'filter',
    callback(row) {
      return row.state === ds.state.currentState;
    }
})
 .transform({
    type: 'percent',
    field: 'population',
    dimension: 'age',
    as: 'percent'
    });

使用G2繪圖
G2-chart Api文檔

import G2 from '@antv/g2';

// 初始化圖表,id指定了圖表要插入的dom,其他屬性設置了圖表所佔的寬高
const c1 = new G2.Chart({
  id: 'c1',
  forceFit: true,
  height: 400,
});

// chart初始化加工過的數據dvForAll
c1.source(dvForAll);

// 配置圖表圖例
c1.legend({
  position: 'top',
});

// 設置座標軸配置,該方法返回 chart 對象,以下代碼表示將座標軸屬性爲人口的數據,轉換爲M爲單位的數據
c1.axis('population', {
  label: {
    formatter: val => {
      return val / 1000000 + 'M';
    }
  }
});

c1.intervalStack()
  .position('state*population')
  .color('age')
  .select(true, {
    mode: 'single',
    style: {
      stroke: 'red',
      strokeWidth: 5
    }
  });
  
//當tooltip發生變化的時候,觸發事件,修改ds的state狀態量,一旦狀態量改變,就會觸發圖表的更新,所以c2餅圖會觸發改變
c1.on('tooltip:change', function(evt) {
  const items = evt.items || [];
  if (items[0]) {
  //修改的currentState爲鼠標所觸及的tooltip的地區
    ds.setState('currentState', items[0].title);
  }
});

// 繪製餅圖
const c2 = new G2.Chart({
  id: 'c2',
  forceFit: true,
  height: 300,
  padding: 0,
});
c2.source(dvForOneState);
c2.coord('theta', {
  radius: 0.8 // 設置餅圖的大小
});
c2.legend(false);
c2.intervalStack()
  .position('percent')
  .color('age')
  .label('age*percent',function(age, percent) {
    percent = (percent * 100).toFixed(2) + '%';
    return age + ' ' + percent;
  });

c1.render();
c2.render();

*

ECharts

ECharts是一個成熟的圖表庫, 使用方便、圖表種類多、容易上手。文檔資源也比較豐富,在此不做贅述。
ECharts文檔

*

ECharts & BizCharts & G2 對比

對比BizCharts和G2兩種圖表庫,BizCharts主要是進行了一層封裝,使得圖表可以以組件的形式進行調用,按需加載,使用起來更加方便。
簡單對比一下三個圖表庫的區別:

初始化圖表:
ECharts:

// 基於準備好的dom,初始化ECharts實例
var myChart = echarts.init(document.getElementById('main'));

BizCharts:

// 以組件的形式,組合調用
import { Chart, Geom, Axis, ... } from 'bizcharts';

<Chart width={600} height={400} data={data}>
    ...
</Chart>

G2:

// 基於準備好的dom,配置之後進行初始化
const chart = new G2.Chart({
    container: 'c1', // 指定圖表容器 ID
    width: 600, // 指定圖表寬度
    height: 300 // 指定圖表高度
});
chart.source(data);
chart.render();
 
<div id="c1" className="charts"></div>

配置:

ECharts:

// 集中在options中進行配置
myChart.setOption({
    title: {
        ...
    },
    tooltip: {},
    xAxis: {
        data: [...]
    },
    yAxis: {},
    series: [{
        ...
    }]
});

BizCharts:

// 根據組件需要,配置參數之後進行賦值
const cols = {...};
const data = {...};
<Chart width={600} height={400} data={data} sca`enter code here`le={cols}>
    ...
</Chart>

G2:

chart.tooltip({
  triggerOn: '...'
  showTitle: {boolean}, // 是否展示 title,默認爲 true
  crosshairs: {
    ...
    style: {
      ...
    }
  }
});

事件:

ECharts:事件 api文檔

myChart.on('click', function (params) {
    console.log(params);
});

BizCharts:事件 api文檔

<chart
  onEvent={e => {
    //do something
  }}
/>

G2: 事件 api文檔

chart.on('mousedown', ev => {});

總結

對比以上3種圖表,ECharts和BizCharts相對容易使用,尤其ECharts的配置非常清晰,BizCharts與其也有一定相似之處。BizCharts優勢在於組件化的形式使得dom結構相對清晰,按需引用。G2比較適合需要大量圖表交互時引用,其豐富的api處理交互邏輯相對更有優勢。

廣而告之

本文發佈於薄荷前端週刊,歡迎Watch & Star ★,轉載請註明出處。

歡迎討論,點個贊再走吧 。◕‿◕。 ~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章