| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 | import { round } from 'echarts/lib/util/number'import { decodeMetricName } from 'containers/Widget/components/util'type numType = number | stringlet _boundaryCheckingState = trueexport function getMetricsMinAndMax(metrics, data, stack) {  const metricsSource = metrics.map((metrics) =>    ['min', 'max'].map((item) => {      return { fn: item, data: metrics }    })  )  return metricsSource.flat().map((item) => {    if (stack) {      return item.data.reduce(        (num, m) =>          num +          Math[item.fn](            ...data.map((d) => d[`${m.agg}(${decodeMetricName(m.name)})`])          ),        0      )    } else {      return Math[item.fn](        ...item.data.map((m) =>          Math[item.fn](            ...data.map((d) => d[`${m.agg}(${decodeMetricName(m.name)})`])          )        )      )    }  })}export function getDoubleYExtendInterval(initExtent, splitNumber) {  let [minExtent, maxExtent] = initExtent  if (minExtent > 0 && maxExtent > 0) {    minExtent = 0  }  if (minExtent < 0 && maxExtent < 0) {    maxExtent = 0  }  if (minExtent === maxExtent) {    if (minExtent !== 0) {      const expandSize = minExtent      maxExtent += expandSize / 2      minExtent -= expandSize / 2    } else {      maxExtent = 1    }  }  let differ = maxExtent - minExtent  if (!isFinite(differ)) {    minExtent = 0    maxExtent = 1    differ = maxExtent - minExtent  }  if (!isFinite(differ)) {    return  }  let interval = differ / splitNumber  if (interval === 0) {    return 0  }  let exponent = Math.floor(Math.log(interval) / Math.LN10)  if (interval / Math.pow(10, exponent) >= 10) {    exponent++  }  const exp10 = Math.pow(10, exponent)  const f = interval / exp10  let nf  if (f < 1.5) {    nf = 1  } else if (f < 2.5) {    nf = 2  } else if (f < 4) {    nf = 3  } else if (f < 7) {    nf = 5  } else {    nf = 10  }  interval = nf * exp10  interval = exponent >= -20 ? +interval.toFixed(exponent < 0 ? -exponent : 0) : interval  minExtent = round(Math.floor(minExtent / interval) * interval)  maxExtent = round(Math.ceil(maxExtent / interval) * interval)  return { minExtent, maxExtent, interval }}export function strip(num: numType, precision = 12): number {  return +parseFloat(Number(num).toPrecision(precision))}export function digitLength(num: numType): number {  const eSplit = num.toString().split(/[eE]/)  const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0)  return len > 0 ? len : 0}export function float2Fixed(num: numType): number {  if (num.toString().indexOf('e') === -1) {    return Number(num.toString().replace('.', ''))  }  const dLen = digitLength(num)  return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num)}export function checkBoundary(num: number) {  if (_boundaryCheckingState) {    if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {      console.warn(        `${num} is beyond boundary when transfer to integer, the results may not be accurate`      )    }  }}export function times(  num1: numType,  num2: numType,  ...others: numType[]): number {  if (others.length > 0) {    return times(times(num1, num2), others[0], ...others.slice(1))  }  const num1Changed = float2Fixed(num1)  const num2Changed = float2Fixed(num2)  const baseNum = digitLength(num1) + digitLength(num2)  const leftValue = num1Changed * num2Changed  checkBoundary(leftValue)  return leftValue / Math.pow(10, baseNum)}export function divide(  num1: numType,  num2: numType,  ...others: numType[]): number {  if (others.length > 0) {    return divide(divide(num1, num2), others[0], ...others.slice(1))  }  const num1Changed = float2Fixed(num1)  const num2Changed = float2Fixed(num2)  checkBoundary(num1Changed)  checkBoundary(num2Changed)  return times(    strip(num1Changed / num2Changed),    strip(Math.pow(10, digitLength(num2) - digitLength(num1)))  )}export function getMetricsExtendMinAndMax(  metrics,  secondaryMetrics,  data,  stack,  splitNumber) {  const [leftMin, leftMax, rightMin, rightMax] = getMetricsMinAndMax(    [metrics, secondaryMetrics],    data,    stack  )  const [leftExtentMin, leftExtentMax, leftInterval] = Object.values(    getDoubleYExtendInterval([leftMin, leftMax], splitNumber)  )  const [rightExtentMin, rightExtentMax, rightInterval] = Object.values(    getDoubleYExtendInterval([rightMin, rightMax], splitNumber)  )  let maxCount  let minCount  const [    leftMaxPartCount,    rightMaxPartCount,    leftMinPartCount,    rightMinPartCount  ] = [    divide(leftExtentMax, leftInterval),    divide(rightExtentMax, rightInterval),    divide(leftExtentMin, leftInterval),    divide(rightExtentMin, rightInterval)  ]  if (leftExtentMin > 0 && rightExtentMin > 0) {    maxCount = Math.max(leftMaxPartCount, rightMaxPartCount)    minCount = Math.max(leftMinPartCount, rightMinPartCount)  } else if (leftExtentMax < 0 && rightExtentMax < 0) {    maxCount = Math.min(leftMaxPartCount, rightMaxPartCount)    minCount = Math.min(leftMinPartCount, rightMinPartCount)  } else {    maxCount = Math.max(leftMaxPartCount, rightMaxPartCount)    minCount = Math.min(leftMinPartCount, rightMinPartCount)  }  return {    leftY: [      times(minCount, leftInterval),      times(maxCount, leftInterval),      leftInterval    ],    rightY: [      times(minCount, rightInterval),      times(maxCount, rightInterval),      rightInterval    ]  }}
 |