持續(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)
}
}
}