背景
目前团队在可视化图表这里采用的Echarts来展示数据, 类似也是用第三方组件库提供的API,但在有的时候还是满足不了业务百变的需求。
预研目标
- 使用D3技术实现可视化功能
简介
D3是一个js可视化工具库,功能非常强大,就像给你一张纸和一枝笔,随心所欲,想怎么画就怎么画,非常符合任性的我们。它借助html、svg以及css,可以把我们抽象的数据,形象鲜活的呈现出来。
D3与Echarts的对比
任何一款工具型产品,在产品设计时都遇到“自由度”和“简便性”两者间的权衡与取舍,而往往这两者很难兼得。
echarts 使用简单而自由度差, d3 自由度好而学习门槛高。
官方学习参考资料:
https://github.com/d3/d3/wiki/API–%E4%B8%AD%E6%96%87%E6%89%8B%E5%86%8C
为了理解关于 D3 的基本概念,我们从github找到示例,然后对照API了解相关功能,而后就行复杂业务的开发。
简易买一本书来同步学习,先尝试实现简单的图形,如果可以的话最好了解一下函数式编程的curry与compose思想。慕课网入门视频地址:https://www.imooc.com/learn/103
学习之后,完成了几个简易图表的开发,DEMO部署地址为:http://172.22.2.20:8010/index.html
实现类似功能代码如下(同为柱形图):
D3代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" content="">
<title>for test</title>
<style type="text/css">
#container {
width: 500px;
height: 250px;
background: #eee;
}
path {
fill: none;
stroke-width: 1;
stroke: #468284;
}
.tick line {
stroke-width: 1;
stroke: black;
}
</style>
</head>
<body>
<div id="container">
</div>
<script type="text/javascript" src="d3.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.js"></script>
<script>
var svgW = 500,
svgH = 250,
margin = {
left: 50,
top: 30,
right: 20,
bottom: 20
},
g_width = svgW - margin.left - margin.right,
g_height = svgH - margin.top - margin.bottom;
var svg = d3.select('#container')
.append('svg')
.attr('width', svgW)
.attr('height', svgH);
var g = d3.select('svg').append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
var data = [1, 3, 5, 7, 8, 4, 3, 7]
// 一个线性比例尺
var scale_x = d3.scale.linear()
// 定义域: 坐标系下的值(输入范围)
.domain([0, data.length - 1])
// 值域,就是映射到svg画布上的值 (输出范围)
.range([0, g_width]);
// 一个线性比例尺
var scale_y = d3.scale.linear()
.domain([0, d3.max(data)])
.range([g_height, 0]);
// 线形图表
// var line_generator = d3.svg.line()
// 面积型图表
var area_generator = d3.svg.area()
.x(function(d, i) {
return scale_x(i);
})
// .y(function(d) {
// return scale_y(d);
// })
.y0(g_height)
.y1(function(d) {
return scale_y(d);
})
.interpolate('cardinal');
g.append('path')
// .attr('d', line_generator(data));
.attr('d', area_generator(data))
.style('fill', 'steelblue');
// 创建一个新的轴生成器
var x_axis = d3.svg.axis().scale(scale_x);
y_axis = d3.svg.axis().scale(scale_y).orient('left');
g.append('g')
.call(x_axis)
.attr('transform', `translate(0, ${g_height})`);
g.append('g')
.call(y_axis)
.append('text')
.text('Price($)')
.attr('transform', `rotate(-90)`)
.attr('text-anchor', 'end')
.attr('dy', '1em')
// .attr('transform', `translate(0, ${g_width})`);
</script>
</body>
</html>
echarts
// 按需引入
const echarts = require('echarts/lib/echarts');
require('echarts/lib/component/grid');
require('echarts/lib/chart/line');
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;
option = {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
smooth: true,
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
areaStyle: {}
}]
};
option && myChart.setOption(option);
D3适用场景
- 灵活性高、交互多的业务图表(框架不能实现图表)
难点
- 知识涉及底层,需要花费一定的时间,进行基础知识的学习
结论:
d3完全可以引入团队技术栈,在图表灵活性上加以提高。