Tech@道农大数据

道农大数据技术组
专注 专业
  1. 首页
  2. 前端
  3. 正文

制作一个略带“科技风”的图表

2021年5月10日 1964点热度 1人点赞 0条评论

阳春三月,春光明媚,正是写代码的好日子,在位置前舒舒服服的输入printf("hello world");时,突然第六感报警,有杀气!抬头一看,UI小姐姐正站在面前,笑眯眯的盯着自己……

“您这……有……有何贵干?”

“呶,这个界面,说是明日亥时前要完成,交给你了“,说罢丢来一张设计图,一瞅,一张大屏。

注:只是例子,设计图并非长这样

“好说好说,请静候佳音!”大屏而已,都做烂了,承接下来先。

UI小姐姐带着微笑离开了,静悄悄的,就和什么都没发生过一样。

开始研究下这设计图吧

设计图很大,一看就是未来界面风格(Sci-fi HUI风格,特点是黑色背景,繁杂图表,光污染,影视作品和游戏作品常客,理工科男最爱)。先从第一个图表看起来,平平无奇,应该是从哪个图表库里截图过来的吧?Echarts?AmCharts?HightCharts?Chartist?Plotly?vis.js?sigmajs?莫不是D3?左看右看都不太像,只好厚着脸皮去问了一下,却被UI小姐姐的一句击碎了:

平平无奇的一个码表图表

“啊,没有用图表库,我随便画了个……” 随便画了个……便画了个……画了个……了个……个……

顿时感觉不妙,难不成这一屏的图表都是自己画的?

“对啊,你看有没有不好做的,我改改?”

“不不不,好做好做” 已经夸下海口,事到如今怎能反悔?!硬着头皮上了只能!

开始分析图表构成,不管如何纷繁复杂,UI人员使用的各种设计工具,和前端使用的绘图手段,很多情况下都是共通的,各种形状+填充构成了美丽的图表世界。如下图,这个图表其实本身确实不复杂,文字可以无视,整个图形主体是由6个圆弧构成,虽然长得都不一样,但是所有非实心的圆弧其实只是dash-array的设置不同而已,不管CSS、Canvas还是SVG,都可以提供很好的支持。

那我们使用什么来画呢?

针对这个图表,它有6个圆弧组合而成,如果使用DOM,那么首先要解决显示“部分”圆弧的问题,使用clip-path是个方法,但是计算百分比的圆弧会比较麻烦,主要是不直观,所以暂时放弃。

剩下Canvas和SVG,其实都可以很好的绘制出这个图形,考虑到我们基础框架用的Vue,和SVG的关联比较方便,修改传入的数字会自动响应到元素的属性上,所以使用SVG会是个不错的选择……

SVG如何画圆弧呢,用circle画不实际,path中的A指令是我们这回要找的壮丁~

虽然这个是基础知识,但回顾一下A指令,会显得本文比较翔实:

指令A (绝对) a (相对)
名称elliptical arc 椭圆弧
参数(rx ry x-axis-rotation large-arc-flag sweep-flag x y)
rx ry 是椭圆的两个半轴的长度
x-axis-rotation 是椭圆相对于坐标系的旋转角度,角度数而非弧度数。
large-arc-flag 是标记绘制大弧(1)还是小弧(0)部分。
sweep-flag 是标记向顺时针(1)还是逆时针(0)方向绘制。
x y 是圆弧终点的坐标。
描述从当前点绘制一段椭圆弧到点 (x, y),椭圆的大小和方向由 (rx, ry) 和 x-axis-rotation 参数决定, x-axis-rotation 参数表示椭圆整体相对于当前坐标系统的旋转角度。椭圆的中心坐标 (cx, cy) 会自动进行计算从而满足其它参数约束。large-arc-flag 和 sweep-flag 也被用于圆弧的计算与绘制。

这里面最难理解的是 large-arc-flag 和 sweep-flag, w3.org 上有一副很好的图片说明这两个参数的作用:

确定两个点和半轴长度,有两个椭圆四段圆弧,这两个参数其实就是为了确定使用哪一段圆弧

如果了解Canvas,会发现Canvas中绘制圆弧很顺畅,给定坐标、旋转方向和角度就行,与数学中学习的椭圆定义一致,SVG却居然使用起点和终点的两个点坐标来确定圆弧的位置。粗看非常反人类的设计,但是“存在即合理“,SVG这么定义一定有它的打算。我琢磨着,应该是因为SVG的基本逻辑就是”描述路径“,上一个绘制动作的终点是下一个绘制动作的起点,这么一想,圆弧用两点来定位就理所当然起来了。

有一个事情是需要实现说明的,我们是做定制化的图表,所以不需要像考虑插件一样准备很多参数或者样式,以合理的时间解决问题是首要的,所以不管尺寸,颜色,展示,都没有参数化,下面代码范例仅作参考。

因为下面缺了1/4个圆,所以确定下几个起点和终点也不难,中学文化就可以轻松计算得出,于是一拍脑袋,开始算吧……

这小数点有点多啊……

这点的位置实在让人有点龇牙咧嘴,但是咋办能,硬着头皮上了。辛辛苦苦计算出的位置,复制过去,SVG展示出来看看,因为舍弃了一些小数,好像有点儿偏差……勉强能用,但是后面涉及到计算百分比的圆弧,那个就麻烦了啊,需要从一个很诡异的位置开始,然后按照值计算,这个……咋感觉事情不太对劲啊。

真是印证了那句话,只要不多动脑子,困难总比方法多……容我再想想……

这么多坑爹的数字,是因为起始点不在坐标轴上,实际上,因为下面割掉的PI/2,圆弧的顶点完全可以在x,y两个坐标轴上,只要旋转一下就可以了,这么一来,arc指令里的x-axis-rotation就有用武之地了,设计者果然还是很有先见之明的!后来想了一下,都不需要用圆弧旋转,直接把这些圆弧组合在一起,group旋转一下就好了呀!。

多美好的坐标位置!旋转-PI/4就可以达到效果图了

当然,这个只是把圆弧画出来,静态的写死就可以,不过这里有一个圆弧是变化的,所以有个小困难是,需要根据数值,决定取大弧还是小弧,而因为这个100%并不是整个圆,所以需要换算一下,不过想明白了其实也很简单……

    dpath () { // 获得变化圆弧路径代码的函数,this.v 是传入数据0~100之间,具体就不多解释了,相信有兴趣的同学看得明白的:)
      const alpha = (1 - 3 * this.v / 100) / 2 * Math.PI;
      const x = 39 * Math.cos(alpha);
      const y = 39 - 39 * Math.sin(alpha);
      if (this.v <= 200 / 3) {
        return `M50 11 a 39 39 0 0 1 ${x} ${y}`;
      }
      return `M50 11 a 39 39 0 1 1 ${x} ${y}`;
    },

后面就是很一般的stroke-dasharray设置, linearGradient之类的,也不多说了。

总之突破绘制圆弧这个小难点后,后面都是水到渠成的事情。

当然一顿操作猛如虎,说了这么多,一看发现大屏只完成了1%,继续继续……

标签: HUD HUI SVG
最后更新:2021年5月14日

zsimple

这个人很懒,什么都没留下

点赞

文章评论

取消回复
最新 热点 随机
最新 热点 随机
制作一个略带“科技风”的图表
制作一个略带“科技风”的图表
标签聚合
HUI HUD SVG

COPYRIGHT © 2021 Tech@道农大数据. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS