Explorar o código

try virtualized

ryan %!s(int64=7) %!d(string=hai) anos
pai
achega
aca69df755

+ 85 - 52
public/app/plugins/panel/table2/TablePanel.tsx

@@ -1,25 +1,39 @@
 // Libraries
 import _ from 'lodash';
 import moment from 'moment';
-import React, { PureComponent, CSSProperties } from 'react';
-
-import ReactTable from 'react-table';
+import React, { Component, CSSProperties, ReactNode } from 'react';
 
 import { sanitize } from 'app/core/utils/text';
 
 // Types
 import { PanelProps } from '@grafana/ui/src/types';
-import { Options, Style, Column, CellFormatter } from './types';
+import { Options, Style, CellFormatter, ColumnInfo } from './types';
 import kbn from 'app/core/utils/kbn';
+import { Table, SortDirectionType, SortIndicator, Column, TableHeaderProps, TableCellProps } from 'react-virtualized';
 
 interface Props extends PanelProps<Options> {}
 
-export class TablePanel extends PureComponent<Props> {
+interface State {
+  sortBy: string;
+  sortDirection: SortDirectionType;
+  sortedList: any[];
+}
+
+export class TablePanel extends Component<Props, State> {
   isUTC: false; // TODO? get UTC from props?
 
-  columns: Column[];
+  columns: ColumnInfo[];
   colorState: any;
 
+  constructor(props: Props) {
+    super(props);
+    this.state = {
+      sortBy: 'index',
+      sortDirection: 'ASC',
+      sortedList: [],
+    };
+  }
+
   initColumns() {
     this.colorState = {};
 
@@ -318,57 +332,76 @@ export class TablePanel extends PureComponent<Props> {
     return columnHtml;
   }
 
+  _rowGetter = ({ index }) => {
+    return this.props.panelData.tableData.rows[index];
+  };
+
+  _sort = ({ sortBy, sortDirection }) => {
+    // const sortedList = this._sortList({sortBy, sortDirection});
+
+    // this.setState({sortBy, sortDirection, sortedList});
+    console.log('TODO, sort!', sortBy, sortDirection);
+  };
+
+  _headerRenderer = (header: TableHeaderProps): ReactNode => {
+    const tableData = this.props.panelData.tableData!;
+    const col = tableData.columns[header.dataKey];
+    if (!col) {
+      return <div>??{header.dataKey}</div>;
+    }
+
+    return (
+      <div>
+        {col.text} {header.sortBy === header.dataKey && <SortIndicator sortDirection={header.sortDirection} />}
+      </div>
+    );
+  };
+
+  _cellRenderer = (cell: TableCellProps) => {
+    const tableData = this.props.panelData.tableData!;
+    const val = tableData.rows[cell.rowIndex][cell.dataKey];
+    return <div>{val}</div>;
+  };
+
   render() {
-    const { panelData, height, options } = this.props;
-    const { pageSize } = options;
-
-    let rows = [];
-    let columns = [];
-    if (panelData.tableData) {
-      this.initColumns();
-      const fields = this.columns.map(c => {
-        return c.accessor;
-      });
-      rows = panelData.tableData.rows.map(row => {
-        return _.zipObject(fields, row);
-      });
-      columns = this.columns.map((c, columnIndex) => {
-        return {
-          Header: c.header,
-          accessor: c.accessor,
-          filterable: !!c.filterable,
-          Cell: row => {
-            return this.renderCell(columnIndex, row.index, row.value);
-          },
-        };
-      });
-    } else {
+    const { panelData, width, height, options } = this.props;
+    const { showHeader } = options;
+    const { sortBy, sortDirection } = this.state;
+    const { tableData } = panelData;
+
+    if (!tableData) {
       return <div>No Table Data...</div>;
     }
 
-    // Only show paging if necessary
-    const showPaginationBottom = pageSize && pageSize < panelData.tableData.rows.length;
-
     return (
-      <ReactTable
-        data={rows}
-        columns={columns}
-        pageSize={pageSize}
-        style={{
-          height: height + 'px',
-        }}
-        showPaginationBottom={showPaginationBottom}
-        getTdProps={(state, rowInfo, column, instance) => {
-          return {
-            onClick: (e, handleOriginal) => {
-              console.log('filter', rowInfo.row[column.id]);
-              if (handleOriginal) {
-                handleOriginal();
-              }
-            },
-          };
-        }}
-      />
+      <Table
+        disableHeader={!showHeader}
+        headerClassName={'hhhh'}
+        headerHeight={30}
+        height={height}
+        overscanRowCount={10}
+        rowClassName={'rrrrr'}
+        rowHeight={30}
+        rowGetter={this._rowGetter}
+        rowCount={tableData.rows.length}
+        sort={this._sort}
+        sortBy={sortBy}
+        sortDirection={sortDirection}
+        width={width}
+      >
+        {tableData.columns.map((col, index) => {
+          return (
+            <Column
+              key={index}
+              dataKey={index}
+              headerRenderer={this._headerRenderer}
+              cellRenderer={this._cellRenderer}
+              flexGrow={1}
+              width={60}
+            />
+          );
+        })}
+      </Table>
     );
   }
 }

+ 1 - 1
public/app/plugins/panel/table2/types.ts

@@ -24,7 +24,7 @@ export interface Style {
 
 export type CellFormatter = (v: any, style: Style) => string;
 
-export interface Column {
+export interface ColumnInfo {
   header: string;
   accessor: string; // the field name
   style?: Style;

+ 1 - 0
public/sass/_grafana.scss

@@ -57,6 +57,7 @@
 @import 'components/panel_pluginlist';
 @import 'components/panel_singlestat';
 @import 'components/panel_table';
+@import 'components/panel_table2';
 @import 'components/panel_text';
 @import 'components/panel_heatmap';
 @import 'components/panel_logs';

+ 64 - 0
public/sass/components/_panel_table2.scss

@@ -0,0 +1,64 @@
+.ReactVirtualized__Table {
+}
+
+.ReactVirtualized__Table__Grid {
+}
+
+.ReactVirtualized__Table__headerRow {
+  font-weight: 700;
+  display: flex;
+  flex-direction: row;
+  align-items: left;
+
+  background: $list-item-bg;
+  border-top: 2px solid $body-bg;
+  border-bottom: 2px solid $body-bg;
+
+  color: $blue;
+}
+.ReactVirtualized__Table__row {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+
+  border-bottom: 2px solid $body-bg;
+}
+
+.ReactVirtualized__Table__headerTruncatedText {
+  display: inline-block;
+  max-width: 100%;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+
+.ReactVirtualized__Table__headerColumn,
+.ReactVirtualized__Table__rowColumn {
+  margin-right: 10px;
+  min-width: 0px;
+}
+.ReactVirtualized__Table__rowColumn {
+  text-overflow: ellipsis;
+  white-space: nowrap;
+
+  border-right: 2px solid $body-bg;
+}
+
+.ReactVirtualized__Table__headerColumn:first-of-type,
+.ReactVirtualized__Table__rowColumn:first-of-type {
+  margin-left: 10px;
+}
+.ReactVirtualized__Table__sortableHeaderColumn {
+  cursor: pointer;
+}
+
+.ReactVirtualized__Table__sortableHeaderIconContainer {
+  display: flex;
+  align-items: center;
+}
+.ReactVirtualized__Table__sortableHeaderIcon {
+  flex: 0 0 24px;
+  height: 1em;
+  width: 1em;
+  fill: currentColor;
+}