首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

  • 24-12-05 21:05
  • 3712
  • 6136
juejin.cn

最近有一个需求,要画一个24小时的时间轴。类似于一个简化的甘特图,可以参考苹果手机的睡眠,不过只有一种颜色。

image.png

如果直接用网络上的甘特图,有点太复杂了,所以准备使用echarts自己写一个类似的。

一、引入echarts

可以参考官方的 文档1 文档2 引入,我创建的vue项目,直接npm install echarts --save安装,按照上面的教程进行初始化。

二、开始绘制

x轴初始化:

echarts中,x轴的具体数据可以在xAxis.data中配置。在这个时间轴中则是从0-24的一个数组。

image.png

一个一个写比较麻烦,可以直接写一个方法。这样生成的就带有分钟。

js
代码解读
复制代码
getXData() { let list = []; for (let i = 0; i <= 24; i++) { let str = `${i}:00`; list.push(str); } return list; },

如果希望x轴每个数据强制展示, 可以用xAxis.axisLabel. interval为0配置。 但是这样的话可能比较拥挤一些,还要画滚动条,设置文字的偏移度之类的。 我最后选择了直接写数字。

js
代码解读
复制代码
xAxis: { min: 0, max: 24, interval:1 }

具体柱形图决定使用renderItem绘制。我做过很多大屏可视化的图表,常见的都是什么bar,pie,line之类的,最多来个map,scatter之类的,renderItem倒是没有用过,今天学习一下,也是拓宽视野了。 可以参考 一下 文档

image.png 感觉还是比较好理解的,只要设置series的type是custom,然后child里放一些type是react的数据应该就可以了,shape中传入x和y,宽度、高度,就可以绘制矩形的形状了。这里的值都是px。

按照教程,我随便画了几个矩形,如下图参考。这里别的难度都不大,主要难度在于计算计算矩形的x和width,别的值都是可以固定的。这里的 image.png 计算矩形,这里我们可以借鉴echarts官方教程的甘特图,里面renderGanttItem方法。就是看着挺复杂的。

当echarts图表的宽度被我们写死时,计算x和width应该还是比较容易的,但是如果要做图表自适应,就比较麻烦了。 我们将renderItem的两个参数输出,可以发现有一个getWidth方法。这个方法可以获得echarts图表的宽度。

js
代码解读
复制代码
renderItem(params,api) { console.log( 'params',params) console.log( 'api',api) }

image.png

或者params里的coordSys也可以获得我们要的数据,我自己本身设置的图表的宽度和高度其实分别是600px和200px,我在grid里设置了边距,coordSys的结果应该是去除空白边距的大小。我们用这个计算应该效果会更好。

image.png

这里我们自己算也可以了,我们有时间段的起始时间和结束时间,可以计算每段时间占一天的百分比,然后乘以coordSys.width,就得到了宽度。x的值可以通过比例获得,x-coordSys.x:coordSys.width = 转化为小数的时间:24。

这我就不具体写了。因为我看echarts有自己的方法,我们自己不用算。 我们把时间转化为小数,调用下面这个方法,应该就可以直接算出来的,比如6:30转化完成后是6.5。理论上宽度用series-custom.renderItem.arguments.api.size,但是我算出来的结果不对,所以就不用这个了。调用两次coord相减。

例如下图是6:30-11:00的柱形图。这里我时间是写死的,其实可以通过api.value(0)和api.value(1)分别获得时间的开始值和结束值。

js
代码解读
复制代码
renderItem(params, api) { let x1 = api.coord([6.5, 1])[0]; let x2 = api.coord([11, 1])[0]; return { type: "group", children: [ { type: "rect", shape: { x: x1, y: 100, width: x2-x1, height: 20 }, }, ], }; },

image.png

最后整理

地图上画一个按钮,模拟接口调用重新渲染图表。按钮绑定formateData事件。用一些模拟数据测试。后端给的数据应该是x:xx这样的格式,或者x时x分,需要对数据进行格式化,重新设置echarts的option,并渲染。

image.png methos中写入以下代码:

js
代码解读
复制代码
formateData() { let testData = ["6:30-6:45", "11:30-11:35", "11:36-11:37", "16:45-19:50"]; const data = []; testData.forEach((e) => { const time = e.split("-"); const time1 = Number(time[0].split(":")[0]) + Number(time[0].split(":")[1]) / 60; const time2 = Number(time[1].split(":")[0]) + Number(time[1].split(":")[1]) / 60; data.push([time1, time2]); }); this.option.series[0].data = data; this.myChart.setOption(this.option); },

data中option代码如下:

js
代码解读
复制代码
option: { xAxis: { min: 0, max: 24, interval: 1, }, yAxis: { show: false, splitLine: false, }, series: [ { type: "custom", data: [], renderItem(params, api) { const data1 = api.value(0); const data2 = api.value(1); let x1 = api.coord([data1, 1])[0]; let x2 = api.coord([data2, 1])[0]; var categoryIndex = api.value(0); return { type: "group", children: [ { type: "rect", shape: { x: x1, y: 100, width: x2 - x1, height: 20 }, }, ], }; }, }, ], },

最终效果如下图:

image.png 这里我们画了一个横向的时间轴,我想如果画纵向的其实也是差不多的。今天也只画了一条,很多时候甘特图是有很多行的,这时候series这个数组里面再push进入一些数据,应该就没问题了。

注:本文转载自juejin.cn的subtle的文章"https://juejin.cn/post/7444066300453814324"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

104
前端
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top