CN-1372 fix: 提交步长计算函数
This commit is contained in:
34
src/components/timeGranularity/TimeGranularity.js
Normal file
34
src/components/timeGranularity/TimeGranularity.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import timeFuns from './timeMap'
|
||||||
|
import { getMillisecond } from '../../utils/date-util'
|
||||||
|
const Second = 1
|
||||||
|
const Min = 60 * Second // seconds In 1 minute
|
||||||
|
const Hour = 60 * Min
|
||||||
|
const Day = 24 * Hour
|
||||||
|
const Week = 7 * Day
|
||||||
|
const Month = 30 * Day
|
||||||
|
const Year = 12 * Month
|
||||||
|
|
||||||
|
export default function getTimeGranularity (timeRange, ruleFun = 'commonGranularity') {
|
||||||
|
if (!timeRange || timeRange.length !== 2) {
|
||||||
|
console.error('请输入 合适的开始时间和结束时间')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间间隔 以秒为单位
|
||||||
|
const durationBySeconds = Math.abs(new Date(getMillisecond(timeRange[1])).getTime() - new Date(getMillisecond(timeRange[0])).getTime()) / 1000
|
||||||
|
|
||||||
|
// 字符串类型的内置 时间粒度函数
|
||||||
|
let timeFunctions = ruleFun
|
||||||
|
if (Object.prototype.toString.call(ruleFun) === '[object String]') {
|
||||||
|
timeFunctions = timeFuns[ruleFun]
|
||||||
|
}
|
||||||
|
if (Object.prototype.toString.call(ruleFun) === '[object Function]') {
|
||||||
|
timeFunctions = ruleFun
|
||||||
|
}
|
||||||
|
if (!timeFunctions) {
|
||||||
|
console.error('请输入 规则方法,或者内置规则方法名称(commonGranularity,aiLearningGranularity等)')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeFunctions(durationBySeconds, { Second, Min, Hour, Day, Week, Month, Year })
|
||||||
|
}
|
||||||
179
src/components/timeGranularity/autoGranularity.js
Normal file
179
src/components/timeGranularity/autoGranularity.js
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
const Second = 1
|
||||||
|
const Min = 60 * Second // seconds In 1 minute
|
||||||
|
const Hour = 60 * Min
|
||||||
|
const Day = 24 * Hour
|
||||||
|
const Week = 7 * Day
|
||||||
|
const Month = 30 * Day
|
||||||
|
const Year = 12 * Month
|
||||||
|
|
||||||
|
const timeUnitDict = {
|
||||||
|
S: Second,
|
||||||
|
M: Min,
|
||||||
|
H: Hour,
|
||||||
|
D: Day,
|
||||||
|
W: Week,
|
||||||
|
Mon: Month,
|
||||||
|
Y: Year
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算 粒度
|
||||||
|
function calcGranularity (type, exactMs) {
|
||||||
|
let value = null
|
||||||
|
if (type === 'S') {
|
||||||
|
value = Math.ceil(exactMs / 1000)
|
||||||
|
}
|
||||||
|
if (type === 'M') {
|
||||||
|
value = Math.ceil(exactMs / (60 * 1000))
|
||||||
|
}
|
||||||
|
if (type === 'H') {
|
||||||
|
value = Math.ceil(exactMs / (60 * 60 * 1000))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'D') {
|
||||||
|
value = Math.ceil(exactMs / (24 * 60 * 60 * 1000))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ({ timeRangeMs, step, limit }) => {
|
||||||
|
let res = 1
|
||||||
|
let accumulation = 0
|
||||||
|
while (1) {
|
||||||
|
if (value < accumulation + step) {
|
||||||
|
res = accumulation || 1 // 至少是1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
accumulation += step
|
||||||
|
}
|
||||||
|
if (step !== 1) {
|
||||||
|
res = correctionGranularity({ calcResult: res, timeRangeMs, limit, type, step, exactMs })
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修正时间粒度 如果计算误差大 按照1 的步长计算 , 误差范围30%
|
||||||
|
function correctionGranularity ({ calcResult, timeRangeMs, limit, type, step, exactMs }) {
|
||||||
|
let pointCount = null
|
||||||
|
let isDeviationAccept = null
|
||||||
|
|
||||||
|
// 计算误差
|
||||||
|
let res = calcResult
|
||||||
|
pointCount = timeRangeMs / (res * timeUnitDict[type] * 1000)
|
||||||
|
isDeviationAccept = calcDeviation(pointCount, limit, res)
|
||||||
|
if (isDeviationAccept) {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// res +step 计算误差
|
||||||
|
res = res + step
|
||||||
|
pointCount = timeRangeMs / (res * timeUnitDict[type] * 1000)
|
||||||
|
isDeviationAccept = calcDeviation(pointCount, limit, res)
|
||||||
|
if (isDeviationAccept) {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接使用1为步长, 计算时间粒度,不用校验精度
|
||||||
|
return calcGranularity(type, exactMs)({ timeRangeMs, step: 1, limit })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取计算偏差
|
||||||
|
function calcDeviation (pointCount, limit, calcResult) {
|
||||||
|
// 偏差0.5 可以接受
|
||||||
|
return Math.abs(pointCount - limit) / limit <= 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算级别 秒 分 小时 ....
|
||||||
|
function calcMagnitude (exactMs, options) {
|
||||||
|
// 这里的拆分 可能导致粒度过大 ...
|
||||||
|
// 60s 以下 秒级粒度
|
||||||
|
if (exactMs < 60 * 1000) {
|
||||||
|
return 'S'
|
||||||
|
}
|
||||||
|
/* 60分钟以下 分钟级粒度 */
|
||||||
|
if (exactMs >= 60 * 1000 && exactMs < 60 * 60 * 1000) {
|
||||||
|
return 'M'
|
||||||
|
}
|
||||||
|
/* 24小时以下 小时级粒度 */
|
||||||
|
if (exactMs >= 60 * 60 * 1000 && exactMs < 24 * 60 * 60 * 1000) {
|
||||||
|
return 'H'
|
||||||
|
}
|
||||||
|
/* 一天以下 天级粒度 */
|
||||||
|
if (exactMs >= 24 * 60 * 60 * 1000) {
|
||||||
|
return 'D'
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 周级 暂时不做 ... */
|
||||||
|
/* 月级粒度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回的时间粒度是 秒
|
||||||
|
export function getGranularity (timeRange = [], opt = {}, unit = 's') {
|
||||||
|
if (!timeRange || timeRange.length !== 2) {
|
||||||
|
console.error('请输入 合适的开始时间和结束时间')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const durationBySeconds = Math.abs((new Date(timeRange[0]).getTime() - new Date(timeRange[1]).getTime()) / 1000)
|
||||||
|
return autoGranularity(durationBySeconds, opt, unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回的时间粒度是 秒
|
||||||
|
export function autoGranularity (durationBySeconds = 0, opt = {}, unit = 's') {
|
||||||
|
const options = {
|
||||||
|
limit: opt.limit || 100,
|
||||||
|
sStep: opt.sStep || 10,
|
||||||
|
mStep: opt.mStep || 10,
|
||||||
|
hStep: opt.hStep || 1,
|
||||||
|
dStep: opt.dStep || 1
|
||||||
|
}
|
||||||
|
const timeRangeMs = durationBySeconds * 1000
|
||||||
|
const exactMs = timeRangeMs / options.limit
|
||||||
|
|
||||||
|
const granularityMagnitude = calcMagnitude(exactMs, options)
|
||||||
|
let granularity = null
|
||||||
|
let granularityObj = {}
|
||||||
|
|
||||||
|
// 秒级粒度
|
||||||
|
if (granularityMagnitude === 'S') {
|
||||||
|
granularity = calcGranularity('S', exactMs)({ timeRangeMs, step: options.sStep, limit: options.limit })
|
||||||
|
granularityObj = {
|
||||||
|
granularity: granularity,
|
||||||
|
type: 'S',
|
||||||
|
second: granularity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 分钟级粒度 */
|
||||||
|
if (granularityMagnitude === 'M') {
|
||||||
|
granularity = calcGranularity('M', exactMs)({ timeRangeMs, step: options.mStep, limit: options.limit })
|
||||||
|
granularityObj = {
|
||||||
|
granularity: granularity,
|
||||||
|
type: 'M',
|
||||||
|
second: granularity * 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 小时级粒度 */
|
||||||
|
if (granularityMagnitude === 'H') {
|
||||||
|
granularity = calcGranularity('H', exactMs)({ timeRangeMs, step: options.hStep, limit: options.limit })
|
||||||
|
granularityObj = {
|
||||||
|
granularity: granularity,
|
||||||
|
type: 'H',
|
||||||
|
second: granularity * 60 * 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 天级粒度 */
|
||||||
|
if (granularityMagnitude === 'D') {
|
||||||
|
granularity = calcGranularity('D', exactMs)({ timeRangeMs, step: options.dStep, limit: options.limit })
|
||||||
|
granularityObj = {
|
||||||
|
granularity: granularity,
|
||||||
|
type: 'D',
|
||||||
|
second: granularity * 60 * 60 * 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!granularity) {
|
||||||
|
console.error('计算时间粒度失败')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if (unit === 's') {
|
||||||
|
return granularityObj.second
|
||||||
|
}
|
||||||
|
|
||||||
|
return granularityObj
|
||||||
|
}
|
||||||
73
src/components/timeGranularity/timeMap.js
Normal file
73
src/components/timeGranularity/timeMap.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import { autoGranularity } from './autoGranularity'
|
||||||
|
|
||||||
|
const Second = 1
|
||||||
|
const Min = 60 * Second // seconds In 1 minute
|
||||||
|
const Hour = 60 * Min
|
||||||
|
const Day = 24 * Hour
|
||||||
|
const Week = 7 * Day
|
||||||
|
const Month = 30 * Day
|
||||||
|
const Year = 12 * Month
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 驶入时间间隔 单位是S
|
||||||
|
* 输出式按键粒度 单位是S
|
||||||
|
* */
|
||||||
|
|
||||||
|
/* 通用-时间粒度,step整分钟 */
|
||||||
|
function commonGranularity (durationBySeconds = 0) {
|
||||||
|
/* 增加时间粒度处理 */
|
||||||
|
if (durationBySeconds <= Hour) {
|
||||||
|
return Min // max: 60
|
||||||
|
} else if (durationBySeconds > Hour && durationBySeconds <= 3 * Hour) {
|
||||||
|
return Min * 2 // max:90
|
||||||
|
} else if (durationBySeconds > 3 * Hour && durationBySeconds <= 6 * Hour) {
|
||||||
|
return Min * 5 // max: 72
|
||||||
|
} else if (durationBySeconds > 6 * Hour && durationBySeconds <= 24 * Hour) {
|
||||||
|
return Min * 10 // max:144
|
||||||
|
} else if (durationBySeconds > Day && durationBySeconds <= 2 * Day) {
|
||||||
|
return Min * 20 // max:144
|
||||||
|
} else if (durationBySeconds > 2 * Day && durationBySeconds <= Week) {
|
||||||
|
return Hour // 168
|
||||||
|
} else if (durationBySeconds > Week && durationBySeconds <= Month) {
|
||||||
|
return Hour * 6 // 120
|
||||||
|
} else if (durationBySeconds > Month && durationBySeconds <= 3 * Month) {
|
||||||
|
return Hour * 12 // 180
|
||||||
|
} else if (durationBySeconds > 3 * Month && durationBySeconds <= Year) {
|
||||||
|
return Day * 2 // 182
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认 100个点,自动计算
|
||||||
|
return autoGranularity(durationBySeconds, {
|
||||||
|
limit: 100
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 专用-报告的时间粒度 step整小时 */
|
||||||
|
function aiLearningGranularity (durationBySeconds = 0) {
|
||||||
|
if (durationBySeconds <= Day) {
|
||||||
|
return Hour // max: 24
|
||||||
|
} else if (durationBySeconds > Day && durationBySeconds <= 2 * Day) {
|
||||||
|
return Hour * 2 // 24
|
||||||
|
} else if (durationBySeconds > 2 * Day && durationBySeconds <= Week) {
|
||||||
|
return Hour * 6 // 28
|
||||||
|
} else if (durationBySeconds > Week && durationBySeconds <= 15 * Day) {
|
||||||
|
return Hour * 12 // 30
|
||||||
|
} else if (durationBySeconds > 15 * Day && durationBySeconds <= Month) {
|
||||||
|
return Hour * 24 // 30
|
||||||
|
}
|
||||||
|
// 预留逻辑:若超过1个月,默认30个点,自动计算
|
||||||
|
return autoGranularity(durationBySeconds, {
|
||||||
|
limit: 30
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 需要内置的 可以陆续在下面继续写
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
/* 通用-粗略的 时间粒度 */
|
||||||
|
commonGranularity,
|
||||||
|
|
||||||
|
/* 专用-知识库智能学习 时间粒度 */
|
||||||
|
aiLearningGranularity
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user