From aa7ef1ad9067a531ed94006c4f5db153e8598d97 Mon Sep 17 00:00:00 2001 From: Conglei Shi Date: Tue, 21 May 2019 11:11:43 -0700 Subject: [PATCH] feat: simply the data processing logic --- .../package.json | 3 +- .../src/Table.tsx | 78 ++++------------- .../src/index.ts | 5 +- .../src/legacy/transformProps.ts | 64 +++++++++++++- .../src/transformProps.ts | 10 ++- .../stories/plugin-chart-table/data.js | 87 +++++++++---------- 6 files changed, 130 insertions(+), 117 deletions(-) diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/package.json b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/package.json index a778e291df..7033619cc2 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/package.json +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/package.json @@ -33,7 +33,6 @@ "@superset-ui/chart": "^0.10.0", "@superset-ui/number-format": "^0.10.0", "@superset-ui/time-format": "^0.10.0", - "@superset-ui/translation": "^0.10.0", - "core-js": "^3.0.1" + "@superset-ui/translation": "^0.10.0" } } diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/Table.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/Table.tsx index 9a41c5e752..dcdd6c3fb6 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/Table.tsx +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/Table.tsx @@ -3,13 +3,14 @@ import DataTable from '@airbnb/lunar/lib/components/DataTable'; import { Renderers, RendererProps } from '@airbnb/lunar/lib/components/DataTable/types'; import { HEIGHT_TO_PX } from '@airbnb/lunar/lib/components/DataTable/constants'; import { FormDataMetric, Metric } from '@superset-ui/chart'; -import { getNumberFormatter, NumberFormats } from '@superset-ui/number-format'; -import { getTimeFormatter } from '@superset-ui/time-format'; type ColumnType = { key: string; label: string; - format: string; + format?: (value: any) => string; + type: 'metric' | 'string'; + maxValue?: number; + minValue?: number; }; type Props = { @@ -58,8 +59,6 @@ type TableState = { const NEGATIVE_COLOR = '#ff8787'; const POSITIVE_COLOR = '#ced4da'; -const formatPercent = getNumberFormatter(NumberFormats.PERCENT_3_POINT); - class TableVis extends React.Component { static defaultProps = defaultProps; @@ -91,7 +90,10 @@ class TableVis extends React.Component { }); }; - static getDerivedStateFromProps(props: TableProps, state: TableState) { + static getDerivedStateFromProps: React.GetDerivedStateFromProps = ( + props: TableProps, + state: TableState, + ) => { const { filters } = props; const { selectedCells } = state; const newSelectedCells = new Set(Array.from(selectedCells)); @@ -104,62 +106,25 @@ class TableVis extends React.Component { ...state, selectedCells: newSelectedCells, }; - } + }; render() { const { - metrics: rawMetrics, + metrics, timeseriesLimitMetric, orderDesc, - percentMetrics, data, alignPositiveNegative, colorPositiveNegative, columns, - tableTimestampFormat, tableFilter, } = this.props; const { selectedCells } = this.state; - const metrics = (rawMetrics || []) - .map(m => (m as Metric).label || (m as string)) - // Add percent metrics - .concat((percentMetrics || []).map(m => `%${m}`)) - // Removing metrics (aggregates) that are strings - .filter(m => typeof data[0][m as string] === 'number'); - const dataArray: { - [key: string]: any; - } = {}; const sortByKey = timeseriesLimitMetric && ((timeseriesLimitMetric as Metric).label || (timeseriesLimitMetric as string)); - metrics.forEach(metric => { - const arr = []; - for (let i = 0; i < data.length; i += 1) { - arr.push(data[i][metric]); - } - - dataArray[metric] = arr; - }); - - const maxes: { - [key: string]: number; - } = {}; - const mins: { - [key: string]: number; - } = {}; - - for (let i = 0; i < metrics.length; i += 1) { - if (alignPositiveNegative) { - maxes[metrics[i]] = Math.max(...dataArray[metrics[i]].map(Math.abs)); - } else { - maxes[metrics[i]] = Math.max(...dataArray[metrics[i]]); - mins[metrics[i]] = Math.min(...dataArray[metrics[i]]); - } - } - - // const tsFormatter = getTimeFormatter(tableTimestampFormat); let formattedData = data.map(row => ({ data: row, })); @@ -183,8 +148,6 @@ class TableVis extends React.Component { } } - const tsFormatter = getTimeFormatter(tableTimestampFormat); - const heightType = 'small'; const getRenderer = (column: ColumnType) => (props: RendererProps) => { const { key } = props; @@ -197,10 +160,12 @@ class TableVis extends React.Component { let left = 0; let width = 0; if (alignPositiveNegative) { - width = Math.abs(Math.round((value / maxes[key]) * 100)); + width = Math.abs( + Math.round((value / Math.max(column.maxValue!, Math.abs(column.minValue!))) * 100), + ); } else { - const posExtent = Math.abs(Math.max(maxes[key], 0)); - const negExtent = Math.abs(Math.min(mins[key], 0)); + const posExtent = Math.abs(Math.max(column.maxValue!, 0)); + const negExtent = Math.abs(Math.min(column.minValue!, 0)); const tot = posExtent + negExtent; left = Math.round((Math.min(negExtent + value, negExtent) / tot) * 100); width = Math.round((Math.abs(value) / tot) * 100); @@ -236,16 +201,7 @@ class TableVis extends React.Component { ); }; - - if (key[0] === '%') { - value = formatPercent(value); - } else { - value = getNumberFormatter(column.format)(value); - } } else { - if (key === '__timestamp') { - value = tsFormatter(value); - } Parent = ({ children }: { children: React.ReactNode }) => ( {children} ); @@ -255,10 +211,10 @@ class TableVis extends React.Component {
- {value} + {column.format ? column.format(value) : value}
); }; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/index.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/index.ts index 8f02339509..91f96e92d7 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/index.ts +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/index.ts @@ -17,14 +17,15 @@ * under the License. */ import { ChartPlugin } from '@superset-ui/chart'; +import Core from '@airbnb/lunar/lib'; import transformProps from './transformProps'; import createMetadata from './createMetadata'; import buildQuery from './buildQuery'; -import Core from '@airbnb/lunar/lib'; +import TableFormData from './TableFormData'; Core.initialize({ name: 'superset-datatable' }); -export default class TableChartPlugin extends ChartPlugin { +export default class TableChartPlugin extends ChartPlugin { constructor() { super({ buildQuery, diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/legacy/transformProps.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/legacy/transformProps.ts index 3b6e8314d5..72f36d143d 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/legacy/transformProps.ts +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/legacy/transformProps.ts @@ -18,7 +18,9 @@ */ /* eslint-disable sort-keys */ -import { ChartProps } from '@superset-ui/chart'; +import { ChartProps, FormDataMetric, Metric } from '@superset-ui/chart'; +import { getNumberFormatter, NumberFormats, NumberFormatter } from '@superset-ui/number-format'; +import { getTimeFormatter, TimeFormatter } from '@superset-ui/time-format'; export default function transformProps(chartProps: ChartProps) { const { height, datasource, filters, formData, onAddFilter, payload } = chartProps; @@ -26,7 +28,7 @@ export default function transformProps(chartProps: ChartProps) { alignPn, colorPn, includeSearch, - metrics, + metrics: rawMetrics, orderDesc, pageLength, percentMetrics, @@ -37,22 +39,78 @@ export default function transformProps(chartProps: ChartProps) { const { columnFormats, verboseMap } = datasource; const { records, columns } = payload.data; + const metrics = ((rawMetrics as FormDataMetric[]) || []) + .map(m => (m as Metric).label || (m as string)) + // Add percent metrics + .concat(((percentMetrics as string[]) || []).map(m => `%${m}`)) + // Removing metrics (aggregates) that are strings + .filter(m => typeof records[0][m as string] === 'number'); + + const dataArray: { + [key: string]: any; + } = {}; + + metrics.forEach(metric => { + const arr = []; + for (let i = 0; i < records.length; i += 1) { + arr.push(records[i][metric]); + } + + dataArray[metric] = arr; + }); + + const maxes: { + [key: string]: number; + } = {}; + const mins: { + [key: string]: number; + } = {}; + + for (let i = 0; i < metrics.length; i += 1) { + maxes[metrics[i]] = Math.max(...dataArray[metrics[i]]); + mins[metrics[i]] = Math.min(...dataArray[metrics[i]]); + } + + const formatPercent = getNumberFormatter(NumberFormats.PERCENT_3_POINT); + const tsFormatter = getTimeFormatter(tableTimestampFormat); + const processedColumns = columns.map((key: string) => { let label = verboseMap[key]; + let formatString = columnFormats && columnFormats[key]; + let formatFunction: NumberFormatter | TimeFormatter | undefined; + let type = 'string'; + // Handle verbose names for percents if (!label) { if (key[0] === '%') { const cleanedKey = key.substring(1); label = `% ${verboseMap[cleanedKey] || cleanedKey}`; + formatFunction = formatPercent; } else { label = key; } } + if (key === '__timestamp') { + formatFunction = tsFormatter; + } + + const extraField: { + [key: string]: any; + } = {}; + + if (metrics.indexOf(key) >= 0) { + formatFunction = getNumberFormatter(formatString); + type = 'metric'; + extraField['maxValue'] = maxes[key]; + extraField['minValue'] = mins[key]; + } return { key, label, - format: columnFormats && columnFormats[key], + format: formatFunction, + type, + ...extraField, }; }); diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/transformProps.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/transformProps.ts index 29a346526d..b522b53e17 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/transformProps.ts +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugin-chart-table/src/transformProps.ts @@ -16,13 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -/* eslint-disable sort-keys */ import { ChartProps, Metric, FormDataMetric } from '@superset-ui/chart'; const DTTM_ALIAS = '__timestamp'; -function transformData(data: ChartProps['payload'][], formData: ChartProps['formData']) { +type PlainObject = { + [key: string]: any; +}; + +function transformData(data: PlainObject[], formData: PlainObject) { const columns = new Set( [...formData.groupby, ...formData.metrics, ...formData.allColumns].map( column => column.label || column, @@ -88,8 +91,7 @@ export default function transformProps(chartProps: ChartProps) { timeseriesLimitMetric, } = formData; const { columnFormats, verboseMap } = datasource; - const data = payload.data || payload[0].data; - const { records, columns } = transformData(data, formData); + const { records, columns } = transformData(payload.data, formData); const processedColumns = columns.map((key: string) => { let label = verboseMap[key]; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-table/data.js b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-table/data.js index da1c722c2b..6fe5881777 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-table/data.js +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-table/data.js @@ -1,46 +1,43 @@ /* eslint-disable sort-keys */ -export default { - columns: ['name', 'sum__num'], - records: [ - { - name: 'Michael', - sum__num: 2467063, - }, - { - name: 'Christopher', - sum__num: 1725265, - }, - { - name: 'David', - sum__num: 1570516, - }, - { - name: 'James', - sum__num: 1506025, - }, - { - name: 'John', - sum__num: 1426074, - }, - { - name: 'Matthew', - sum__num: 1355803, - }, - { - name: 'Robert', - sum__num: 1314800, - }, - { - name: 'Daniel', - sum__num: 1159354, - }, - { - name: 'Joseph', - sum__num: 1114098, - }, - { - name: 'William', - sum__num: 1113701, - }, - ], -}; +export default [ + { + name: 'Michael', + sum__num: 2467063, + }, + { + name: 'Christopher', + sum__num: 1725265, + }, + { + name: 'David', + sum__num: 1570516, + }, + { + name: 'James', + sum__num: 1506025, + }, + { + name: 'John', + sum__num: 1426074, + }, + { + name: 'Matthew', + sum__num: 1355803, + }, + { + name: 'Robert', + sum__num: 1314800, + }, + { + name: 'Daniel', + sum__num: 1159354, + }, + { + name: 'Joseph', + sum__num: 1114098, + }, + { + name: 'William', + sum__num: 1113701, + }, +];