ExploreGraphPanel.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import React, { PureComponent } from 'react';
  2. import { hot } from 'react-hot-loader';
  3. import { connect } from 'react-redux';
  4. import { LegendDisplayMode, GraphWithLegend } from '@grafana/ui';
  5. import { TimeZone, AbsoluteTimeRange, GraphSeriesXY, dateTimeForTimeZone, LoadingState } from '@grafana/data';
  6. import { GraphSeriesToggler } from 'app/plugins/panel/graph2/GraphSeriesToggler';
  7. import Panel from './Panel';
  8. import { StoreState, ExploreId, ExploreMode } from 'app/types';
  9. import { getTimeZone } from '../profile/state/selectors';
  10. import { toggleGraph, updateTimeRange } from './state/actions';
  11. const MAX_NUMBER_OF_TIME_SERIES = 20;
  12. interface Props {
  13. exploreId: ExploreId;
  14. series: GraphSeriesXY[];
  15. width: number;
  16. absoluteRange?: AbsoluteTimeRange;
  17. loading?: boolean;
  18. mode?: ExploreMode;
  19. showingGraph?: boolean;
  20. showingTable?: boolean;
  21. timeZone?: TimeZone;
  22. onHiddenSeriesChanged?: (hiddenSeries: string[]) => void;
  23. toggleGraph: typeof toggleGraph;
  24. updateTimeRange: typeof updateTimeRange;
  25. }
  26. interface State {
  27. hiddenSeries: string[];
  28. showAllTimeSeries: boolean;
  29. }
  30. export class ExploreGraphPanel extends PureComponent<Props, State> {
  31. state: State = {
  32. hiddenSeries: [],
  33. showAllTimeSeries: false,
  34. };
  35. onShowAllTimeSeries = () => {
  36. this.setState({
  37. showAllTimeSeries: true,
  38. });
  39. };
  40. onClickGraphButton = () => {
  41. const { toggleGraph, exploreId, showingGraph } = this.props;
  42. toggleGraph(exploreId, showingGraph);
  43. };
  44. onChangeTime = (absoluteRange: AbsoluteTimeRange) => {
  45. const { exploreId, updateTimeRange } = this.props;
  46. updateTimeRange({ exploreId, absoluteRange });
  47. };
  48. renderGraph = () => {
  49. const {
  50. width,
  51. series,
  52. onHiddenSeriesChanged,
  53. timeZone,
  54. absoluteRange,
  55. mode,
  56. showingGraph,
  57. showingTable,
  58. } = this.props;
  59. const { showAllTimeSeries } = this.state;
  60. if (!series) {
  61. return null;
  62. }
  63. const timeRange = {
  64. from: dateTimeForTimeZone(timeZone, absoluteRange.from),
  65. to: dateTimeForTimeZone(timeZone, absoluteRange.to),
  66. raw: {
  67. from: dateTimeForTimeZone(timeZone, absoluteRange.from),
  68. to: dateTimeForTimeZone(timeZone, absoluteRange.to),
  69. },
  70. };
  71. const height = mode === ExploreMode.Logs ? 100 : showingGraph && showingTable ? 200 : 400;
  72. const showBars = mode === ExploreMode.Logs ? true : false;
  73. const showLines = mode === ExploreMode.Metrics ? true : false;
  74. const isStacked = mode === ExploreMode.Logs ? true : false;
  75. const lineWidth = mode === ExploreMode.Metrics ? 1 : 5;
  76. const seriesToShow = showAllTimeSeries ? series : series.slice(0, MAX_NUMBER_OF_TIME_SERIES);
  77. return (
  78. <GraphSeriesToggler series={seriesToShow} onHiddenSeriesChanged={onHiddenSeriesChanged}>
  79. {({ onSeriesToggle, toggledSeries }) => {
  80. return (
  81. <GraphWithLegend
  82. displayMode={LegendDisplayMode.List}
  83. height={height}
  84. isLegendVisible={true}
  85. placement={'under'}
  86. width={width}
  87. timeRange={timeRange}
  88. timeZone={timeZone}
  89. showBars={showBars}
  90. showLines={showLines}
  91. showPoints={false}
  92. onToggleSort={() => {}}
  93. series={toggledSeries}
  94. isStacked={isStacked}
  95. lineWidth={lineWidth}
  96. onSeriesToggle={onSeriesToggle}
  97. onSelectionChanged={this.onChangeTime}
  98. />
  99. );
  100. }}
  101. </GraphSeriesToggler>
  102. );
  103. };
  104. render() {
  105. const { series, mode, showingGraph, loading } = this.props;
  106. const { showAllTimeSeries } = this.state;
  107. return (
  108. <>
  109. {series && series.length > MAX_NUMBER_OF_TIME_SERIES && !showAllTimeSeries && (
  110. <div className="time-series-disclaimer">
  111. <i className="fa fa-fw fa-warning disclaimer-icon" />
  112. {`Showing only ${MAX_NUMBER_OF_TIME_SERIES} time series. `}
  113. <span className="show-all-time-series" onClick={this.onShowAllTimeSeries}>{`Show all ${
  114. series.length
  115. }`}</span>
  116. </div>
  117. )}
  118. {mode === ExploreMode.Metrics && (
  119. <Panel label="Graph" collapsible isOpen={showingGraph} loading={loading} onToggle={this.onClickGraphButton}>
  120. {this.renderGraph()}
  121. </Panel>
  122. )}
  123. {mode === ExploreMode.Logs && this.renderGraph()}
  124. </>
  125. );
  126. }
  127. }
  128. function mapStateToProps(state: StoreState, { exploreId }: { exploreId: string }) {
  129. const explore = state.explore;
  130. // @ts-ignore
  131. const item: ExploreItemState = explore[exploreId];
  132. const { loadingState, showingGraph, showingTable, absoluteRange, mode } = item;
  133. const loading = loadingState === LoadingState.Loading || loadingState === LoadingState.Streaming;
  134. return {
  135. loading,
  136. showingGraph,
  137. showingTable,
  138. timeZone: getTimeZone(state.user),
  139. absoluteRange,
  140. mode,
  141. };
  142. }
  143. const mapDispatchToProps = {
  144. toggleGraph,
  145. updateTimeRange,
  146. };
  147. export default hot(module)(
  148. connect(
  149. mapStateToProps,
  150. mapDispatchToProps
  151. )(ExploreGraphPanel)
  152. );