Conformance: Time Trend chart done.
This commit is contained in:
@@ -69,3 +69,113 @@ export function setBarChartData(baseData) {
|
||||
// console.log(data);
|
||||
return data
|
||||
};
|
||||
/**
|
||||
* 將一段時間均分成多段的時間點
|
||||
* @param {string} startTime 開始時間(ex: 434) 總秒數
|
||||
* @param {string} endTime 結束時間(ex: 259065) 總秒數
|
||||
* @param {number} amount 切分成多少段
|
||||
* @returns {array} 均分成多段的時間 array
|
||||
*/
|
||||
export function timeRange(minTime, maxTime, amount) {
|
||||
// x 軸(時間軸)的範圍是最大-最小,從最小值按照 index 累加間距到最大值
|
||||
const startTime = minTime;
|
||||
const endTime = maxTime;
|
||||
let timeRange = []; // return數據初始化
|
||||
const timeGap = (endTime - startTime) / (amount - 1); // 切分成多少段
|
||||
|
||||
for (let i = 0; i < amount; i++) {
|
||||
timeRange.push(startTime + timeGap * i);
|
||||
}
|
||||
timeRange = timeRange.map(value => Math.round(value));
|
||||
return timeRange;
|
||||
};
|
||||
/**
|
||||
* 將 y 軸的值分割成跟 x 時間軸一樣的等份,使用統計學 R 語言算出貝茲曲線攻勢
|
||||
* @param {array} data 切分成多少段
|
||||
* @param {number} yAmount 切分成多少段
|
||||
* @param {number} yMax y 最大值
|
||||
* @returns {array} 均分成多段的時間 array
|
||||
*/
|
||||
export function yTimeRange(data, yAmount, yMax) {
|
||||
const yRange = [];
|
||||
const yGap = (1/ (yAmount-1));
|
||||
|
||||
// 貝茲曲線公式
|
||||
const threebsr = function (t, a1, a2, a3, a4) {
|
||||
return (
|
||||
(1 - t) * (1 - t) * (1 - t) * a1 +
|
||||
3 * t * (1 - t)* (1 - t) * a2 +
|
||||
3 * t * t * (1 - t) * a3 +
|
||||
t * t * t * a4
|
||||
)
|
||||
};
|
||||
|
||||
for (let j = 0; j < data.length - 1; j++) {
|
||||
for (let i = 0; i <= 1; i += yGap*11) {
|
||||
yRange.push(threebsr(i, data[j].y, data[j].y, data[j + 1].y, data[j + 1].y));
|
||||
}
|
||||
}
|
||||
|
||||
if(yRange.length < yAmount) {
|
||||
let len = yAmount - yRange.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
yRange.push(yMax)
|
||||
}
|
||||
}
|
||||
else if(yRange.length > yAmount) {
|
||||
let len = yRange.length - yAmount;
|
||||
for(let i = 0; i < len; i++) {
|
||||
yRange.splice(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return yRange;
|
||||
};
|
||||
/**
|
||||
* 找出選擇的時間點的 index
|
||||
* @param {array} data xVal
|
||||
* @param {number} xValue x 值
|
||||
* @returns {numver} x index
|
||||
*/
|
||||
export function getXIndex(data, xValue) {
|
||||
let closestElement = data[0]; // 假定第一个元素是最接近的
|
||||
let closestIndex = xValue; // 假定第一个元素的索引是 0
|
||||
let smallestDifference = Math.abs(xValue - data[0]); // 初始差值设为第一个元素与目标数的差值
|
||||
|
||||
for (let i = 1; i < data.length; i++) {
|
||||
let difference = Math.abs(xValue - data[i]);
|
||||
|
||||
if (difference < smallestDifference) {
|
||||
closestElement = data[i];
|
||||
closestIndex = i;
|
||||
smallestDifference = difference;
|
||||
}
|
||||
}
|
||||
|
||||
return closestIndex;
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @param {number} seconds
|
||||
* @returns {string}
|
||||
*/
|
||||
export function formatTime(seconds) {
|
||||
const days = Math.floor(seconds / (3600 * 24));
|
||||
const hours = Math.floor((seconds % (3600 * 24)) / 3600);
|
||||
const minutes = Math.floor((seconds % 3600) / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
|
||||
let result = '';
|
||||
if (days > 0) {
|
||||
result += `${days}d`;
|
||||
}
|
||||
if (hours > 0) {
|
||||
result += `${hours}h`;
|
||||
}
|
||||
if (minutes > 0) {
|
||||
result += `${minutes}m`;
|
||||
}
|
||||
result += `${remainingSeconds}s`;
|
||||
|
||||
return result.trim(); // 去除最后一个空格
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user