我们从一个静态的散点图开始讲述一个故事。简单的实例,开始你的数据可视化。
你需要准备:
一台联网的电脑;
一个代码编辑器,支持javascript编写(甚至只是一个txt编辑器);
一个充满好奇心的大脑;
正式开始
-
数据获取:
数据通常可以直接由他人提供。你的同事们经常可以替你分担数据收集这份工作(埋点日志或者其它数据统计)。如果你计划制作几个图表用于描述情况,或者领导希望你能分析年度的数据,那么你通常能拿到一些excel或者其它的电子表格;如果你计划设计一个数据监控后台,那么你的数据来源就是后端的研发同事。
ECharts的不同图表需要不同形式的数据,但通常都是json格式。我们现在绘制的散点图,需要的数据是二维结构。ECharts官网有一个表格工具,利用这个工具,可以轻松地将excel表转化为可用的数据结构。
这里直接给出我们的第一份数据(json格式)。你可能注意到数据被一个函数index()包含,这个单纯为了避免浏览器的跨域问题。你无需下载数据,根据后文内容直接引用地址即可。
-
数据分析:
数据是笔者直接提供的,所以至少在格式上不存在问题。但对于数据内容,你绝对不应该认为它是正确无疑的。
记住,绝不能只因为它是数字就相信它就是正确的
我们要注意的是那些不太对头的东西···如果任何东西看上去有些异常,我们就需要到源头去进行验证。
大部分异常都只是笔误而已,但有些异常却真的存在,而它们就是有意思的地方。可以作为故事重点。
不过笔者不希望第一个故事就如此复杂。笔者将在文末讲解如何筛选无意义或错误数据,最终获得可用的数据的具体方法。
-
初始图表:
打开你的编辑器,是时候写(粘贴)一波代码了。
-
引入ECharts:不需要考虑太多,将下文的代码全部粘贴到你的编辑器中就好了。代码几乎引入了你全部可能用到的库,后续编写其它的图表也可以继续沿用这个head。
ECharts -
接下来我们在
中完成我们的内容(不必担心,笔者会在最后给出完整代码):-
为ECharts准备一个具备大小(宽高)的容器:
-
准备一个javaScript块,后续内容都在其中完成:
-
基于准备好的容器,初始化ECharts实例(//之后内容为注释,不会影响你的代码):
-
使用 option 来表述图表信息:数据,数据如何映射成图形,交互行为。具体可查看代码内注释:
var option = { //图表标题,当前为空 title: {}, //提示框,当前为空 tooltip: {}, //横坐标设置,当前仅设置类别为‘category‘,即‘类目’ xAxis: { type: 'category', }, //纵坐标设置,当前仅设置类别为‘value‘,即‘值’ yAxis: { type: 'value', }, //坐标系设置,如上下左右离边框距离等属性,当前为空 grid: {}, //系列列表,用于指定图表名称、类型,数据等,当前类型为‘scatter’,即‘散点图’;数据有四行,每个类目对应一个值,将绘制一幅包含四个点的散点图 series: [{ name: 'scatter', type: 'scatter', data: [ ["安徽省当涂第一中学",61], ["安徽省六安第一中学",14], ["安庆市第十一中学校",4], ["安庆市第一中学",36], ] }] };
-
使用刚指定的配置项和数据显示图表:
// 使用刚指定的配置项和数据显示图表。 myChart.setOption(option);
完成!
-
-
当前全部的代码如下。现在你可以把文件保存为XXX.html,然后用浏览器打开,查看下你使用ECharts绘制的第一幅图表吧(你甚至只需要新建一个txt文件,将代码粘贴进去后保存为.html):
ECharts -
然而现在作为初始的图表还不够格,你肯定不会满足于四个数据的散点图。第一节笔者提供了一个json,里面有400个数据,现在我们使用这份数据进行图表绘制(你将初次接触跨域问题):
引用网络数据并不简单,如果你使用的是chrome浏览器(建议),你将不得不解决跨域问题(简单的说就是数据来源不同于.html文件的地址,chrome会禁止数据的获取)。不过笔者最终找到了一个比较简单的方法(jsonp):
-
回到第二节第5步,完成之后我们将4、5步的内容包含在一个回调函数中。并将 data 指向函数 index (data) 中的 data :
//jsonp读取本地json文件 //回调函数名称(index),需要与 src 中一致,而且要与文件地址中名一致。jsonp格式 名称([]) //不然无法获取到对应的文件 function index(data){ //4、5步完成的内容 var option = { title: {}, tooltip: {}, //xAxis:{}, xAxis: { type: 'category', }, yAxis: { type: 'value', }, grid: {}, series: [{ name: 'scatter', type: 'scatter', //data指向index(data)中的data data: data, }] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); };
-
我们尚未引用网络数据,现在我们完成这个步骤,并回调上文定义的方法。新建一个javaScript块,写入以下内容:
注意,包含的都是注释内容,实际生效的只有包含的代码。其中,src 指向基础数据的地址,这个地址一直到 ?callback 前为止。后文中给出了新的数据地址,你只需要替换代码中的地址即可。
完成!
-
-
现在的完整代码如下。生成的初始图表为:
ECharts 挺不错的嘛!有了初始的图表,现在我们可以对其进行美化,使其更引人注目。
-
-
图表美化:
图表的美化主要依靠修改/增加 option (第二节第4步)中的信息。现在我们依次修改设置,逐步美化图表:
-
我们首先设置一个背景颜色(笔者绘制图表喜欢深色色调)。rgba大家应当非常熟悉,前三个数值设置了颜色,第四个数值制定了颜色的透明程度。现在的颜色相当黑,但不是纯黑(为什么不选择纯黑?):
//背景颜色,当前透明度为100%,接近纯黑色 backgroundColor:'rgba(1, 1, 1, 1)',
-
接下来修改坐标系设置 grid ,令坐标系上下左右分别距离边框一个给定的百分比。我们来看一下现在图表的样式吧:
//坐标系设置,距离上边框较远,左右居中 grid: { left: '5%', right: '5%', top:'15%', bottom: '7%' },
好吧,似乎变得更加难以辨别了(因为坐标系尚未调整,几乎无法辨别,分割线却过于明显)。不要灰心,我们继续编码。
-
表格上方预留了足够的空间,接下来我们设置一下标题内容:
//标题 title: { //标题内容 text: '学校与排课次数散点图', //标题字体颜色及字体大小 textStyle:{ color:'#fff', fontSize:30, }, //离上边框距离 top:'5%', //离左边框距离,当前为‘居中’ left: 'center', },
现在我们有了一个居中置顶(保持一定距离)的标题,你可以保存文件用浏览器查看效果。
-
接下来我们编辑一下两个坐标轴的格式
//横坐标设置 xAxis: { //类型为‘类目轴’,即种类而非数值 type: 'category', //坐标轴刻度文字格式 axisLabel:{ //设置不显示,后续设置无效 show:false, }, //坐标轴线设置 axisLine:{ lineStyle:{ color:'#fff',//坐标轴颜色为白色 width:2,//坐标轴线宽度2个像素 } } },
横坐标我们设置其不显示刻度上的各标签(因为标签过多无法全部显示,也显示必要性)。坐标轴线为白色,这样在深色背景下容易辨认。坐标轴分割线无需设置,因为当前为类目轴,无分割线。
//纵坐标设置 yAxis: { //类型为‘数值轴’,自带分割线 type: 'value', //纵坐标轴名称 name:' (次)', //坐标轴名称格式设置 nameTextStyle:{ //设置行高及对齐方式,使得坐标轴名称达到图形所示效果 fontSize:20,//字体大小 verticalAlign:'top',//垂直对齐方式,搭配行高使用,控制垂直方向高度 align:'left',//水平对齐方式 lineHeight:10//行高 }, //data:[50,100],//值范围,本例不使用 //分割线格式设置 splitLine:{ show:true,//显示 //分割线设置 lineStyle:{ opacity:0.3,//透明度:0.3 type:'dotted'//类型,除此之外还有‘solid’‘dashed’,可以切换观察效果 } }, //坐标轴刻度文字格式 axisLabel:{ //通过以下设置,使得坐标轴标签在刻度上方 fontSize:20,//字体大小 align:'right', verticalAlign:'bottom', }, //坐标轴线设置,由于设置的宽度为0,不显示坐标轴 axisLine:{ lineStyle:{ color:'#fff', width:0,//不显示坐标轴 } } },
纵坐标设置较为复杂,我们设置了坐标轴的名称(将显示在坐标轴尾端),规定分割线的透明度为0.3,保证分割线不影响图表观看。调整了坐标轴刻度标签的格式,使其落于刻度之上。最后,我们隐藏了纵坐标轴线,使得整个图表更加凸显重点(散点本身,而非坐标轴)。
现在的图表如下。与上图相比,重点已经相当突出了:
-
还没有结束,深色背景搭配红色散点可不是个好选择。我们应当对散点进行一些格式的设置,使其从背景中抽离出来。这一切都需要在 series 中完成:
series: { name: 'scatter', type: 'scatter', //散点大小,当前为 10 像素 symbolSize:10, //散点格式(非选定状态下) itemStyle:{ color:'red',//颜色为红色 borderColor:'#fff',//边框颜色为白色 borderWidth:2,//边框 2 个像素 shadowBlur:3,//阴影 3 个像素 shadowColor:'#eac736'//阴影颜色,接近于橙黄色,产生光亮效果 }, //散点格式(选定状态下),emphasis即为选中状态,与normal相对 emphasis: { itemStyle: { //color: 'red', borderColor: '#fff',//边框颜色为白色 borderWidth: 5,//边框 5 个像素 shadowBlur: 15,//阴影 15 个像素 shadowColor: '#eac736'//阴影颜色,接近于橙黄色,产生光亮效果 } }, //散点的值(value)格式设置 label: { //仅当选中状态下显示 emphasis: { show: true,//显示 position: 'left',//左侧 //字体格式 textStyle: { color: '#fff',//颜色为白色 fontSize: 16//字体大小 16 个像素 } } }, data: data, },
现在,你的图表应当足够吸引人眼球了。如果你有别的想法,可以根据官方文档,或者在上文的基础上对代码做一些修改。
-
现在给出散点图的完整代码。将其粘贴到你的编辑器中,另存为XXX.html文件然后使用浏览器打开即可。或者新建一个txt文件,将内容粘贴进去,修改后缀为.html,使用浏览器打开同样可以查看结果(当然,笔者希望读者能够按步骤逐渐完成,而不是直接复制最终的代码):
ECharts -
使用 ECharts 的部分基本完成,接下来笔者使用 hype(我们将在另一个手册对其进行介绍) 对图表作进一步改进(读者可以将图表保存为图片,然后进行编辑):
- 分析基础数据,得出中位数及平均数,分别为12和22.7
- 在hype中绘制矢量图形,添加中位数线和平均值线,并分别指出线类型及具体数值
- 也许你对这个背景感兴趣。笔者设置图表的背景透明,然后底层的图形上添加了毛玻璃效果
-
现在图表绘制完成,添加上下文:本图表绘制的是学校使用排课引擎的次数图,每个点指代一个学校,可以看到,多数学校集中在0~30的区间内。少数学校调用次数超过90次,最多的调用为193次。
添加上下文非常重要,因为当你的读者在阅读图表的时候不能保证你总在旁边。我们的散点图如果没有标题及上下文,读者根本不可能知道其代表的意义(或许是公司员工迟到分钟数?那最高值很可能是笔者本人)。
-
-
该图表的意义:
散点图展示了一段时间内300余所学校调用排课引擎的情况。我们预期的调用次数应当在10次左右,并且多次的调用没有实际意义(具体不做解释)。但实际情况可以看到,平均数比中位数多10,存在相当多的点调用次数在30次以上,最高的点调用次数为193次。
散点的集中状态基本符合预期,但是调用次数多的点明显存在问题。应当对其进行记录,观察是否存在地域特征,做进一步分析。
-
数据图表相互演进:
正如笔者前面所述,数据可视化的流程不是线性的。只需要简单调整一下数据的输入,即便是同一套数据,也会呈现出不同的效果。
-
笔者按排课次数排序,得到了新的基础数据。可以看到,各点不再散乱分布于各处,而是按从小到大依次排序,呈现出指数函数一般的图形(显然我们的数据本身并不具备指数函数的特征)。
现在,根据这张图表,你能得到哪些信息?(别忘了,我们的中位数是12,平均值是22.7)
-
笔者按地区排序,再次得到了新的基础数据。新的图表似乎与之前并没有什么区别。你可以试着在图表上将各个区域划分开(从左到右),观察不同区域(政策)之间是否存在着点位分布上的规律。
实际上规律并不明显,你可能只感觉到福建和广东地区相比其它地区点位更加散乱一些。不如试着统计下各地区的中位数和平均数?这里列举一些地区的数值:
- 北京:「中位数:11」,「平均数:22.6」
- 福建:「中位数:25」,「平均数:36.6」
- 广东:「中位数:13」,「平均数:27.6」
结果确实如此,福建的两个数值都远远超过平均值。现在你的故事开始有趣起来了,你应该把它讲给你的福建同事听,询问他们其中的原因。这些应该能对你的产品改进提供帮助。
-
两者结合或许也会非常有趣,如果你有时间,可以试着先按地区排序,再把地区内部按次数排序,这里笔者就不再赘述,只给出最终图表,你能从中分析出什么结果?
-
故事结束
第一个故事到此差不多也可以结束了。
你可能觉得作为第一个入门故事,代码内容有点过多,这一点笔者也深有同感。但因为对于不同的图表,ECharts的编码内容基本相同(坐标系设置,内容设置),举一反三相当简单,所以笔者尽量对每一行代码做了解释。后续笔者的编码介绍内容将逐渐简化(不要担心,笔者总会给出完整代码),而把重点放在数据分析和图表美化(当然也少不了图表本身的分析),以及通过一些初级的 javaScript 编码实现简单交互上。
好了,休息一下,倒杯热茶,然后开始我们的第二个故事。