【可视化库对比】ECharts、AntV、D3和Three

发布时间 2024-01-05 19:14:29作者: 泠风lj

本文写作目的:大家在使用可视化库创作可视化作品的时候,可能会产生这样的问题:“现如今成熟的可视化库有这么多,我到底该选择哪一个呢?”这其实也是我在学习数据可视化课程的时候面临的一个问题。因此本文旨在对比上述广泛被使用到的4个前端可视化库:EchartAntVD3Three,了解它们的区别和共性,以此帮助大家更好地判断选择哪一个可视化库创作可视化作品。为了更好地比较它们,这里我分别使用它们绘制柱状图,通过例子更加深入地理解。

 

1. ECharts

  1. 第一步:获取DOM节点,得到一个容器,待会用于放图表的
  2. 第二步:echarts.init(chartDom):初始化,输入dom节点,得到一个echart的实例
  3. 第三步:配置options,用户可以通过json格式的数据,指定图表的内容,从以下几个部分配置:title、tooltip、legend、xAxis、yAxis、series。
  4. 第四步:myChart.setOption(option),把你的配置设置进去,让它按照你的配置来画图~
  5. 使用评价:简单易用,难点都封装好了,只需要配置数据即可。所以非常适合小白用户,如果需要在网页中快速展示图表信息,刚好这个图表是比较常规的,不需要过多地调整和配置,就可以采用eCharts。
  6. 美观度评价:自带渐入动画、图表配色不错。
查看代码
 var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;

option = {
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: [120, 200, 150, 80, 70, 110, 130],
      type: 'bar'
    }
  ]
};
option && myChart.setOption(option);

 

2. AntV

AntV是蚂蚁集团数据可视化团队打造的一个非常完善的数据可视化解决方案,进入到AntV的官网中我们可以发现它由七大模块组成(并且页面右侧有一个ChartCube,可以在线编辑图表):
1. G2|G2Plot:可视化图形语法和通用图表库
2. S2:多维可视分析表格
3. G6|Graphin:关系数据可视化分析工具和图分析组件
4. X6|XFlow:流程图相关的图表和组件
5. L7|L7Plot:地理空间数据可视化框架和地理图表
6. F2|F6:移动端的可视化解决方案
7. AVA:可视分析技术框架

绘制柱状图的话,可以 用到G2或者G2Plot。咦?它们两又有什么区别呢。下面具体来说说:
(1)G2:它是可视化图形语法,官网说的是采用"一句话"的形式来生成图表。我看源代码其实是采用了链式调用的方式,一个个函数串起来构建一个图表。每个函数因为其函数名比较通俗易懂,就像一个词语一样,那么连起来就像是一句话了,即”你先把data怎么怎么处理以下,然后encode一下,或者再给我加点lable之类的...“,整体上看,就像你给它说了一句命令吧~其实在底层,它还是先会把这个声明语法转化为js object,其实就是options,直到调用了chart.render()的时候才会真正地解析和渲染。

查看代码
 const chart = new G2.Chart({
    container: 'container',
    theme: 'classic',
    width:349,
    height:500
  });
  
  chart
    .interval()
    .data([
      { genre: 'Mon', sold: 120 },
      { genre: 'Tue', sold: 200 },
      { genre: 'Wed', sold: 150 },
      { genre: 'Thu', sold: 80 },
      { genre: 'Fri', sold: 70 },
      { genre: 'Sat', sold: 110 },
      { genre: 'Sun', sold: 130 },
    ])
    .encode('x', 'genre')
    .encode('y', 'sold')
    .encode('color', 'genre');
  
  chart.render();

 

 

(2)G2Plot:它的使用方法和Echarts比较像,只要配置图表的options。用起来比较简单,用户不需要知道那么多的细节。其中的G2指的就是图形语法,也致敬了基于R语言的ggplot可视化库。配置可选项有:data、xField、yField、color、point、label、xAxis、yAixs、legend等。创建柱状图可以采用:new Column('container', options).

查看代码
 const data=[
          { genre: 'Mon', sold: 120 },
          { genre: 'Tue', sold: 200 },
          { genre: 'Wed', sold: 150 },
          { genre: 'Thu', sold: 80 },
          { genre: 'Fri', sold: 70 },
          { genre: 'Sat', sold: 110 },
          { genre: 'Sun', sold: 130 },
]
const {Column}=G2Plot
const column = new Column('container', {
    data,
    xField: 'genre',
    yField: 'sold',
  });
column.render();

配色更年轻化、时尚化一点

G2比ECharts更灵活,有一个自定义扩展功能可以定制化图表,AntV团队将 G2Plot 基于 G2 开发图表的 Adaptor 模式直接开放出来,用户可以基于这一个模式去基于 G2 封装定制图表。

 

3. D3

