{"ast":null,"code":"import * as chart from '~/utils/chart';\nimport { xAxisMap } from './types';\nimport { formatTime, quantile } from '~/utils';\nimport BigNumber from 'bignumber.js';\nimport cloneDeep from 'lodash/cloneDeep';\nimport compact from 'lodash/compact';\nimport maxBy from 'lodash/maxBy';\nimport minBy from 'lodash/minBy';\nimport sortBy from 'lodash/sortBy';\nBigNumber.config({\n  EXPONENTIAL_AT: [-6, 7]\n});\nexport * from './types';\nexport const sortingMethodMap = {\n  default: null,\n  descending: points => sortBy(points, point => point.item[3]).reverse(),\n  ascending: points => sortBy(points, point => point.item[3]),\n  // Compare other ponts width the trigger point, caculate the nearest sort.\n  nearest: (points, data) => sortBy(points, point => point.item[3] - data[2])\n};\nexport const transform = ({\n  datasets,\n  smoothing\n}) => // https://en.wikipedia.org/wiki/Moving_average\ndatasets.map(seriesData => {\n  const data = cloneDeep(seriesData);\n  let last = new BigNumber(data.length > 0 ? 0 : Number.NaN);\n  let numAccum = 0;\n  let startValue = 0;\n  const bigSmoothing = new BigNumber(smoothing);\n  data.forEach((d, i) => {\n    const nextVal = new BigNumber(d[2]); // second to millisecond.\n\n    const millisecond = d[0] = Math.floor(d[0] * 1000);\n\n    if (i === 0) {\n      startValue = millisecond;\n    } // Relative time, millisecond to hours.\n\n\n    d[4] = Math.floor(millisecond - startValue) / (60 * 60 * 1000);\n\n    if (!nextVal.isFinite()) {\n      d[3] = nextVal.toNumber();\n    } else {\n      // last = last * smoothing + (1 - smoothing) * nextVal;\n      last = last.multipliedBy(bigSmoothing).plus(bigSmoothing.minus(1).negated().multipliedBy(nextVal));\n      numAccum++;\n      let debiasWeight = new BigNumber(1);\n\n      if (!bigSmoothing.isEqualTo(1)) {\n        //debiasWeight = 1.0 - Math.pow(smoothing, numAccum);\n        debiasWeight = bigSmoothing.exponentiatedBy(numAccum).minus(1).negated();\n      } // d[3] = last / debiasWeight;\n\n\n      d[3] = last.dividedBy(debiasWeight).toNumber();\n    }\n  });\n  return data;\n});\nexport const chartData = ({\n  data,\n  runs,\n  smooth,\n  xAxis\n}) => data.map((dataset, i) => {\n  // smoothed data:\n  // [0] wall time\n  // [1] step\n  // [2] orginal value\n  // [3] smoothed value\n  // [4] relative\n  const name = runs[i];\n  const color = chart.color[i % chart.color.length];\n  const colorAlt = chart.colorAlt[i % chart.colorAlt.length];\n  return [{\n    name,\n    z: i,\n    lineStyle: {\n      color: colorAlt,\n      width: chart.series.lineStyle.width\n    },\n    data: dataset,\n    encode: {\n      x: [xAxisMap[xAxis]],\n      y: [2]\n    },\n    smooth\n  }, {\n    name,\n    z: runs.length + i,\n    itemStyle: {\n      color\n    },\n    data: dataset,\n    encode: {\n      x: [xAxisMap[xAxis]],\n      y: [3]\n    },\n    smooth\n  }];\n}).flat();\nexport const singlePointRange = value => ({\n  min: value ? Math.min(value * 2, 0) : -0.5,\n  max: value ? Math.max(value * 2, 0) : 0.5\n});\nexport const range = ({\n  datasets,\n  outlier\n}) => {\n  var _minBy$min, _minBy, _maxBy$max, _maxBy;\n\n  const ranges = compact(datasets === null || datasets === void 0 ? void 0 : datasets.map(dataset => {\n    if (dataset.length == 0) return;\n    const values = dataset.map(v => v[2]);\n\n    if (!outlier) {\n      var _Math$min, _Math$max;\n\n      // Get the orgin data range.\n      return {\n        min: (_Math$min = Math.min(...values)) !== null && _Math$min !== void 0 ? _Math$min : 0,\n        max: (_Math$max = Math.max(...values)) !== null && _Math$max !== void 0 ? _Math$max : 0\n      };\n    } else {\n      // Get the quantile range.\n      const sorted = dataset.map(v => v[2]).sort();\n      return {\n        min: quantile(sorted, 0.05),\n        max: quantile(values, 0.95)\n      };\n    }\n  }));\n  const min = (_minBy$min = (_minBy = minBy(ranges, range => range.min)) === null || _minBy === void 0 ? void 0 : _minBy.min) !== null && _minBy$min !== void 0 ? _minBy$min : 0;\n  const max = (_maxBy$max = (_maxBy = maxBy(ranges, range => range.max)) === null || _maxBy === void 0 ? void 0 : _maxBy.max) !== null && _maxBy$max !== void 0 ? _maxBy$max : 0;\n\n  if (!(min === 0 && max === 0)) {\n    return {\n      min: min > 0 ? min * 0.9 : min * 1.1,\n      max: max > 0 ? max * 1.1 : max * 0.9\n    };\n  }\n}; // TODO: make it better, don't concat html\n\nexport const tooltip = (data, i18n) => {\n  const indexPropMap = {\n    Time: 0,\n    Step: 1,\n    Value: 2,\n    Smoothed: 3,\n    Relative: 4\n  };\n  const widthPropMap = {\n    Run: 60,\n    Time: 120,\n    Step: 40,\n    Value: 60,\n    Smoothed: 60,\n    Relative: 60\n  };\n  const translatePropMap = {\n    Run: 'common:runs',\n    Time: 'scalars:x-axis-value.wall',\n    Step: 'scalars:x-axis-value.step',\n    Value: 'scalars:value',\n    Smoothed: 'scalars:smoothed',\n    Relative: 'scalars:x-axis-value.relative'\n  };\n  const transformedData = data.map(item => {\n    var _data$indexPropMap$Sm, _data$indexPropMap$Sm2;\n\n    const data = item.item;\n    return {\n      Run: item.run,\n      // use precision then toString to remove trailling 0\n      Smoothed: new BigNumber((_data$indexPropMap$Sm = data[indexPropMap.Smoothed]) !== null && _data$indexPropMap$Sm !== void 0 ? _data$indexPropMap$Sm : Number.NaN).precision(5).toString(),\n      Value: new BigNumber((_data$indexPropMap$Sm2 = data[indexPropMap.Smoothed]) !== null && _data$indexPropMap$Sm2 !== void 0 ? _data$indexPropMap$Sm2 : Number.NaN).precision(5).toString(),\n      Step: data[indexPropMap.Step],\n      Time: formatTime(data[indexPropMap.Time], i18n.language),\n      // Relative display value should take easy-read into consideration.\n      // Better to tranform data to 'day:hour', 'hour:minutes', 'minute: seconds' and second only.\n      Relative: Math.floor(data[indexPropMap.Relative] * 60 * 60) + 's'\n    };\n  });\n  let headerHtml = '<tr style=\"font-size:14px;\">';\n  headerHtml += Object.keys(transformedData[0]).map(key => {\n    return `<td style=\"padding: 0 4px; font-weight: bold; width: ${widthPropMap[key]}px;\">${i18n.t(translatePropMap[key])}</td>`;\n  }).join('');\n  headerHtml += '</tr>';\n  const content = transformedData.map(item => {\n    let str = '<tr style=\"font-size:12px;\">';\n    str += Object.keys(item).map(val => {\n      return `<td style=\"padding: 0 4px; overflow: hidden;\">${item[val]}</td>`;\n    }).join('');\n    str += '</tr>';\n    return str;\n  }).join(''); // eslint-disable-next-line\n\n  return `<table style=\"text-align: left;table-layout: fixed;width: 500px;\"><thead>${headerHtml}</thead><tbody>${content}</tbody><table>`;\n};","map":null,"metadata":{},"sourceType":"module"}