做为一个前端打字员,除了绿茶婊以外,最讨厌的就是图表:一个让我伤心,一个让我难过;比这更讨厌的就是文档写得不清不楚的图表库(大几率是九年义务教育期间没有学好语文),让我又爱又恨!因此本篇博文会比较枯燥,只简单描述一下使用BizCharts的过程,固然,重要的是总结遇到的坑(听从一个坑不踩两次,一个女生不泡两次原则)。前端
By the way,提到BizCharts,让咱们感谢一下阿里巴巴:其开源了这个好用的(虽然偶尔不那么好用,还偶得挺常常的)的react图表库供你们使用,对使用react技术栈的前端打字员来讲简直就是福音。本文不会有过多的api解释,具体的接口能够看官网文档鬼门关。react
刚开始,视觉设计师哄我说:“个人要求并不高,待我从前同样好”,啊呸,说错了,“个人要求是:只要能把数据用直方图展示出来就行了”,so easy程序员
// 引入相关的组件
import { Chart, Axis, Tooltip, Geom } from 'bizcharts';
// 随便mock一下数据
const str = ['we', 'are', 'the', 'black', 'gold', 'team'];
const mockData = () => {
let result = [];
for (let i = 0, len = 6; i < len; i++) {
result.push({
xAxis: ticks[i],
yAxis: Math.floor(Math.random() * 100)
});
}
return result;
};
// 图表组件
<Chart
width={ 600 }
height={ 400 }
data={ mockData() }
>
{/* x轴,横轴,以data数据的xAxis属性值为柱子的值 */}
<Axis name="xAxis" />
{/* y轴,纵轴,以data数据的yAxis属性值为柱子的值 */}
<Axis name="yAxis" />
{/* 鼠标hover直方图柱子的时候,tooltip显示的值 */}
<Tooltip />
{/* 几何标记对象,主要用以描述你要画的是什么图形(直方图、折线图、饼状图、区域图):interval是直方图 */}
<Geom
type="interval"
position="xAxis*yAxis"
/>
</Chart>
复制代码
一波操做猛如狗,让视觉设计师看看效果:npm
note:此直方图每一根柱子都是单点的,也就是其反映了某个横坐标点的数据状况。加入咱们须要一个连续区间柱子,那么做为xAxis的数据字段值应该为一个数组,包含两个元素,代表区间的起始值。json
const mockData = () => {
let result = [];
for (let i = 0, len = 6; i < len; i++) {
result.push({
xAxis: [i + 0.01, i + 1 - 0.01], // 若是不加减0.01,那么第一根柱子的终点跟第二根柱子的起点是同一个,会感受两个柱子粘在一块儿
yAxis: Math.floor(Math.random() * 100)
});
}
return result;
};
复制代码
视觉设计师:“emmmmmm,图表长宽定死了会不会有点僵硬啊,高度能够写死,宽度总得来个自适应吧?”api
“毛闷台”数组
<Chart
height={ 400 }
data={ mockData() }
forceFit // 我妈说了(guanfang wendang shuode),加上这个属性就可使图表宽度自适应了,隔壁echart同窗要学习一下
>
</Chart>
复制代码
效果秀一波dom
视觉(蜜汁微笑):“猿子,你这玩意有bug啊”ssh
“胡说,你这傻*不会用吧”函数
(义正词严)“哼哼,放大窗口图表宽度确实会自适应,可是缩小就挂掉了(并不自适应),ahhhhhh”
(谄媚)“讨厌,再给我两分钟~~让我把bug结成冰。。。”
note: 实验代表,若是Chart组件的父组件Father采用flex布局,即Father使用flex自适应宽度,那么就会出现上述的问题;因此,若是有多个图表同行并列布局,请不要使用flex布局,给Father组件的宽度设置为百分比吧,此时的forceFit就会起做用了。同时,BizCharts对重绘设置了防抖,只有当中止缩放的时候才会重绘。
(屌到飞起)“over,拿去用吧”
(一脸鄙视)“哇喔~好棒棒呀,敢不敢让我调一点点小细节,我保证就一点点!”
“Come on baby!”
“
”
把视觉杀了以后,需求仍是要作的,先解决死者的第一个遗愿。
Tooltip组件提供了一个属性crosshairs,用以设置tooltip的辅助线和辅助框;默认状况下,此属性会为’line’、‘area’、‘path’、‘areaStack’类型的Geom组件开启垂直辅助线、为‘interval’类型的Geom组件展现矩形背景框。死者说的很丑的方框就是这个!
<Tooltip crosshairs={ false }/>
复制代码
好的,把框去掉了!咦,咱们不是说要修改它的颜色吗?好的,改一下
<Tooltip
crosshairs={{
type: "rect" // 可选值:rect、x、y、cross,分别对应辅助狂、平行x轴辅助线、平行y轴辅助线,十字辅助线
style: {
fill: 'red', // 辅助框颜色
shadowColor: 'red', // 辅助框周边阴影的颜色
shadowBlur: 1, // 辅助框周边阴影的透明度
opacity: 0 // 辅助框的透明度
}
}}
/>
复制代码
note:假如开启的是辅助线,即type不是“rect”,那么上述的样式定义将不起做用。究其缘由,看了此组件的源码以后才发现,描述辅助线样式的属性不是style对象,而是lineStyle对象,官方文档并未说明这一点。
<Tooltip
crosshairs={{
type: "y"
lineStyle: {
stroke: 'red', // 辅助线颜色
lineWidth: 4, // 辅助线宽度,单位为px
opacity: 1 // 辅助线透明度
}
}}
/>
复制代码
看起来仍是很容易就实现了死者的第一个遗愿,就这样怼死了视觉,是否是太残忍了点?事已至此,继续实现他的遗愿吧。
第二个遗愿是给tooltip换个样式。既然要修改tooltip的样式,就应该继续对Tooltip组件下手。经过阅读文档,发现其还有一个itemTpl的属性,也就是能够经过这个属性定义tooltip的模板
// 定义一个模板
// name-value是相关柱子的key-value值
const tooltipsDisplayTpl = ` <p class="chart-tooptip"> <span class="chart-tooptip-right">{name}</span> <span>{value}</span> </p> `;
/* // 重写tooltip元素的样式 // 由于视觉已死,样式是随便搞的,就弄点黑色背景当默哀一下吧 .g2-tooltip { background-color: rgba(44, 49, 68, 0.80) !important; } .chart-tooptip { margin: 0; color: white; } .chart-tooptip-right { margin-right: 12px; } */
<Tooltip
crosshairs={ false }
itemTpl={ tooltipsDisplayTpl }
showTitle={ false } // 去头(标题,即横轴对应的刻度),每每影响我颜值的不是个人身材,而是个人脸,因此不要脸了
/>
复制代码
note:若是想自定义tooltip展现的内容,还须要设置Geom组件的tooltip属性,即将数据映射到Tooltip对象上;因此此属性值若是为false的话,就不会向Tooltip组件传递任何数据(此时Tooltip只会显示title);还可设置为字符串,展现字符串对应的数据字段;But, it's not the point,重点在于可自定义
// 定义数据返回的格式,name属性对应的是itemTpl里面的同名变量
const getTooltipData = (xAxis, yAxis) => {
return {
name: xAxis,
value: yAxis
};
}
<Geom
type="interval"
position="xAxis*yAxis"
tooltip={["xAxis*yAxis", getTooltipData]}
/>
复制代码
第二个遗愿也实现了,愧疚感也多了一点!最主要是写代码的时候总是以为后面有人站着盯着我看。
说不定实现全部遗愿就不会有这种感受了呢,那就继续第三个遗愿吧:“改变鼠标hover柱子时候柱子的颜色”,翻遍了整个文档,发现没有关于hover的接口啊!看来视觉是要抱恨终天了,阿门。
就在我感受到后背愈加的凉飕飕的时候,我发现Geom组件有一个属性active
文档就真的描述了那么两句话,也没例子。急病乱投医的我只能尝试一波,设置为true,得了,hover柱子的时候柱子颜色改变了!!!
<Geom
type="interval"
position="xAxis*yAxis"
tooltip={["xAxis*yAxis", getTooltipData]}
active={ true }
/>
复制代码
那若是须要自定义鼠标hover柱子的样式呢?对照着Geom文档的select属性,又尝试了一遍
<Geom
type="interval"
position="xAxis*yAxis"
tooltip={["xAxis*yAxis", getTooltipData]}
style={{ cursor: 'pointer' }} // 鼠标hover上去的时候,显示小手手,免费送的
active={[
true,
{
style: {
fill: 'black', // 柱子颜色,继续默哀
shadowColor: 'red', // 总体阴影颜色,包括边缘
shadowBlur: 1, // 阴影的透明度
opacity: 0 // 柱子颜色透明度
}
}
]}
/>
复制代码
(神气的)“狗子,别死了,老子搞定啦”
“靠,我都装死两天了,你敢不敢再慢一点”
“那官方文档就写了一行字:只可意会不可言传!我天分有限,意会了比较久”
“嘚瑟,看,又出bug了吧!你的表子一闪一闪的”
(掐着他脖子使劲晃)“那TM不是bug!!!”
不过话说回来,当数据更新时,从旧数据切换到新数据,会很突兀,没有缓冲过程,看着特别不舒服。我寻思着,在数据更新的时候,加个动画呗!可是初始动画生效了,更新动画就不生效了(如看官们知道解决办法,请不吝赐教)。因为赶着下班,我决定使用DataSet:一个用于管理表格数据的神器,听说更新数据的时候,其会给我弄个动画(除此之外有方便地导入非json数据等等功能,下文有一些例子,具体细节我没有详细去研究,之后学习了再分享)。唔好理,总之好犀利!
// 安装
// npm install @antv/data-set
// 引入
import DataSet from '@antv/data-set';
// 生成一个View实例,做为类的属性,故不要在render方法里面生成这个实例
dv = new DataSet().createView();
render() {
this.dv.source(data);
<Chart height={ 400 } data={ this.dv } forceFit ></Chart>
}
复制代码
“猿子,6啊!吃宵夜吗?个人”
“虽然不怎么饿,可是你请就不同了,go”
吃了一桶泡面后......
“猿子,你看,宵夜也吃了·······”
“你又想干吗···············”
简直就是饱饭思淫欲啊!!!
”我只是以为柱子的颜色能够渐变会显得咱们公司的产品更屌一点“
”狗子,你扛揍不?“
(可怜兮兮)”揍完以后能够加个渐变吗......“
”......“
”我就知道你对我最好了,我给你捶背捏大腿吧~“
”滚一边去“
<Geom
type="interval"
position="xAxis*yAxis"
tooltip={["xAxis*yAxis", getTooltipData]}
color={['xAxis', '#3DA4FF-#FFFFFF']}
/>
复制代码
(掐着我脖子使劲晃)”老子要的是从上往下渐变,不是从左往右渐变“
“别.....别.....掐.....我....改....改.....”
<Geom
type="interval"
position="xAxis*yAxis"
tooltip={["xAxis*yAxis", getTooltipData]}
color={['xAxis', 'l(90) 0:#3DA4FF 1:#FFFFFF']}
/>
复制代码
note:l是指线性渐变,90是指旋转九十度(即从上到下渐变,看官们能够多试试几个姿式,啊呸,多试试几个角度)
0和1标定的色值标明初始色值和终止色值,注意一点,色值不可使用颜色名字,如“red”、“blue”等
可添加多个渐变色值,如
color="l(90) 0:#000000 0.5:#FFFFFF 1:#000000"
复制代码
note:若是是area类型的Geom,那么第一种渐变方式是不起做用的,只能选用第二种
“狗子,我真要下班了”
“那个,你看都搞着渐变了,要不搞一波颜色分类”
”没得谈,goodbye!“
”宵夜个人“
”顶你个肺,又想用泡面忽悠我!!!“
”撸串,骗你我是狗“
”emmmmmm.....“
既然提到颜色分类,咱们就接着提一下dv.transform 吧, dv.transform内置了一些基础的函数:filter,map,pick,rename,reverse …… 具体可自行查看文档
只须要添加 groupBy 字段,而且在传入的原始数据data中添加对应的字段classify便可轻松搞定。
dv.transform({
groupBy: ['classify'], // 以classify字段进行分组
});
复制代码
”猿子,颜色仍是要自定义的哦“
(白眼)
<Geom
position={'xAxis*yAxis'}
color={['classify', classify => {
// 这里根据不一样字段返回不一样颜色
return classify === 'test' ? 'red' : 'yellow';
}]}
style={{ cursor: 'pointer' }}
/>
复制代码
做为一个有责任的前端打字员,有一点即便设计不要求的,我仍是须要说明的,横轴的刻度值是能够自定义的
<Axis
name={xAxis}
label={{
textStyle: {
fill: 'red', // 颜色
textBaseline: 'top' // 对齐基线
},
formatter: (val) => {
return `${ val }\n换行了`
}
}}
/>
复制代码
”狗子,撸串去!!!“
”要不仍是吃个泡面????“
狗子,卒!
感谢看官们看完了个人胡扯,须要更正一点的是,我司程序员与视觉、交互设计师的相处是很是友爱和气的。以上总结,仅参考学习之用,不喜勿喷;若有错漏,欢迎指正。
@Author: beidan, PaperCrane