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

sfornt發表於2018-10-06

最近阿里正式開源的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示例

三、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 ★,轉載請註明出處。

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

相關文章