diff --git a/superset-frontend/src/explore/controls.jsx b/superset-frontend/src/explore/controls.jsx index c22393397f0cd..401bad34e32d3 100644 --- a/superset-frontend/src/explore/controls.jsx +++ b/superset-frontend/src/explore/controls.jsx @@ -124,8 +124,8 @@ const groupByControl = { default: [], includeTime: false, description: t( - 'One or many columns to group by. High cardinality groupings should include a sort by metric ' + - 'and series limit to limit the number of fetched and rendered series.', + 'One or many columns to group by. High cardinality groupings should include a series limit ' + + 'to limit the number of fetched and rendered series.', ), optionRenderer: c => , valueKey: 'column_name', @@ -361,10 +361,7 @@ export const controls = { validators: [legacyValidateInteger], default: 10000, choices: formatSelectOptions(ROW_LIMIT_OPTIONS), - description: t( - 'Limits the number of rows that get displayed. Should be used in conjunction with a sort ' + - 'by metric.', - ), + description: t('Limits the number of rows that get displayed.'), }, limit: { @@ -375,11 +372,10 @@ export const controls = { choices: formatSelectOptions(SERIES_LIMITS), clearable: true, description: t( - 'Limits the number of series that get displayed. Should be used in conjunction with a sort ' + - 'by metric. A joined subquery (or an extra phase where subqueries are not supported) is ' + - 'applied to limit the number of series that get fetched and rendered. This feature is ' + - 'useful when grouping by high cardinality column(s) though does increase the query ' + - 'complexity and cost.', + 'Limits the number of series that get displayed. A joined subquery (or an extra phase ' + + 'where subqueries are not supported) is applied to limit the number of series that get ' + + 'fetched and rendered. This feature is useful when grouping by high cardinality ' + + 'column(s) though does increase the query complexity and cost.', ), }, @@ -389,8 +385,8 @@ export const controls = { default: null, clearable: true, description: t( - 'Metric used to define the top series. Should be used in conjunction with the series or ' + - 'row limit', + 'Metric used to define how the top series are sorted if a series or row limit is present. ' + + 'If undefined reverts to the first metric (where appropriate).', ), mapStateToProps: state => ({ columns: state.datasource ? state.datasource.columns : [], diff --git a/superset/utils/core.py b/superset/utils/core.py index feed64abff18a..fad19f4b7ebbd 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -1326,6 +1326,11 @@ def get_metric_names(metrics: Sequence[Metric]) -> List[str]: return [metric for metric in map(get_metric_name, metrics) if metric] +def get_first_metric_name(metrics: Sequence[Metric]) -> Optional[str]: + metric_labels = get_metric_names(metrics) + return metric_labels[0] if metric_labels else None + + def ensure_path_exists(path: str) -> None: try: os.makedirs(path) diff --git a/superset/viz.py b/superset/viz.py index f1415b2fc06d3..ecf4f63c6a20e 100644 --- a/superset/viz.py +++ b/superset/viz.py @@ -1251,7 +1251,9 @@ class NVD3TimeSeriesViz(NVD3Viz): def query_obj(self) -> QueryObjectDict: query_obj = super().query_obj() - sort_by = self.form_data.get("timeseries_limit_metric") + sort_by = self.form_data.get( + "timeseries_limit_metric" + ) or utils.get_first_metric_name(query_obj.get("metrics") or []) is_asc = not self.form_data.get("order_desc") if sort_by: sort_by_label = utils.get_metric_name(sort_by)