BizCharts使用采坑教程

 
了不得的BizCharts

最近项目的管理后台都在用阿里粑粑开源的管理框架Ant Design Pro,说真话,仍是比较好用的。该框架内部也封装了一些图标插件,可是在最近的一个项目中发现,这些图标可定制性仍是差了点,不能知足客户需求。html

好在它的后面也介绍了本身亲生的BizChart可视化图表组件,由于定制性比较高,可是api中的介绍又不是每一个都有例子,更没有组合使用的例子,通过度娘介绍,发现这片文章备受我青睐,我怕做者哪天不高兴放弃了,因此转存了一份,顺便把本身实践到的补充到后面。前端

原文

做为一个前端打字员,除了绿茶婊以外,最讨厌的就是图表:一个让我伤心,一个让我难过;比这更讨厌的就是文档写得不清不楚的图表库(大几率是九年义务教育期间没有学好语文),让我又爱又恨!因此本篇博文会比较枯燥,只简单描述一下使用BizCharts的过程,固然,重要的是总结遇到的坑(听从一个坑不踩两次,一个女生不泡两次原则)。react

By the way,提到BizCharts,让咱们感谢一下阿里巴巴:其开源了这个好用的(虽然偶尔不那么好用,还偶得挺常常的)的react图表库供你们使用,对使用react技术栈的前端打字员来讲简直就是福音。本文不会有过多的api解释,具体的接口能够看官网文档鬼门关。npm

正经篇幅

刚开始,视觉设计师哄我说:“个人要求并不高,待我从前同样好”,啊呸,说错了,“个人要求是:只要能把数据用直方图展示出来就行了”,so easyjson

// 引入相关的组件
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>

一波操做猛如狗,让视觉设计师看看效果:api

 
数据可视化,BizCharts图表库入坑历程

note:此直方图每一根柱子都是单点的,也就是其反映了某个横坐标点的数据状况。加入咱们须要一个连续区间柱子,那么做为xAxis的数据字段值应该为一个数组,包含两个元素,代表区间的起始值。数组

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; };
 
 
 
BizChart2.jpg

视觉设计师:“emmmmmm,图表长宽定死了会不会有点僵硬啊,高度能够写死,宽度总得来个自适应吧?”bash

“毛闷台”antd

<Chart height={ 400 } data={ mockData() } forceFit // 我妈说了(guanfang wendang shuode),加上这个属性就可使图表宽度自适应了,隔壁echart同窗要学习一下
    >
</Chart>

效果秀一波app

 
数据可视化,BizCharts图表库入坑历程

视觉(蜜汁微笑):“猿子,你这玩意有bug啊”

“胡说,你这傻*不会用吧”

(义正词严)“哼哼,放大窗口图表宽度确实会自适应,可是缩小就挂掉了(并不自适应),ahhhhhh”

(谄媚)“讨厌,再给我两分钟~~让我把bug结成冰。。。”

note: 实验代表,若是Chart组件的父组件Father采用flex布局,即Father使用flex自适应宽度,那么就会出现上述的问题;因此,若是有多个图表同行并列布局,请不要使用flex布局,给Father组件的宽度设置为百分比吧,此时的forceFit就会起做用了。同时,BizCharts对重绘设置了防抖,只有当中止缩放的时候才会重绘。

 
数据可视化,BizCharts图表库入坑历程

(屌到飞起)“over,拿去用吧”

(一脸鄙视)“哇喔~好棒棒呀,敢不敢让我调一点点小细节,我保证就一点点!”

“Come on baby!”

  1. 鼠标hover柱子的时候,为何柱子后面有个很丑的方框,换个颜色吧!
  2. 鼠标hover柱子的时候,出现的tooltip样式丑爆了,待会我给你设计一个吧
  3. 鼠标hover柱子的时候,柱子的颜色应该有所改变,对用户比较友好!!!
  4. ...哎,你别拿刀啊~~~

把视觉杀了以后,需求仍是要作的,先解决死者的第一个遗愿。

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 // 辅助框的透明度
 } }} />
 
数据可视化,BizCharts图表库入坑历程

note:假如开启的是辅助线,即type不是“rect”,那么上述的样式定义将不起做用。究其缘由,看了此组件的源码以后才发现,描述辅助线样式的属性不是style对象,而是lineStyle对象,官方文档并未说明这一点。

