美文网首页
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