美文网首页
00:00-24:00时间轴拆分时间段组件(vue)

00:00-24:00时间轴拆分时间段组件(vue)

作者: scrollHeart | 来源:发表于2023-07-28 14:04 被阅读0次

持续更新中。。。
上代码:https://github.com/scrollHeart/timeSplit
一、需求:
1.做一个00:00-24:00时间轴表,可进行时段拆分和删除
2.时间轴上的时刻可用手柄拖动
3.拆分规则:折中间时刻拆分成2个时间段,可拆分时段<10个,最小拆分时间粒度为15min
4.删除规则:删除该时段,此时段时间向后一时段合并,生成新时段
5.拖动规则:不得超出时间轴,最小时间粒度宽度太小时,可设置最小宽度,方便查看时间段

二、实现思路:
1.计算每秒对应的像素值,画出各时段宽度和刻度
2.编辑时,拖动手柄,重新计算各时段宽度和刻度
3.时间规则化和合理化(消除类似12:60时间的显示)
4.拆分时段,宽度和刻度计算
5.删除时段,宽度和刻度计算
6.当拆分粒度达到最小粒度时,时间段宽度很小,设置最小宽度,并确保总宽度不超出时间轴

  • 以上这些在代码里都可看见,下面解释下计算宽度差额的简单算法思路

三、计算宽度差额的简单算法思路
起因:总宽度固定的,保证各时段正常展示且不超出总时间轴宽度,需要对各时段宽度进行检验和处理差额
思路:
1.先统一向后补齐宽度差额,当前时段不够最小宽度,向其邻近的下一个时段借宽度差,若邻近下一个时段仍然不够减,继续向后借,直到最后一个时段;
2.若最后一个时段仍然不够减,跳到出现差额的时段邻近的前一个时段,依次向前借差额
代码段:

methods: {
// 向前找回宽度差
        findPrevWidthCapFn(p, s, obj) {
            // 向前一时段找回宽度差,若前一时段宽度也小于最小宽度,则继续向前找
            if (p >= 0) {
                if (!obj[p].widthGap) {
                    if (obj[p].width >= obj[s].widthGap + this.miniLength) {
                        obj[p].width = obj[p].width - obj[s].widthGap;
                    }
                    else {
                        if (p > 0) {
                            // 向前一时段找回宽度差
                            p--;
                            // 继续向前找
                            this.findPrevWidthCapFn(p, s, obj);
                        }
                    }
                }
                else {
                    if (p > 0) {
                        // 向前一时段找回宽度差
                        p--;
                        // 继续向前找
                        this.findPrevWidthCapFn(p, s, obj);
                    }
                }
            }
        },
        // 向后找回宽度差
        findNextWidthGapFn(newVal, p, s, n, obj) {
            if (n <= newVal.length - 1) {
                if (!obj[n].widthGap) {
                    if (obj[n].width >= obj[s].widthGap + this.miniLength) {
                        obj[n].width = obj[n].width - obj[s].widthGap;
                    }
                    else {
                        if (n >= newVal.length - 1) {
                            // 最后一个时段,仍无法处理宽度差额,向最小宽度的时段索引前找
                            p = s - 1;
                            // 向前一时段找回宽度差,若前一时段宽度也小于最小宽度,则继续向前找
                            this.findPrevWidthCapFn(p, s, obj);
                        }
                        else {
                            // 向后一时段找回宽度差
                            n++;
                            // 继续向后找
                            this.findNextWidthGapFn(newVal, p, s, n, obj);
                        }
                    }
                }
                else {
                    if (n >= newVal.length - 1) {
                        // 最后一个时段,仍无法处理宽度差额,向最小宽度的时段索引前找
                        p = s - 1;
                        this.findPrevWidthCapFn(p, s, obj);
                    }
                    else {
                        // 向后一时段找回宽度差
                        n++;
                        // 继续向后找
                        this.findNextWidthGapFn(newVal, p, s, n, obj);

                    }
                }
            }
        },
        // 每个时段检查是否有宽度差额
        checkWidthGapFn(i, s, p, n, newVal, obj) {
            // 设置当前时段宽度
            if (obj[i].widthGap) {
                s = i;
                if (i >= newVal.length - 1) {
                    // 最后一个时段,向前找
                    p = i - 1;
                    // 向前一时段找回宽度差,若前一时段宽度也小于最小宽度,则继续向前找
                    // this.findPrevWidthCapFn(p);
                    console.log(this, 'this')
                    this.findPrevWidthCapFn(p, s, obj)
                }
                else {
                    n = i + 1;
                    // 继续向后找
                    // this.findNextWidthGapFn(n);
                    this.findNextWidthGapFn(newVal, p, s, n, obj)
                }
            }
        },
        // 计算整个时段表的宽度数组
        updateWidthList(newVal) {
            let list = [];
            let obj = {};
            newVal.forEach((item, index) => {
                let period = item;
                period.start_time = this.standardTime(period.start_time);
                period.end_time = this.standardTime(period.end_time);
                let second = (this.$moment(period.end_time, 'HH:mm')
                    - this.$moment(period.start_time, 'HH:mm')) / 1000;
                obj[index] = {'second': second};
                if (this.PTR * second < this.miniLength) {
                    obj[index].widthGap = this.miniLength - this.PTR * second;
                    obj[index].width = this.miniLength;
                }
                else {
                    obj[index].width = this.PTR * second;
                }
            });
            // 初始化有宽度差的时段索引
            // const _this = this;
            let i = 0; // 遍历当前时段索引
            let s = 0; // 取最小宽度的时段索引
            let n = 0; // 向后查找时段索引,处理宽度差额
            let p = 0; // 向前查找时段索引,处理宽度差额
            for (let i = 0; i < newVal.length; i++) {
                // testFn(i);
                // 每个时段检查是否有宽度差额
                this.checkWidthGapFn(i, s, p, n, newVal, obj);

            }
            for (let key in obj) {
                if (obj[key].width) {
                    list.push(obj[key].width);
                }
                else {
                    list.push(obj[key].second * this.PTR);
                }
            }
            this.widthList = list;
        },
},
watch: {
  timeList:{
        immediate: false,
        deep: true,
        handler(newVal) {
//计算整个时段表的宽度数组
             this.updateWidthList(newVal)
        }
  }
}

相关文章

网友评论

      本文标题:00:00-24:00时间轴拆分时间段组件(vue)

      本文链接:https://www.haomeiwen.com/subject/bvarpdtx.html