00:00-24:00時間軸拆分時間段組件(vue)

持續(xù)更新中。。。
上代碼:https://github.com/scrollHeart/timeSplit
一、需求:
1.做一個00:00-24:00時間軸表,可進行時段拆分和刪除
2.時間軸上的時刻可用手柄拖動
3.拆分規(guī)則:折中間時刻拆分成2個時間段,可拆分時段<10個,最小拆分時間粒度為15min
4.刪除規(guī)則:刪除該時段,此時段時間向后一時段合并,生成新時段
5.拖動規(guī)則:不得超出時間軸,最小時間粒度寬度太小時,可設置最小寬度,方便查看時間段

二、實現思路:
1.計算每秒對應的像素值,畫出各時段寬度和刻度
2.編輯時,拖動手柄,重新計算各時段寬度和刻度
3.時間規(guī)則化和合理化(消除類似12:60時間的顯示)
4.拆分時段,寬度和刻度計算
5.刪除時段,寬度和刻度計算
6.當拆分粒度達到最小粒度時,時間段寬度很小,設置最小寬度,并確??倢挾炔怀鰰r間軸

  • 以上這些在代碼里都可看見,下面解釋下計算寬度差額的簡單算法思路

三、計算寬度差額的簡單算法思路
起因:總寬度固定的,保證各時段正常展示且不超出總時間軸寬度,需要對各時段寬度進行檢驗和處理差額
思路:
1.先統(tǒng)一向后補齊寬度差額,當前時段不夠最小寬度,向其鄰近的下一個時段借寬度差,若鄰近下一個時段仍然不夠減,繼續(xù)向后借,直到最后一個時段;
2.若最后一個時段仍然不夠減,跳到出現差額的時段鄰近的前一個時段,依次向前借差額
代碼段:

methods: {
// 向前找回寬度差
        findPrevWidthCapFn(p, s, obj) {
            // 向前一時段找回寬度差,若前一時段寬度也小于最小寬度,則繼續(xù)向前找
            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--;
                            // 繼續(xù)向前找
                            this.findPrevWidthCapFn(p, s, obj);
                        }
                    }
                }
                else {
                    if (p > 0) {
                        // 向前一時段找回寬度差
                        p--;
                        // 繼續(xù)向前找
                        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;
                            // 向前一時段找回寬度差,若前一時段寬度也小于最小寬度,則繼續(xù)向前找
                            this.findPrevWidthCapFn(p, s, obj);
                        }
                        else {
                            // 向后一時段找回寬度差
                            n++;
                            // 繼續(xù)向后找
                            this.findNextWidthGapFn(newVal, p, s, n, obj);
                        }
                    }
                }
                else {
                    if (n >= newVal.length - 1) {
                        // 最后一個時段,仍無法處理寬度差額,向最小寬度的時段索引前找
                        p = s - 1;
                        this.findPrevWidthCapFn(p, s, obj);
                    }
                    else {
                        // 向后一時段找回寬度差
                        n++;
                        // 繼續(xù)向后找
                        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;
                    // 向前一時段找回寬度差,若前一時段寬度也小于最小寬度,則繼續(xù)向前找
                    // this.findPrevWidthCapFn(p);
                    console.log(this, 'this')
                    this.findPrevWidthCapFn(p, s, obj)
                }
                else {
                    n = i + 1;
                    // 繼續(xù)向后找
                    // 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)
        }
  }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容