zeroFillSeries.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 =
  24. startTime && roundDownToNearest12HourInterval(startTime);
  25. const endTimeNearestInterval = endTime && roundDownToNearest12HourInterval(endTime);
  26. const seriesData = [
  27. ...(startTimeNearestInterval &&
  28. startTimeNearestInterval.diff(moment(firstDatum.name)) < 0
  29. ? [{value: zerofillValue, name: startTimeNearestInterval.format(dateFormat)}]
  30. : []),
  31. ...series.data,
  32. ...(endTimeNearestInterval && endTimeNearestInterval.diff(moment(lastDatum.name)) > 0
  33. ? [{value: zerofillValue, name: endTimeNearestInterval.format(dateFormat)}]
  34. : []),
  35. ];
  36. let currentDatum, nextDatum, lastSeenDate, nextDate, diff;
  37. for (let index = 0; index < seriesData.length - 1; index++) {
  38. // Push the first datapoint
  39. if (index === 0) {
  40. newData.push({
  41. ...seriesData[index],
  42. name: moment(seriesData[index].name).format(dateFormat),
  43. });
  44. }
  45. currentDatum = seriesData[index];
  46. nextDatum = seriesData[index + 1];
  47. lastSeenDate = moment(currentDatum.name);
  48. nextDate = moment(nextDatum.name);
  49. diff = moment.duration(nextDate.diff(lastSeenDate));
  50. while (diff.asMilliseconds() > interval.asMilliseconds()) {
  51. // The gap between the two datapoints is more than the intended interval!
  52. // We need to fill 0s
  53. lastSeenDate.add(interval);
  54. newData.push({
  55. value: zerofillValue,
  56. name: moment(lastSeenDate).format(dateFormat),
  57. });
  58. diff = moment.duration(moment(nextDatum.name).diff(lastSeenDate));
  59. }
  60. // Push the next datapoint
  61. newData.push({
  62. ...nextDatum,
  63. name: moment(nextDatum.name).format(dateFormat),
  64. });
  65. }
  66. return {
  67. ...series,
  68. data: newData,
  69. };
  70. }
  71. function roundDownToNearest12HourInterval(time: moment.Moment) {
  72. const hour = time.hour();
  73. const nearestDay = time.clone().startOf('day');
  74. if (hour < 12) {
  75. return nearestDay;
  76. }
  77. return nearestDay.add(12, 'hour');
  78. }