element表格----实现时间刻度线

859 阅读3分钟

一、背景

在开发过程中碰到一个需求,要求在table表格中实现类似时间刻度尺的功能,该功能通过刻度尺的形式展示24小时中的有效时间段。需求如下:

DCuTM9QDRm.png

二、思考

获取的单条数据格式如下:"09:27:31,10:09:34;13:04:50,14:00:54;14:34:14,15:12:10;15:40:39,16:07:57;16:35:05,16:46:44";

在实现过程中,思考了以下几种方法: 1.每一个时刻都作为一个单独的表头,将属于该时刻内的有效时间分割出来,再计算有效时间长度和无效时间长度,通过margin和width展示

2.将表格分割成左右两个部分,左边为table表格右边直接拼接刻度尺组件

3.将时刻归为一个表头,保证小时与小时的长度保持一致,计算有效时间长度,取有效时段离0时的距离做为偏移量。

三、实现

最后选取方案3,实现起来较为简单方便。实现如下思路如下: 1、将时刻归为一个表头,保证小时与小时的长度保持一致,这样我们就会获得24个长度相同的一个表头,设置一个该表头盒子长度为100%,表头宽度可以定死,这里假设定位720px。我们在表格中设置一个布局容器盒子,类名命名为time-length,布局方式设置为flex布局,再通过遍历的方式将容器盒子内的盒子渲染出来。在这里我们使用定位来处理盒子,将类名为timeBlock的盒子设置为absolute;我们将里面的盒子通过样式调整成我们需要的宽度(item.width)和其距离零刻度线的left(item.length)偏移量。

<el-table-column width="720px" header-align="center" prop="timePeriod" :resizable="false"

label=" 0 时| 1 时| 2 时| 3 时| 4 时| 5 时| 6 时| 7 时| 8 时| 9 时| 10时| 11时| 12时| 13时| 14时| 15时| 16时| 17时| 18时| 19时| 20时| 21时| 22时| 23时 ">
  <template slot-scope="scope">
    <div class="time-length" v-for="(item,index) in scope.row['timePeriod']" :key="index+'px'">
      <div :style="{width:item.width,left:item.length}" class="timeBlock"></div>
    </div>
  </template>
</el-table-column>

对应的css代码块为:

.time-length {
  display: flex;
  width: 720px;
  .timeBlock {
    position: absolute;
    height: 4px;
    background: #00db99;
  }
}

2、再进行对时间进行处理,进行时间相关计算:我们将时间转化成秒计算。24个小时转化为86400 秒,将获取的单条数据格式进行处理,这里对获取的数组进行遍历分割split(";"),将其分割成:[time1,time2]格式;并且对这个格式进行处理得到我们想要的长度和其针对0刻度线位置,这里统一写成了一个方法:

getTimeRuleWidth(time1, time2) {
//计算刻度尺长度
  let timeDiffRange = 0; //计算开启的时间段获取它的长度百分比
  let rangeZero = 0;
  timeDiffRange =(parseInt(this.timeEvent(time2) - this.timeEvent(time1)) /86400 *700).toFixed(2) + "px"; //计算展示长度
  rangeZero =(parseInt(this.timeEvent(time1) - 0) / 86400 * 700).toFixed(2) + "px"; //距离0刻度位置
  return { length: rangeZero, width: timeDiffRange };
},

通过该方法我们可以拿到类名为timeBlock的盒子的宽度和距离0度线的距离,不过我们需要将传入的时间处理成秒,方法如下:

timeEvent(e) {
//将时分秒转化为秒
if (!!e) {
let time = e;
let len = time.split(":");
if (len.length == 3) {
let hour = time.split(":")[0];
let min = time.split(":")[1];
let sec = time.split(":")[2];
return Number(hour * 3600) + Number(min * 60) + Number(sec);
}
if (len.length == 2) {
let min = time.split(":")[0];
let sec = time.split(":")[1];
return Number(min * 60) + Number(sec);
}
if (len.length == 1) {
let sec = time.split(":")[0];
return Number(sec);
}
} else {
return 0;
}
}

这样处理完我们便可以得到我们想要timeBlock类盒子的宽度和距离0刻度线的距离,其他就是对其颜色进行处理就完成了。其他就是我这边对相关数据进行有关处理的代码,obj是接口拿到的相关数组处理后的新数组,仅供参考,如下:

const newObj = obj.map(i => {
  let List = i.timePeriod.split(";");
  let newList = List.map(it => {
  return this.getTimeRuleWidth(
    it.split(",")[0] || 0,
    it.split(",")[1] || 0
  );
});

完成效果如下:

kppHfZPGWy.png

fqVAIrG9DQ.png

剩下的就是对表头刻度尺样式的优化。