<Tooltip crosshairs={{ type: "y" lineStyle: { stroke: 'red', // 辅助线颜色
                lineWidth: 4, // 辅助线宽度,单位为px
                opacity: 1 // 辅助线透明度
 } }} />
 
 
 
数据可视化,BizCharts图表库入坑历程

看起来仍是很容易就实现了死者的第一个遗愿,就这样怼死了视觉,是否是太残忍了点?事已至此,继续实现他的遗愿吧。

第二个遗愿是给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 } // 去头(标题,即横轴对应的刻度),每每影响我颜值的不是个人身材,而是个人脸,因此不要脸了
    />
 
 
 
数据可视化,BizCharts图表库入坑历程

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]} />

 
数据可视化,BizCharts图表库入坑历程

第二个遗愿也实现了,愧疚感也多了一点!最主要是写代码的时候总是以为后面有人站着盯着我看。

说不定实现全部遗愿就不会有这种感受了呢,那就继续第三个遗愿吧:“改变鼠标hover柱子时候柱子的颜色”,翻遍了整个文档,发现没有关于hover的接口啊!看来视觉是要抱恨终天了,阿门。

就在我感受到后背愈加的凉飕飕的时候,我发现Geom组件有一个属性active

 
数据可视化,BizCharts图表库入坑历程

文档就真的描述了那么两句话,也没例子。急病乱投医的我只能尝试一波,设置为true,得了,hover柱子的时候柱子颜色改变了!!!

<Geom type="interval" position="xAxis*yAxis" tooltip={["xAxis*yAxis", getTooltipData]} active={ true } />
 
数据可视化,BizCharts图表库入坑历程

那若是须要自定义鼠标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 // 柱子颜色透明度
 } } ]} />

 
数据可视化,BizCharts图表库入坑历程

(神气的)“狗子,别死了,老子搞定啦”

“靠,我都装死两天了,你敢不敢再慢一点”

“那官方文档就写了一行字:只可意会不可言传!我天分有限,意会了比较久”

“嘚瑟,看,又出bug了吧!你的表子一闪一闪的”

(掐着他脖子使劲晃)“那TM不是bug!!!”

 
数据可视化,BizCharts图表库入坑历程

不过话说回来,当数据更新时,从旧数据切换到新数据,会很突兀,没有缓冲过程,看着特别不舒服。我寻思着,在数据更新的时候,加个动画呗!可是初始动画生效了,更新动画就不生效了(如看官们知道解决办法,请不吝赐教)。因为赶着下班,我决定使用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>
    }
 
数据可视化,BizCharts图表库入坑历程

“猿子,6啊!吃宵夜吗?个人”

“虽然不怎么饿,可是你请就不同了,go”

吃了一桶泡面后......

“猿子,你看,宵夜也吃了·······”

“你又想干吗···············”

简直就是饱饭思淫欲啊!!!

”我只是以为柱子的颜色能够渐变会显得咱们公司的产品更屌一点“

”狗子,你扛揍不?“

(可怜兮兮)”揍完以后能够加个渐变吗......“

”......“

”我就知道你对我最好了,我给你捶背捏大腿吧~“

”滚一边去“

<Geom type="interval" position="xAxis*yAxis" tooltip={["xAxis*yAxis", getTooltipData]} color={['xAxis', '#3DA4FF-#FFFFFF']} />
 
数据可视化,BizCharts图表库入坑历程

(掐着我脖子使劲晃)”老子要的是从上往下渐变,不是从左往右渐变“

“别.....别.....掐.....我....改....改.....”

<Geom type="interval" position="xAxis*yAxis" tooltip={["xAxis*yAxis", getTooltipData]} color={['xAxis', 'l(90) 0:#3DA4FF 1:#FFFFFF']} />

 
数据可视化,BizCharts图表库入坑历程

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' }} />

 
数据可视化,BizCharts图表库入坑历程

做为一个有责任的前端打字员,有一点即便设计不要求的,我仍是须要说明的,横轴的刻度值是能够自定义的

<Axis name={xAxis} label={{ textStyle: { fill: 'red',  // 颜色
                textBaseline: 'top'  // 对齐基线
 }, formatter: (val) => { return `${ val }\n换行了` } }} />

 
