可视化工具之调研

1,438 阅读5分钟

考察点

  • 开源协议
  • 组件库大小
  • 开发维护及社区状态
  • 浏览器兼容性
  • 功能

D3

开源协议

免费

组件库大小

243KB d3js.org/d3.v5.min.j…

开发维护及社区状态

  • watch:4090
  • star:86313
  • fork:21083
  • issues:4 open,1998 closed

浏览器兼容性

D3 5+ 支持最新浏览器,比如 Chrome,Edge,Firefox 以及 Safari。D3 4以及之前的版本支持 IE 9 以上的版本。

功能

D3相对底层,代码简洁,学习周期长,可定制化,给予很多自由选择集,操作svg,支持Dom操作,数据处理,数据绑定,结合fetch便捷获取数据。

echarts

开源协议

免费

组件库大小

471KB cdn.bootcss.com/echarts/4.2…

开发维护及社区状态

  • watch:1969
  • star:35598
  • fork:10724
  • issues:2776 open,7756 closed

浏览器兼容性

兼容到IE7,兼容性良好。

功能

上手快、封装度过高、不可定制化、对于开发者设计控制的空间少,比Highcharts图类型多。可操作canvas和svg。

Highcharts

开源协议

非商业免费

组件库大小

233KB cdn.highcharts.com.cn/highcharts/…

开发维护及社区状态

  • watch:359
  • star:8871
  • fork:2323
  • issues:1293 open,8395 closed

浏览器兼容性

支持iPhone,iPad 和 IE6 以上的版本

功能

操作svg,封装度高,官方文档比echarts更简洁易懂,个人认为颜值比echarts高,图的种类要比echarts少。

three.js

开源协议

免费

组件库大小

504KB cdn.bootcss.com/three.js/r8…

开发维护及社区状态

  • watch:2456
  • star:53467
  • fork:20199
  • issues:598 open,8378 closed

浏览器兼容性

ie、safari兼容性不太好

功能

3D效果,性能差。

举🌰

接下来针对2D环境下的饼图做一个详细比较。二话不说,翠花先上代码。

D3饼图

// https://observablehq.com/@d3/pie-chart@347
export default function define(runtime, observer) {
  const main = runtime.module();
  main.variable(observer()).define(["md","d3","data"], function(md,d3,data){return(
md`# Pie Chart

This chart shows the estimated population by age in the United States as of 2015. The total estimated population is ${d3.sum(data, d => d.value).toLocaleString()}. Compare to a [donut chart](/@d3/donut-chart).

Data: [American Community Survey](https://www.census.gov/data.html)`
)});
  main.variable(observer("chart")).define("chart", ["pie","data","d3","width","height","color","arc","arcLabel"], function(pie,data,d3,width,height,color,arc,arcLabel)
{
  const arcs = pie(data);

  const svg = d3.create("svg")
      .attr("viewBox", [-width / 2, -height / 2, width, height]);

  svg.append("g")
      .attr("stroke", "white")
    .selectAll("path")
    .data(arcs)
    .join("path")
      .attr("fill", d => color(d.data.name))
      .attr("d", arc)
    .append("title")
      .text(d => `${d.data.name}: ${d.data.value.toLocaleString()}`);

  svg.append("g")
      .attr("font-family", "sans-serif")
      .attr("font-size", 12)
      .attr("text-anchor", "middle")
    .selectAll("text")
    .data(arcs)
    .join("text")
      .attr("transform", d => `translate(${arcLabel.centroid(d)})`)
      .call(text => text.append("tspan")
          .attr("y", "-0.4em")
          .attr("font-weight", "bold")
          .text(d => d.data.name))
      .call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append("tspan")
          .attr("x", 0)
          .attr("y", "0.7em")
          .attr("fill-opacity", 0.7)
          .text(d => d.data.value.toLocaleString()));

  return svg.node();
}
);
  main.variable(observer("data")).define("data", ["d3"], function(d3){return(
d3.csv("https://gist.githubusercontent.com/mbostock/a3541c73fdccd432acc8b11bf9f02641/raw/2bd0fce0bf34b020e93c5f6527b5a9d08c33ff06/population-by-age.csv", d3.autoType)
)});
  main.variable(observer("color")).define("color", ["d3","data"], function(d3,data){return(
d3.scaleOrdinal()
    .domain(data.map(d => d.name))
    .range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), data.length).reverse())
)});
  main.variable(observer("height")).define("height", ["width"], function(width){return(
Math.min(width, 500)
)});
  main.variable(observer("arc")).define("arc", ["d3","width","height"], function(d3,width,height){return(
d3.arc()
    .innerRadius(0)
    .outerRadius(Math.min(width, height) / 2 - 1)
)});
  main.variable(observer("arcLabel")).define("arcLabel", ["width","height","d3"], function(width,height,d3)
{
  const radius = Math.min(width, height) / 2 * 0.8;
  return d3.arc().innerRadius(radius).outerRadius(radius);
}
);
  main.variable(observer("pie")).define("pie", ["d3"], function(d3){return(
d3.pie()
    .sort(null)
    .value(d => d.value)
)});
  main.variable(observer("d3")).define("d3", ["require"], function(require){return(
require("d3@5")
)});
  return main;
}
  • 只有👆代码是不够的,利用D3进行本地开发还需要起一个http-server服务。由于浏览器的安全限制,不能直接读取本地文件。
  • 上面的代码中多次看到selectAll这个函数,D3是利用选择集对DOM进行操作的,虽然操作DOM十分灵活,但大量的DOM操作也会造成性能的下降。
  • 根据D3饼图的代码可以推断出,想要利用好D3,必定要花费一些时间成本。因为D3与echarts和HighCharts相比较较为复杂。echarts和HighCharts较为简单,案例几乎拿起来就能用。甚至HighCharts的图上标有类似手写的注释,十分清楚明了。曾经看过一句话,把D3学习好,甚至可以手写一个echarts/HighCharts。虽然有些夸张,但是D3的学习成本明显比其他两个工具要高。
  • D3的一个功能使是echarts和HighCharts望其项背。D3两个或多个不同类型的图表,用户对其中一个图表进行交互操作,其他图表可以很流畅的进行交互变化。

