zeroFillSeries.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import moment from 'moment';
  2. import {Series, SeriesDataUnit} from 'sentry/types/echarts';
  3. export function zeroFillSeries(
  4. series: Series,
  5. interval: moment.Duration,
  6. startTime?: moment.Moment,
  7. endTime?: moment.Moment,
  8. zerofillValue?: any
  9. ): Series {
  10. if (!series?.data?.length) {
  11. return series;
  12. }
  13. if (!zerofillValue) {
  14. zerofillValue = 0;
  15. }
  16. const firstDatum = series.data[0];
  17. const lastDatum = series.data[series.data.length - 1];
  18. const dateFormat = moment(firstDatum.name).creationData().format?.toString();
  19. if (!dateFormat) {
  20. return series;
  21. }
  22. const newData: SeriesDataUnit[] = [];
  23. const startTimeNearestInterval = startTime && roundUpToNearest12HourInterval(startTime);
  24. const endTimeNearestInterval = endTime && roundDownToNearest12HourInterval(endTime);
  25. const seriesData = [
  26. ...(startTimeNearestInterval &&
  27. startTimeNearestInterval.diff(moment(firstDatum.name)) < 0
  28. ? [{value: zerofillValue, name: startTimeNearestInterval.format(dateFormat)}]
  29. : []),
  30. ...series.data,
  31. ...(endTimeNearestInterval && endTimeNearestInterval.diff(moment(lastDatum.name)) > 0
  32. ? [{value: zerofillValue, name: endTimeNearestInterval.format(dateFormat)}]
  33. : []),
  34. ];
  35. let currentDatum, nextDatum, lastSeenDate, nextDate, diff;
  36. for (let index = 0; index < seriesData.length - 1; index++) {
  37. // Push the first datapoint
  38. if (index === 0) {
  39. newData.push({
  40. ...seriesData[index],
  41. name: moment(seriesData[index].name).format(dateFormat),
  42. });
  43. }
  44. currentDatum = seriesData[index];
  45. nextDatum = seriesData[index + 1];
  46. lastSeenDate = moment(currentDatum.name);
  47. nextDate = moment(nextDatum.name);
  48. diff = moment.duration(nextDate.diff(lastSeenDate));
  49. while (diff.asMilliseconds() > interval.asMilliseconds()) {
  50. // The gap between the two datapoints is more than the intended interval!
  51. // We need to fill 0s
  52. lastSeenDate.add(interval);
  53. newData.push({
  54. value: zerofillValue,
  55. name: moment(lastSeenDate).format(dateFormat),
  56. });
  57. diff = moment.duration(moment(nextDatum.name).diff(lastSeenDate));
  58. }
  59. // Push the next datapoint
  60. newData.push({
  61. ...nextDatum,
  62. name: moment(nextDatum.name).format(dateFormat),
  63. });
  64. }
  65. return {
  66. ...series,
  67. data: newData,
  68. };
  69. }
  70. function roundUpToNearest12HourInterval(time: moment.Moment) {
  71. return roundDownToNearest12HourInterval(time.clone().add(12, 'hour').subtract(1, 'ms'));
  72. }
  73. function roundDownToNearest12HourInterval(time: moment.Moment) {
  74. const hour = time.hour();
  75. const nearestDay = time.clone().startOf('day');
  76. if (hour < 12) {
  77. return nearestDay;
  78. }
  79. return nearestDay.add(12, 'hour');
  80. }