D3.js是一个很popular的库,好消息是有很多资料,坏消息是很多都是英文的。而且在看官网的案例之前,要先搞懂Observable,不然,案例会看得你怀疑人生。它一般结合svg进行绘图,用起来很麻烦,像在造轮子,但是灵活度很高,基本上你可以实现任何你想要的图表。”没有你编不出来的,只有你想不到的——chying“

查看代码
 const drawContainer = document.getElementById("d3container");
const [width, height, marginLeft, marginBottom] = [400, 500, 30, 30]
const svg = d3.select(drawContainer).append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("viewBox", [0, marginBottom + 10, width, height - marginBottom])
    .attr("style", "max-width: 100%; height: auto; height: intrinsic;");

const data = [
    { genre: 'Mon', sold: 120 },
    { genre: 'Tue', sold: 200 },
    { genre: 'Wed', sold: 150 },
    { genre: 'Thu', sold: 80 },
    { genre: 'Fri', sold: 70 },
    { genre: 'Sat', sold: 110 },
    { genre: 'Sun', sold: 130 },
]
// data process
const xValue = d3.map(data, item => item.genre);
const yValue = d3.map(data, item => item.sold);

// set scale
const xScale = d3.scaleBand()
    .domain(xValue)
    .rangeRound([marginLeft, width])
const yScale = d3.scaleLinear()
    .domain([0, d3.max(yValue)])
    .range([height, marginBottom]);

//set axis
const xAxis = d3.axisBottom(xScale)
    .ticks(0)
    .tickPadding(12);
const yAxis = d3.axisLeft(yScale)
    .ticks(5)
    .tickPadding(8)
    .tickFormat(d3.format('d'));
//add to svg
svg.append("g")
    .attr("transform", `translate(0,${height})`)
    .call(xAxis);

svg.append("g")
    .attr("transform", `translate(${0},0)`)
    .call(yAxis)
    .call(g => g.select(".domain").remove())
    .call(g => g.selectAll(".tick line").clone()
        .attr("x2", width)
        .attr("stroke-opacity", 0.1))
    .call(g => g.selectAll("text")
        .attr("x", 0)
        .attr("fill", "currentColor")
        .attr("text-anchor", "start")
        .text()
    );

svg.append("g")
    .attr("fill", "#9999ff")
    .selectAll("rect")
    .data(data)
    .join("rect")
    .attr("x", d => xScale(d.genre))
    .attr("y", d => yScale(d.sold))
    .attr("height", d => yScale(0) - yScale(d.sold))
    .attr("width", xScale.bandwidth() - 10);

 

4. Three

Three.js是用来绘制三维图形的,它属于WebGL技术。如果学过OpenGL相关知识,那么用Three.js就会相对比较简单了。需要采取以下步骤:
1. 创建场景
2. 设置一个Camera,相当于让它当你的眼睛,去看Three世界内的物体
3. 设置渲染器
4. 创建物体,三步走:geometry、material、Mesh(geometry, material)

查看代码
 let scene
let camera, renderer, light, controls
let geometry, cube
//ori data
const oriData = [
    { genre: 'Mon', sold: 120 },
    { genre: 'Tue', sold: 200 },
    { genre: 'Wed', sold: 150 },
    { genre: 'Thu', sold: 80 },
    { genre: 'Fri', sold: 70 },
    { genre: 'Sat', sold: 110 },
    { genre: 'Sun', sold: 130 },
]
init()
animate();

function init() {
    //create scence
    scene = new THREE.Scene()
    //create camera
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
    camera.position.z = 150
    //create renderer
    renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)
    //add light
    scene.add(new THREE.AmbientLight(0x555555))
    light = new THREE.SpotLight(0xffffff, 1.5)
    light.position.set(0, -10, 100)
    scene.add(light)
    //add controls
    controls = new THREE.OrbitControls(camera, renderer.domElement)
    //create objects by data
    const material = new THREE.MeshPhongMaterial({ color: 0x40E0D0 })
    
    oriData.forEach((item, index) => {
        const { sold } = item
        geometry = new THREE.BoxGeometry(4, sold / 10, 4)
        // geometry.setDrawRange({start:10})
        cube = new THREE.Mesh(geometry, material)
        cube.position.set(index * 10 - 30, sold / 10 / 2, 0)
        scene.add(cube)
    })
}

function animate() {
    requestAnimationFrame(animate)
    renderer.render(scene, camera)

}

 

 

5. 总结

  1. 代码规范:EChart和D3官网的案例有一些用的es6之前的语法,antd遵循了es6新语法规范,更加专业、与时俱进。
  2. 灵活度:ECharts<G2<D3
  3. 使用难度:Echart≈G2PLot<G2<D3
  4. 场景:画三维图用Three,三维地图AntV的L7|L7Plot也可以做到,画二维图用ECharts或者G2、G2Plot均可

 

 

转载自:https://zhuanlan.zhihu.com/p/623219646