echarts饼图

option = {
    title : {
        text: '某站点用户访问来源',
        subtext: '纯属虚构',
        x:'center'
    },
    tooltip : {
        trigger: 'item',
        formatter: "{a} <br/>{b} : {c} ({d}%)"
    },
    legend: {
        orient: 'vertical',
        left: 'left',
        data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
    },
    series : [
        {
            name: '访问来源',
            type: 'pie',
            radius : '55%',
            center: ['50%', '60%'],
            data:[
                {value:335, name:'直接访问'},
                {value:310, name:'邮件营销'},
                {value:234, name:'联盟广告'},
                {value:135, name:'视频广告'},
                {value:1548, name:'搜索引擎'}
            ],
            itemStyle: {
                emphasis: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }
    ]
};

  • echarts的饼图是不是比D3要简单很多!!!!有木有,拿起来就可以用!!!
  • echarts可以直接本地文件开发,不需要起服务开发。
  • echarts作为百度的一个开源项目,背后有强大的技术团队做支持。翻看近几年网络上对echarts的评价,我发现echarts一直在拉近与其他可视化框架的距离,提升的速度很快。 -由👆的代码可以看出,echarts的封装性过高,不可定制化,不能像D3一样想画什么画什么。
  • echarts的浏览器兼容性比D3好很多。

HighCharts饼图

var chart = Highcharts.chart('container', {
	chart: {
		type: 'pie'
	},
	title: {
		text: 'Browser market share, January, 2015 to May, 2015'
	},
	subtitle: {
		text: 'Source: <a href="http://netmarketshare.com/">netmarketshare.com</a>'
	},
	yAxis: {
		title: {
			text: 'Total percent market share'
		}
	},
	plotOptions: {
		pie: {
			animation: {
				duration: 2000
			},
			dataLabels: {
				enabled: false
			},
			shadow: false,
			center: ['50%', '50%']
		}
	},
	tooltip: {
		valueSuffix: '%'
	},
	series: [{
		name: 'Inner',
		data: browserData,
		size: '40%'
	}, {
		name: 'Outer',
		data: versionsData,
		size: '80%',
		innerSize: '60%'
	}]
});

  • HighCharts的代码风格是不是与echarts很接近,同样都是拿来就可以用。
  • HighCharts可以直接本地文件开发,不需要起服务开发。
  • 我个人认为HighCharts的颜值要比echarts高,并且中文文档写的更清楚易懂。
  • HighCharts同样封装度过高。
  • HighCharts图表种类少于echarts。HighCharts有15个种类,而echarts有21个种类。
  • HighCharts是这三种可视化工具中唯一商业收费的工具。

总结

可视化工具 学习成本 难易程度 是否开源 兼容性 本地开发环境 图形种类限制
D3 开源 IE兼容性差 需要http-server服务 想画什么画什么
echarts 开源 兼容性良好 不需要node服务 可以画21种封装好的图表
HighCharts 商业收费 兼容性良好 不需要node服务 可以画15种封装好的图表