From 3ef1540f8c6c3a7d81c8861af81cbc02dcd105cb Mon Sep 17 00:00:00 2001 From: Cindy Chang Date: Mon, 22 Jul 2024 14:25:38 +0800 Subject: [PATCH] refactor setChartData - slope calculation --- src/module/setChartData.js | 121 ++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 54 deletions(-) diff --git a/src/module/setChartData.js b/src/module/setChartData.js index 40ca5ff..7c7c1ed 100644 --- a/src/module/setChartData.js +++ b/src/module/setChartData.js @@ -11,74 +11,87 @@ import getMoment from 'moment'; * @returns {array} 可直接套入 chart.js 的 data */ export function setLineChartData(baseData, xMax, xMin, isPercent, yMax, yMin) { - let data = baseData.map(i=>({x:i.x,y:i.y})) - // y 軸斜率計算請參考 ./public/timeFrameSlope 的圖 - // x 值為 0 ~ 11, - // 將三的座標(ax, ay), (bx, by), (cx, cy)命名為 (a, b), (c, d), (e, f) - // 最小值: (f - b)(c - a) = (e - a)(d - b),求 b = (ed - ad - fa - fc) / (e - c - a) - // 最大值: (f - b)(e - c) = (f - d)(e - a),求 f = (be - bc -de + da) / (a - c) + // 將 baseData 轉換為包含 x 和 y 屬性的物件陣列 + let data = baseData.map(i => ({ x: i.x, y: i.y })); - // y 軸最小值 + // 計算 y 軸最小值 + let b = calculateYMin(baseData, isPercent, yMin, yMax); + + // 計算 y 軸最大值 + let mf = calculateYMax(baseData, isPercent, yMin, yMax); + + // 添加最小值 + data.unshift({ + x: xMin, + y: b, + }); + + // 添加最大值 + data.push({ + x: xMax, + y: mf, + }); + + return data; + }; + /** + * 計算 y 軸最小值 + * + * x 值為 0 ~ 11, + * 將三的座標(ax, ay), (bx, by), (cx, cy)命名為 (a, b), (c, d), (e, f) + * 最小值: (f - b)(c - a) = (e - a)(d - b),求 b = (ed - ad - fa - fc) / (e - c - a) + */ +function calculateYMin(baseData, isPercent, yMin, yMax) { let a = 0; - let b; let c = 1; let d = baseData[0].y; let e = 2; let f = baseData[1].y; - b = (e*d - a*d - f*a - f*c) / (e - c - a) - if(isPercent) { // sonar-qube - if (b >= 1) { - b = 1; - } else if (b <= 0) { - b = 0; - } else { - b = b; - } - } - else { - if (b >= yMax) { - b = yMax; - } else if (b <= yMin) { - b = yMin; - } else { - b = b; - } - } - - // y 軸最大值 + let b = (e * d - a * d - f * a - f * c) / (e - c - a); + return clampValue(b, isPercent, yMin, yMax); +}; +/** + * 計算 y 軸最大值 + * + * x 值為 9 ~ 11, + * 將三的座標(ax, ay), (bx, by), (cx, cy)命名為 (a, b), (c, d), (e, f) + * 最大值: (f - b)(e - c) = (f - d)(e - a),求 f = (be - bc -de + da) / (a - c) + */ +function calculateYMax(baseData, isPercent, yMin, yMax) { let ma = 9; let mb = baseData[8].y; let mc = 10; let md = baseData[9].y; let me = 11; - let mf; - mf = (mb*me - mb*mc -md*me + md*ma) / (ma - mc); + let mf = (mb * me - mb * mc - md * me + md * ma) / (ma - mc); + return clampValue(mf, isPercent, yMin, yMax); +}; +/** + * 將值限制在指定範圍內 + * 如果 isPercent 為 true,則將值限制在 0 到 1 之間 + * 否則,將值限制在 yMin 和 yMax 之間 + * + * @param {number} value 需要被限制的值 + * @param {boolean} isPercent 如果為 true,表示值應該被限制在百分比範圍內(0 到 1) + * @param {number} min 非百分比情況下的最小允許值(yMin) + * @param {number} max 非百分比情況下的最大允許值(yMax) + * @returns {number} 被限制在指定範圍內的值 + */ +function clampValue(value, isPercent, min, max) { if (isPercent) { - if (mf >= 1) { - mf = 1; - } else if (mf <= 0) { - mf = 0; + if (value >= 1) { + return 1; + } else if (value <= 0) { + return 0; + } + } else { + if (value >= max) { + return max; + } else if (value <= min) { + return min; } - } else if (mf >= yMax) { - mf = yMax; - } else if (mf <= yMin) { - mf = yMin; } - - // 添加最小值 - // The unshift() method of Array instances adds the specified elements to - // the beginning of an array and returns the new length of the array. - data.unshift({ - x: xMin, - y: b, - }) - // 添加最大值 - data.push({ - x: xMax, - y: mf, - }) - - return data; + return value; }; /** * 將後端的 chart data x 值轉換時間格式,長條圖