Graph.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Libraries
  2. import $ from 'jquery';
  3. import React, { PureComponent } from 'react';
  4. import { withSize } from 'react-sizeme';
  5. import 'vendor/flot/jquery.flot';
  6. import 'vendor/flot/jquery.flot.time';
  7. // Types
  8. import { TimeRange, TimeSeriesVMs } from 'app/types';
  9. interface GraphProps {
  10. timeSeries: TimeSeriesVMs;
  11. timeRange: TimeRange;
  12. showLines?: boolean;
  13. showPoints?: boolean;
  14. showBars?: boolean;
  15. size?: { width: number; height: number };
  16. }
  17. export class Graph extends PureComponent<GraphProps> {
  18. static defaultProps = {
  19. showLines: true,
  20. showPoints: false,
  21. showBars: false,
  22. };
  23. element: any;
  24. componentDidUpdate(prevProps: GraphProps) {
  25. if (
  26. prevProps.timeSeries !== this.props.timeSeries ||
  27. prevProps.timeRange !== this.props.timeRange ||
  28. prevProps.size !== this.props.size
  29. ) {
  30. this.draw();
  31. }
  32. }
  33. componentDidMount() {
  34. this.draw();
  35. }
  36. draw() {
  37. const { size, timeSeries, timeRange, showLines, showBars, showPoints } = this.props;
  38. if (!size) {
  39. return;
  40. }
  41. const ticks = (size.width || 0) / 100;
  42. const min = timeRange.from.valueOf();
  43. const max = timeRange.to.valueOf();
  44. const flotOptions = {
  45. legend: {
  46. show: false,
  47. },
  48. series: {
  49. lines: {
  50. show: showLines,
  51. linewidth: 1,
  52. zero: false,
  53. },
  54. points: {
  55. show: showPoints,
  56. fill: 1,
  57. fillColor: false,
  58. radius: 2,
  59. },
  60. bars: {
  61. show: showBars,
  62. fill: 1,
  63. barWidth: 1,
  64. zero: false,
  65. lineWidth: 0,
  66. },
  67. shadowSize: 0,
  68. },
  69. xaxis: {
  70. mode: 'time',
  71. min: min,
  72. max: max,
  73. label: 'Datetime',
  74. ticks: ticks,
  75. timeformat: time_format(ticks, min, max),
  76. },
  77. grid: {
  78. minBorderMargin: 0,
  79. markings: [],
  80. backgroundColor: null,
  81. borderWidth: 0,
  82. // hoverable: true,
  83. clickable: true,
  84. color: '#a1a1a1',
  85. margin: { left: 0, right: 0 },
  86. labelMarginX: 0,
  87. },
  88. };
  89. try {
  90. $.plot(this.element, timeSeries, flotOptions);
  91. } catch (err) {
  92. console.log('Graph rendering error', err, flotOptions, timeSeries);
  93. }
  94. }
  95. render() {
  96. return (
  97. <div className="graph-panel">
  98. <div className="graph-panel__chart" ref={e => (this.element = e)} />
  99. </div>
  100. );
  101. }
  102. }
  103. // Copied from graph.ts
  104. function time_format(ticks, min, max) {
  105. if (min && max && ticks) {
  106. const range = max - min;
  107. const secPerTick = range / ticks / 1000;
  108. const oneDay = 86400000;
  109. const oneYear = 31536000000;
  110. if (secPerTick <= 45) {
  111. return '%H:%M:%S';
  112. }
  113. if (secPerTick <= 7200 || range <= oneDay) {
  114. return '%H:%M';
  115. }
  116. if (secPerTick <= 80000) {
  117. return '%m/%d %H:%M';
  118. }
  119. if (secPerTick <= 2419200 || range <= oneYear) {
  120. return '%m/%d';
  121. }
  122. return '%Y-%m';
  123. }
  124. return '%H:%M';
  125. }
  126. export default withSize()(Graph);