LogLabelStats.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import React, { PureComponent } from 'react';
  2. import classnames from 'classnames';
  3. import { LogLabelStatsModel } from '@grafana/data';
  4. function LogLabelStatsRow(logLabelStatsModel: LogLabelStatsModel) {
  5. const { active, count, proportion, value } = logLabelStatsModel;
  6. const percent = `${Math.round(proportion * 100)}%`;
  7. const barStyle = { width: percent };
  8. const className = classnames('logs-stats-row', { 'logs-stats-row--active': active });
  9. return (
  10. <div className={className}>
  11. <div className="logs-stats-row__label">
  12. <div className="logs-stats-row__value" title={value}>
  13. {value}
  14. </div>
  15. <div className="logs-stats-row__count">{count}</div>
  16. <div className="logs-stats-row__percent">{percent}</div>
  17. </div>
  18. <div className="logs-stats-row__bar">
  19. <div className="logs-stats-row__innerbar" style={barStyle} />
  20. </div>
  21. </div>
  22. );
  23. }
  24. const STATS_ROW_LIMIT = 5;
  25. interface Props {
  26. stats: LogLabelStatsModel[];
  27. label: string;
  28. value: string;
  29. rowCount: number;
  30. onClickClose: () => void;
  31. }
  32. export class LogLabelStats extends PureComponent<Props> {
  33. render() {
  34. const { label, rowCount, stats, value, onClickClose } = this.props;
  35. const topRows = stats.slice(0, STATS_ROW_LIMIT);
  36. let activeRow = topRows.find(row => row.value === value);
  37. let otherRows = stats.slice(STATS_ROW_LIMIT);
  38. const insertActiveRow = !activeRow;
  39. // Remove active row from other to show extra
  40. if (insertActiveRow) {
  41. activeRow = otherRows.find(row => row.value === value);
  42. otherRows = otherRows.filter(row => row.value !== value);
  43. }
  44. const otherCount = otherRows.reduce((sum, row) => sum + row.count, 0);
  45. const topCount = topRows.reduce((sum, row) => sum + row.count, 0);
  46. const total = topCount + otherCount;
  47. const otherProportion = otherCount / total;
  48. return (
  49. <div className="logs-stats">
  50. <div className="logs-stats__header">
  51. <span className="logs-stats__title">
  52. {label}: {total} of {rowCount} rows have that label
  53. </span>
  54. <span className="logs-stats__close fa fa-remove" onClick={onClickClose} />
  55. </div>
  56. <div className="logs-stats__body">
  57. {topRows.map(stat => (
  58. <LogLabelStatsRow key={stat.value} {...stat} active={stat.value === value} />
  59. ))}
  60. {insertActiveRow && activeRow && <LogLabelStatsRow key={activeRow.value} {...activeRow} active />}
  61. {otherCount > 0 && (
  62. <LogLabelStatsRow key="__OTHERS__" count={otherCount} value="Other" proportion={otherProportion} />
  63. )}
  64. </div>
  65. </div>
  66. );
  67. }
  68. }