用 node.js 实现一个命令行可视化库
# 用 node.js 实现一个命令行可视化库
# 前言
在准备一个爬虫项目时突发奇想,能不能把数据在命令行中展示出来?于是有了c-chart (opens new window)这个库。
目前支持两种简单的类型,未来可能会支持更多图表类型:
- [x] 柱状图
- [x] 散点图
# 效果展示
使用很简单,首先安装依赖:
npm i c-chart
然后调用默认导出的 print
方法,根据传参即可绘制对应的图表。如果需要直接使用打印的字符串,也可以通过 generate
方法获取
# 柱状图
import print from "c-chart";
print({
type: "bar",
data: [5, 7, 3, 2],
direction: "y"
});
2
3
4
5
6
↑ _
| | |
| | |
| _ | |
| | | | |
| | | | |
| | | | | _
| | | | | | | _
| | | | | | | | |
+-------+------+------+------+---------→
2
3
4
5
6
7
8
9
10
通过传入 direction: 'x'
,可以改变柱状图的方向为横向
import print from "c-chart";
print({
type: "bar",
data: [5, 7, 3, 2]
});
2
3
4
5
+--------------------------------------→
|
|_______________________
|_______________________|
|______________________________________
|______________________________________|
|________
|________|
|_
|_|
|
|
|
↓
2
3
4
5
6
7
8
9
10
11
12
13
14
# 散点图
type 为 scatter,传入二维数组的 data,每个元素代表其横纵坐标的取值即可
import print from ".";
print({
type: "scatter",
data: [
[10.0, 8.04],
[8.07, 6.95],
[13.0, 7.58],
[9.05, 8.81],
[11.0, 8.33],
[14.0, 7.66],
[13.4, 6.81],
[10.0, 6.33],
[14.0, 8.96],
[12.5, 6.82],
[9.15, 7.2],
[11.5, 7.2],
[3.03, 4.23],
[12.2, 7.83],
[2.02, 4.47],
[1.05, 3.33],
[4.05, 4.96],
[6.03, 7.24],
[12.0, 6.26],
[12.0, 8.84],
[7.08, 5.82],
[5.02, 5.68]
]
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
↑
| * * *
| * *
| * * * *
| * * * * *
| * * *
| *
| * *
| *
+*-------------------------------------→
2
3
4
5
6
7
8
9
10
# 实现思路
和 echarts 等 web 端可视化框架一样,命令行中画图仍然是在处理以下内容:
- 绘制
- 坐标系
- 数据度量
# 1. 绘制
绘制功能是画图的基础,对于不同的平台有不同的底层实现,如使用 canvas、svg 等。
而在命令行中,方案则是字符串。在c-chart (opens new window)中,一个图表本质上是一个二维数组 graph
,每个元素 graph[i][j]
代表该点的内容;然后通过 join 组成字符串,最后通过 console.log 显示到命令行。
因此,绘图的过程,也就是确定二维数组 graph 中每个元素,该由什么字符填充。
由此,可以实现一些可复用的绘制方法,如直线填充,矩形填充等,供后续使用
# 2. 坐标系
c-chart (opens new window)中的坐标系分为了纵向和横向两种,取决于 direction
参数。
坐标轴本质上就是原点加两条直线(以及末尾的箭头)。而坐标轴的长度,则取决于用户传入的 size
参数
# 3. 数据度量
数据度量的工作用于格式化、统一用户传入的 data 。
- data 中的数据可能很大或很小,所以需要确定一个合适的比例尺
- 字符串的图表只支持整数,所以需要对数据做取整操作
- data 中最大值和最小值的差值可能很大,而最终表格中能展现的差异是有限的,所以只能保证其相对大小的正确
概括来讲就是,假设 data 中原数据位于区间[min,max]
,坐标轴中可供绘制的部分长度为 len
:
则该部分的问题转化为了将区间[min,max]
的元素映射至区间[1,len]
。
经过映射后,即得到了可绘制的横纵坐标。