数据可视化,BizCharts图表库入坑历程

”狗子,撸串去!!!“

”要不仍是吃个泡面????“

狗子,卒!


如下内容来自本身的总结


很显然,本人没有博主这枚猿有文化底蕴,辞藻上既不华丽丽,也没有故事性,纯属就是论事,记笔记的形式。

1. 柱状图/点图上显示文字及格式化内容

该需求须要用到Label组件,她是Geon的子组件,上代码

<div>
        <Chart height={400} data={dv} forceFit>
          <Axis name="月份" />
          <Axis name="月均降雨量" />
          <Legend />
          <Tooltip crosshairs={{ type: "y" }} />
          <Geom type="interval" position="月份*月均降雨量" color={"name"} adjust={[ { type: "dodge", marginRatio: 1 / 32 } ]} >
            <Label content={['月份*月均降雨量', (月份, 月均降雨量) => (`${月均降雨量}`)]} textStyle={{ textAlign: 'center', // 文本对齐方向,可取值为: start middle end
                  fill: '#404040', // 文本的颜色
                  fontSize: '14', // 文本大小
                  fontWeight: 'normal', // 文本粗细
                  rotate: 0, // 文字旋转
                  textBaseline: 'top', // 文本基准线,可取 top middle bottom,默认为middle
 }} />
            </Geom>
        </Chart>
      </div>

效果:

 
image.png

2. 图标上增长日期选择onChange

import React, { PureComponent } from 'react'; import { Chart, Geom, Axis, Tooltip, Label } from 'bizcharts'; import { DatePicker } from 'antd'; import numeral from 'numeral'; import moment from 'moment'; import style from './index.less'; class AppTotalUsers extends PureComponent { numeralCount = count => numeral(count).format('0,0.00'); wanCount = count => { let data; if (count < 10000) { data = count; } else { data = this.numeralCount(count / 10000); data = `${data} 万`; } return data; }; handleSelect = value => { const { callback } = this.props; const payload = { showDate: value }; callback(payload); }; // Can not select days before today and today
  disabledDate = current => current && current > moment().endOf('day'); const appChartData = [ { "x": "用户中心管理", "y": "23715", "date": "2019-03-22" }, { "x": "测试app", "y": "2899", "date": "2019-03-22" } ]; render() { const { appChartData, showDate } = this.props; const background = { fill: '#FFFFFF', // 图表背景色-白色
      fillOpacity: 0, // 图表背景透明度
 }; const appScale = { y: { alias: '人数', type: 'pow', }, }; return ( <div style={{ height: 390 }}>
        <div style={{ padding: '20px', background: '#FFFFFF' }}>
          <Chart height={300} data={appChartData} scale={appScale} forceFit background={background}>
            <span className={style.mainTitle}>历史累计用户人数(人)</span>
            <DatePicker className={style.dateSelect} allowClear={false} onChange={this.handleSelect} disabledDate={this.disabledDate} // value={moment(appChartData[0] && appChartData[0].date, 'YYYY-MM-DD')}
              value={moment(showDate, 'YYYY-MM-DD')} />
            <Axis name="x" />
            <Axis name="y" visible={false} />
            <Tooltip crosshairs={{ type: 'y', title: '人数', }} />
            <Geom type="interval" position="x*y"> {/* 柱子上做文章用这个子组件 */} <Label content={['x*y', (x, y) => this.wanCount(`${y}`)]} textStyle={{ textAlign: 'center', // 文本对齐方向,可取值为: start middle end
                  fill: '#404040', // 文本的颜色
                  fontSize: '12', // 文本大小
                  fontWeight: 'normal', // 文本粗细
                  rotate: 0, // 文字旋转
                  textBaseline: 'top', // 文本基准线,可取 top middle bottom,默认为middle
 }} />
            </Geom>
          </Chart>
        </div>
      </div>
 ); } } export default AppTotalUsers;
 
 

index.less文件

.chartDiv { padding: '0 20px'; background-color: '#FFFFFF'; } .mainTitle { font-weight: bold; font-size: 16px; padding: 10px; } .remark { font-weight: normal; font-size: 14px; padding-right: 30px; float: right; } .dateSelect { :global(.ant-calendar-picker-input) { border: none; } padding-right: 50px; float: right; }

效果:


 
相关文章
相关标签/搜索