Files
lucia-frontend/src/module/timeLabel.js
2026-03-06 08:54:51 +08:00

236 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import moment from 'moment';
const TOFIXED_DEICMAL = 1;
/**
* 若想要有等差的Y軸刻度則必須確保index是乘以一個共通的被乘數
* 此被乘數就是 stepSize
* @param {number} maxTimeInSecond
* @returns {object} {resultStepSize, unitToUse}
*/
export const getStepSizeOfYTicks = (maxTimeInSecond, numOfParts) => {
const {unitToUse, timeValue} = getTimeUnitAndValueToUse(maxTimeInSecond);
let resultStepSize;
const getLarger = 1 + (1 / (numOfParts - 1));
resultStepSize = (timeValue * getLarger / numOfParts);
return {resultStepSize, unitToUse};
}
/**
* Convert second to possibly day or hour or mins.
* @param {number} secondToDecide
* @returns {object} {unitToUse, timeValue} where timeValue is measured in unitToUse
*/
const getTimeUnitAndValueToUse = (secondToDecide) => {
const day = 24 * 60 * 60;
const hour = 60 * 60;
const minutes = 60;
const dd = secondToDecide / day;
const hh = secondToDecide / hour;
const mm = secondToDecide / minutes;
if (dd > 0 && dd > 1) {
return {
unitToUse: "d",
timeValue: secondToDecide / day,
};
} else if (hh > 0 && hh > 1) {
return {
unitToUse: "h",
timeValue: secondToDecide / hour,
};
} else if (mm > 0 && mm > 1) {
return {
unitToUse: "m",
timeValue: secondToDecide / minutes,
};
} else {
return {
unitToUse: "s",
timeValue: secondToDecide,
}
}
};
/**
* For the display of PrimeVue chart.
* According to the max time of the data given,
* split the Y axis into equal part as ticks.
* @param {number} stepSize stepSize of Y axis
* @param {number} index index of current visiting tick on Y axis
* @param {string} unitToUse time unit to display; "dhms" usually
*/
export function getYTicksByIndex(stepSize, index, unitToUse){
const rawStepsizeMultIndex = (stepSize * index).toString();
const shortenStepsizeMultIndex = rawStepsizeMultIndex.substring(
0, rawStepsizeMultIndex.indexOf('.') + 1 + TOFIXED_DEICMAL);
return `${shortenStepsizeMultIndex}${unitToUse}`;
};
/**
* 將秒數轉換成帶有時間單位的格式
* @param {number} second 總秒數
* @param {number} fixedNumber 小數點後幾位
* @returns {string} 轉換完的格式(ex: 1 day, 6.8 hrs)
*/
export function getTimeLabel(second, fixedNumber = 0) {
const day = 24 * 60 * 60;
const hour = 60 * 60;
const minutes = 60;
// 取餘數的操作會把 second 限制在一天之內的範圍即從0到86399之間
// 意思是過了多少天後剩下多少秒。
const dd = Math.floor(second / day);
const hh = Math.floor((second % day) / hour);
const mm = Math.floor((second % hour) / minutes);
if(dd > 0){
return (second / day).toFixed(fixedNumber) + " days";
}
else if(hh > 0){
return ((second % day) / hour).toFixed(fixedNumber) + " hrs";
}
else if(mm > 0){
return ((second % hour) / minutes).toFixed(fixedNumber) + " mins";
}
if(second == 0){
return second + " sec";
}
return second + " sec";
}
/**
* 將秒數轉換成帶有縮寫時間單位的格式
* @param {number} second 總秒數
* @param {number} fixedNumber 小數點後幾位
* @returns {string} 轉換完的格式(ex: 1 d, 6.8 h)
* 如果秒數second大於等於一天86400 秒),返回以天為單位的時間,帶有 d 標誌。
* 如果秒數小於一天但大於等於一小時3600 秒),返回以小時為單位的時間,帶有 h 標誌。
* 如果秒數小於一小時但大於等於一分鐘60 秒),返回以分鐘為單位的時間,帶有 m 標誌。
* 如果秒數等於 0 秒,返回 "0s"。
* 如果秒數小於 60 秒但大於 0 秒,返回原始秒數,帶有 s 標誌。
*/
export function simpleTimeLabel(second, fixedNumber = 0) {
const day = 24 * 60 * 60;
const hour = 60 * 60;
const minutes = 60;
const dd = Math.floor(second / day);
const hh = Math.floor((second / hour) / day);
const mm = Math.floor((second / hour) / minutes);
if(dd > 0){
return (second / day).toFixed(fixedNumber) + "d";
}
else if(hh > 0){
return ((second % day) / hour).toFixed(fixedNumber) + "h";
}
else if(mm > 0){
return ((second % hour) / minutes).toFixed(fixedNumber) + "m";
}
if(second == 0){
return second + "s";
}
return second + "s";
}
/**
* 考慮到每包資料內的時間範圍有的大有的小,
* 需要根據不同時間範圍級別的資料刻劃不同的Y軸座標
* 因此需要根據最大的時間值來決定Y軸刻度怎麼切分。
* 跟隨最大值的時間單位,將秒數轉換成帶有縮寫時間單位的格式
* @param {number} second 要轉換單位的秒數
* @param {number} max 該 data 中的最大值
* @param {number} fixedNumber 小數點後幾位
* @returns {string} 轉換完的格式(ex: 1 d, 6.8 h)
*/
export function followTimeLabel(second, max, fixedNumber = 0) {
const day = 24 * 60 * 60;
const hour = 60 * 60;
const minutes = 60;
const dd = max / day;
const hh = max / hour;
const mm = max/ minutes;
let maxUnit = '';
let result = "";
if (dd > 1) {
maxUnit = 'd';
} else if (hh > 1) {
maxUnit = 'h';
} else if (mm > 1) {
maxUnit = 'm';
} else {
maxUnit = 's';
}
switch (maxUnit) {
case 'd':
if((second / day) === 0) {
fixedNumber = 0;
}
result = (second / day).toFixed(fixedNumber) + 'd';
break;
case 'h':
if((second / hour) === 0) {
fixedNumber = 0;
}
result = (second / hour).toFixed(fixedNumber) + 'h';
break;
case 'm':
if((second / minutes) === 0) {
fixedNumber = 0;
}
result = (second / minutes).toFixed(fixedNumber) + 'm';
break;
case 's':
if(second === 0) {
fixedNumber = 0;
}
result = second.toFixed(fixedNumber) + 's';
break;
}
return result;
}
/**
* Select an appropriate time format based on the time difference.
* 根據時間差距選擇適合的時間格式
* 舉例 月: 2022/06
* 舉例 日: 06/06
* 舉例 時: 03/05 12:00
* 舉例 分: 03/05 12:15
* 舉例 秒: 09:05:32
* @param {Array<number>} timestamps - An array of timestamps.
* @returns {string} - The suitable time format string.
*/
export const setTimeStringFormatBaseOnTimeDifference = (minTimeStamp, maxTimeStamp) => {
const timeDifferenceInSeconds = maxTimeStamp - minTimeStamp;
let dateFormat;
if (timeDifferenceInSeconds < 60) {
dateFormat = 'HH:mm:ss'; // 秒
} else if (timeDifferenceInSeconds < 3600) {
dateFormat = 'MM/DD HH:mm'; // 分鐘
} else if (timeDifferenceInSeconds < 86400) { // 86400 秒 = 24 小時
dateFormat = 'MM/DD HH:mm'; // 小時
} else if (timeDifferenceInSeconds < 2592000) { // 2592000 秒 = 30 天
dateFormat = 'YYYY/MM/DD'; // 天
} else {
dateFormat = 'YYYY/MM/DD'; // 月
}
return dateFormat;
};
/**
* Converts an array of Unix timestamps to formatted date strings based on the
* specified format for use as axis ticks.
* 根據指定的格式將 Unix 時間戳數組轉換為軸標籤的格式化日期字符串。
* @param {Array<number>} timeStampArr
* @param {string} timeFormat For example, 'MM/DD'
*/
export const mapTimestampToAxisTicksByFormat = (timeStampArr, timeFormat) => {
if (timeStampArr) {
return timeStampArr.map(ts => moment(ts).format(timeFormat));
}
};