Skip to content

Commit

Permalink
[Table Visualization] Replace table visualization with React and Data…
Browse files Browse the repository at this point in the history
…Grid

In this PR, we add back functions to make new table usage to
be consistent with the replaced one.
* total function
* percentage column
* filter in/out

Meanwhile, we also add back server. Functional tests are removed.
We will add new functional test in opensearch-dashboards-functional-test
repo. We also clean out some legacy codes.

Issue Resolved:
opensearch-project#2855
  • Loading branch information
ananzh committed Nov 14, 2022
1 parent d53fbf8 commit d0fb0cf
Show file tree
Hide file tree
Showing 68 changed files with 747 additions and 5,376 deletions.
6 changes: 6 additions & 0 deletions src/plugins/data/common/field_formats/field_format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ export abstract class FieldFormat {
*/
public type: any = this.constructor;

/**
* @property {boolean} - allow numeric aggregation
* @private
*/
allowsNumericalAggregations?: boolean;

protected readonly _params: any;
protected getConfig: FieldFormatsGetConfigFn | undefined;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,55 @@ import produce from 'immer';
import { Draft } from 'immer';
import { EuiIconTip } from '@elastic/eui';
import { search } from '../../../../../data/public';
import { NumberInputOption, SwitchOption } from '../../../../../charts/public';
import { NumberInputOption, SwitchOption, SelectOption } from '../../../../../charts/public';
import {
useTypedDispatch,
useTypedSelector,
setStyleState,
} from '../../../application/utils/state_management';
import { useAggs } from '../../../../public/application/utils/use';
import { TableOptionsDefaults } from '../table_viz_type';
import { Option } from '../../../application/app';
import { AggTypes } from '../types';

const { tabifyGetColumns } = search;

const totalAggregations = [
{
value: AggTypes.SUM,
text: i18n.translate('visTypeTableNew.totalAggregations.sumText', {
defaultMessage: 'Sum',
}),
},
{
value: AggTypes.AVG,
text: i18n.translate('visTypeTableNew.totalAggregations.averageText', {
defaultMessage: 'Average',
}),
},
{
value: AggTypes.MIN,
text: i18n.translate('visTypeTableNewNew.totalAggregations.minText', {
defaultMessage: 'Min',
}),
},
{
value: AggTypes.MAX,
text: i18n.translate('visTypeTableNewNew.totalAggregations.maxText', {
defaultMessage: 'Max',
}),
},
{
value: AggTypes.COUNT,
text: i18n.translate('visTypeTableNewNew.totalAggregations.countText', {
defaultMessage: 'Count',
}),
},
];

function TableVizOptions() {
const styleState = useTypedSelector((state) => state.style) as TableOptionsDefaults;
const { aggConfigs } = useAggs();
const dispatch = useTypedDispatch();

const setOption = useCallback(
Expand All @@ -32,6 +70,35 @@ function TableVizOptions() {
[dispatch, styleState]
);

const percentageColumns = useMemo(() => {
const defaultPercentageColText = {
value: '',
text: i18n.translate('visTypeTableNew.params.defaultPercentageCol', {
defaultMessage: 'Don’t show',
}),
};
return aggConfigs
? [
defaultPercentageColText,
...tabifyGetColumns(aggConfigs.getResponseAggs(), true)
.filter((col) => get(col.aggConfig.toSerializedFieldFormat(), 'id') === 'number')
.map(({ name }) => ({ value: name, text: name })),
]
: [defaultPercentageColText];
}, [aggConfigs]);

useEffect(() => {
if (
!percentageColumns.find(({ value }) => value === styleState.percentageCol) &&
percentageColumns[0] &&
percentageColumns[0].value !== styleState.percentageCol
) {
setOption((draft) => {
draft.percentageCol = percentageColumns[0].value;
});
}
}, [percentageColumns, styleState.percentageCol, setOption]);

const isPerPageValid = styleState.perPage === '' || styleState.perPage > 0;

return (
Expand Down Expand Up @@ -101,6 +168,49 @@ function TableVizOptions() {
}
data-test-subj="showPartialRows"
/>

<SwitchOption
label={i18n.translate('visTypeTableNewNew.params.showTotalLabel', {
defaultMessage: 'Show total',
})}
paramName="showTotal"
value={styleState.showTotal}
setValue={(_, value) =>
setOption((draft) => {
draft.showTotal = value;
})
}
/>

<SelectOption
label={i18n.translate('visTypeTableNewNew.params.totalFunctionLabel', {
defaultMessage: 'Total function',
})}
disabled={!styleState.showTotal}
options={totalAggregations}
paramName="totalFunc"
value={styleState.totalFunc}
setValue={(_, value) =>
setOption((draft) => {
draft.totalFunc = value;
})
}
/>

<SelectOption
label={i18n.translate('visTypeTableNewNew.params.PercentageColLabel', {
defaultMessage: 'Percentage column',
})}
options={percentageColumns}
paramName="percentageCol"
value={styleState.percentageCol}
setValue={(_, value) =>
setOption((draft) => {
draft.percentageCol = value;
})
}
id="datatableVisualizationPercentageCol"
/>
</Option>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ import { AggGroupNames } from '../../../../data/public';
import { TableVizOptions } from './components/table_viz_options';
import { VisualizationTypeOptions } from '../../services/type_service';
import { toExpression } from './to_expression';
import { AggTypes } from './types';

export interface TableOptionsDefaults {
perPage: number | '';
showPartialRows: boolean;
showMetricsAtAllLevels: boolean;
showTotal: boolean;
totalFunc: AggTypes;
percentageCol: string;
}

export const createTableConfig = (): VisualizationTypeOptions<TableOptionsDefaults> => ({
Expand Down Expand Up @@ -87,6 +91,9 @@ export const createTableConfig = (): VisualizationTypeOptions<TableOptionsDefaul
perPage: 10,
showPartialRows: false,
showMetricsAtAllLevels: false,
showTotal: false,
totalFunc: AggTypes.SUM,
percentageCol: '',
},
render: TableVizOptions,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { SchemaConfig } from '../../../../visualizations/public';
import { TableVisExpressionFunctionDefinition } from '../../../../vis_type_table_new/public';
import { TableVisExpressionFunctionDefinition } from '../../../../vis_type_table/public';
import { AggConfigs, IAggConfig } from '../../../../data/common';
import { buildExpression, buildExpressionFunction } from '../../../../expressions/public';
import { RenderState } from '../../application/utils/state_management';
Expand Down
12 changes: 12 additions & 0 deletions src/plugins/vis_builder/public/visualizations/table/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export enum AggTypes {
SUM = 'sum',
AVG = 'avg',
MIN = 'min',
MAX = 'max',
COUNT = 'count',
}
37 changes: 36 additions & 1 deletion src/plugins/vis_type_table/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
Contains the data table visualization, that allows presenting data in a simple table format.
# Data Table

This is an OpenSearch Dashboards plugin that is used to visualize data and aggregations in tabular format.

## Create Data Table
To create a data table in OpenSearch Dashboards, first select `Visualize` from the navigation menu. Then click `Create Visualization` and choose `Data Table` as the visualization type.

## Select Metrics

### Metrics Aggregation
At the `Metrics`, select the metric aggregation type from the menu and config it accordinly.

### Buckets Aggregation
At the `Buckets`, config the columns to be displayed in the table visualization.
- `Split Rows` allows you to add another column to the table.
- `Split Table` splits the table into seperate tables for the aggregation you choose.

## Select Options
In the `Options` tab, you could config more options.
- `Max rows per page` is the maximum number of rows displayed per page.
- `Show metrics for every bucket/level` adds metrics aggregation to every columns.
- `Show partial rows` will include data with missing columns.
- `Show total` calculates the selected metrics per column and displays the result at the bottom.
- `Percentage column` adds one percentage column based on the chosen metrics aggregation.

## Example

Below is an example of creating a table visualization using sample ecommerce data.

- Create a new data table visualization and set a relative time 15 weeks ago.
- Compute the count of ecommerce: Choose `Count` in Metrics Aggregation.
- Split the rows on the top 5 of `manufacturer.keyword` ordered by `Metric:Count` in descending and add a label "manufacturer".
geoip.city_name
- Split the table in rows on the top 5 of `geoip.city_name` ordered by `Metric:Count` in ascending order.
- Click the `Save` button on the top left and save the visualization as "Top manufacturers by count per city".
- Choose a table and click the download icon to download the table.
6 changes: 3 additions & 3 deletions src/plugins/vis_type_table/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
"requiredPlugins": [
"expressions",
"visualizations",
"data",
"opensearchDashboardsLegacy"
"data"
],
"requiredBundles": [
"opensearchDashboardsUtils",
"share",
"opensearchDashboardsReact",
"charts",
"share",
"visDefaultEditor"
]
}

This file was deleted.

23 changes: 0 additions & 23 deletions src/plugins/vis_type_table/public/_table_vis.scss

This file was deleted.

42 changes: 0 additions & 42 deletions src/plugins/vis_type_table/public/agg_table/_agg_table.scss

This file was deleted.

1 change: 0 additions & 1 deletion src/plugins/vis_type_table/public/agg_table/_index.scss

This file was deleted.

Loading

0 comments on commit d0fb0cf

Please sign in to comment.