动态刻度可视化组件实现

大数据 数据可视化
之前有个网友问我了一个很有价值的问题,笔者思考了一下决定自己实现一个动态刻度可视化组件的方案, 来解决这一类的需求.

前言

之前有个网友问我了一个很有价值的问题, 有关实现数据可视化的问题, 但是这个可视化问题不是一般的柱状图, 折现图之类的,而是不规则刻度的数据可视化.所以笔者思考了一下决定自己实现一个动态刻度可视化组件的方案, 来解决这一类的需求.

正文

最初的需求是这样的:

我们只需要输入文字, 数值比例, 就能生成如上图所示的刻度图.但是作为一名有追求的程序员, 需要对问题抽象化, 形成通用的解决方案,所以我们开始重组需求:

由上图我们可以拆解为一下几个需求点:

  • 支持数值自定义
  • 数值单位自定义
  • 支持刻度组件宽度自定义
  • 支持刻度线数量自定义
  • 支持刻度变化幅度自定义
  • 传入已有进度比例,即激活区范围
  • 支持刻度样式自定义
  • 支持数值样式自定义
  • 支持自定义说明文本以及说明文本自定义

以上就是笔者挖掘的通用需求,当然有其他需求也可以渐进的增加.

确认了以上需求之后,我们开始选择技术选型, 笔者之前常用的技术栈是vue和react,所以接下来我们初步确认该组件采用如下技术方案:

  • react + typescript + umi-library

如果大家擅长使用vue, 也可以, 笔者之前也写过如何搭建vue的组件库相关的文章,感兴趣可以学习了解一下, 其本质思想是一致的.

接下来我们开始实现动态刻度可视化组件. 如果对umi不熟悉的,可以参考笔者之前写的文章从0到1教你搭建前端团队的组件系统(高级进阶必备).

1. 定义基本属性类型

由以上需求分析我们可以定义如下的属性类型:

  1. export interface TickerProps { 
  2.   width: number; 
  3.   maxHeight: number; 
  4.   percent: number; 
  5.   text: string; 
  6.   value: number; 
  7.   showValue: boolean; 
  8.   unit: string; 
  9.   lineNum: number; 
  10.   defaultColor: string; 
  11.   activeColor: string; 
  12.   textStyle: object; 
  13.   valueStyle: object; 

2. 组件整体结构

  1. const Ticker: React.FC<TickerProps> = function(props:TickerProps) { 
  2.   const { 
  3.     width = 100, 
  4.     maxHeight = 10, 
  5.     percent = 50, 
  6.     value, 
  7.     text = '瞬时能见度'
  8.     showValue = true
  9.     unit = 'M'
  10.     lineNum = 12, 
  11.     defaultColor = '#06c'
  12.     activeColor = 'red'
  13.     valueStyle, 
  14.     textStyle 
  15.   } = props 
  16.   return ( 
  17.     <div className="ticker"
  18.       { 
  19.         showValue && 
  20.         <div className="value" style={valueStyle}> 
  21.           { value || 0 } <span className="unit">{ unit }</span> 
  22.         </div> 
  23.       } 
  24.       <div className="tickerGraph"
  25.         <div className="tickerLine"
  26.            
  27.         </div> 
  28.         <div className="tickerBar"></div> 
  29.       </div> 
  30.       { 
  31.         !!text && <div className="text">{ text }</div> 
  32.       } 
  33.     </div> 
  34.   ); 
  35. }; 
  36.  
  37. export default Ticker; 

3. 视图搭建

有关刻度可视化我们完全采用dom实现, 所以这里笔者具体分析一下如何实现刻度视图:

上图的思路就是用一个个dom来组装成随机刻度图形,所以我们只要利用css实现这个形状, 也就成功了一半.至于激活状态,我们会根据传入的数据量来决定激活范围,接下来会介绍如何渲染激活的刻度,也就是上图的红色区域.

4.特殊功能实现

因为该组件很多功能在搭建结构之后已经实现了, 这里我们唯一关注的就是css和js长度计算的问题, css实现方案有很多, 这里就不具体介绍了, 笔者这里重点介绍一下如何实现指定范围的随机高度:

  1. // 生成指定范围的随机高度 
  2. const random = (min:number, max:number):number => { 
  3.   return min + Math.random() * (max - min

动态刻度条的随机高度我们就是利用以上函数实现的, 刻度条内部实现如下:

  1. <div className="tickerLine" style={{borderBottomColor: defaultColor}}> 
  2.   { 
  3.     new Array(lineNum).fill(0).map((item:number, i: number) => { 
  4.       let isActive = (i + 1) <= Math.floor(lineNum * percent / 100) 
  5.       return <span 
  6.                className="tick" 
  7.                style={{ 
  8.                  height: random(3, maxHeight) + 'px'left: (gap + 2) * i + 'px'
  9.                  backgroundColor: isActive ? activeColor : defaultColor 
  10.                 }}> 
  11.              </span> 
  12.     }) 
  13.   } 
  14. </div> 

gap为刻度之间的间距, 由于计算刻度的位置需要一点几何知识, 公式如下:

  1. W = Lw * lineNum + gap * ( lineNum - 1) 

其中W表示刻度总宽度, Lw为刻度线宽度, lineNum为刻度线数量.

还有一个注意点就是激活态, 笔者使用如下函数来判断刻度是否具有激活状态:

  1. let isActive = (i + 1) <= Math.floor(lineNum * percent / 100) 

这块也非常好理解, 也就是我们传入的比率乘以线的总数量,即可求出哪些刻度线是需要激活的.

以上细节实现完成之后,我们就可以来实现有点意思的刻度可视化方案啦, 如下展示的demo:

1.可见度测量

2.正态分布模型

3.标尺

4.光栅

5.自定义文本样式

本文转载自微信公众号「趣谈前端」

【编辑推荐】

 

责任编辑:姜华 来源: 趣谈前端
相关推荐

2017-10-14 13:54:26

数据可视化数据信息可视化

2020-03-11 14:39:26

数据可视化地图可视化地理信息

2010-08-12 13:52:38

Flex组件

2010-07-30 14:00:41

Flex组件

2014-05-28 15:23:55

Rave

2021-10-28 08:42:31

Dooring表单设计器数据可视化

2022-08-26 09:15:58

Python可视化plotly

2009-04-21 14:26:41

可视化监控IT管理摩卡

2014-12-31 16:48:43

Touch touchevent多点触摸

2021-02-01 22:01:57

Coco工具macOS

2021-07-27 08:29:33

可视化组件商店H5-Dooring

2022-05-16 09:34:17

Python可视化图表

2019-08-06 10:35:25

Python时间序列可视化

2022-09-29 11:16:21

Python数据可视化

2021-11-19 08:30:39

H5-Dooring 可视化组件商店

2015-08-20 10:06:36

可视化

2020-12-29 08:04:16

可视化地图组件日历组件

2017-03-28 14:57:23

kylinsuperset可视化

2015-08-20 10:00:45

可视化

2020-09-27 11:15:37

可视化PandasPython
点赞
收藏

51CTO技术栈公众号