236 lines
7.3 KiB
JavaScript
236 lines
7.3 KiB
JavaScript
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));
|
||
}
|
||
}; |