mirror of
https://github.com/apache/superset.git
synced 2026-06-09 09:39:25 +00:00
feat(chart-controls): implement drag&drop controls for all charts (#1127)
* feat(chart-controls): implement drag&drop controls for all charts * Split stacked controls into separate rows
This commit is contained in:
committed by
Yongjie Zhao
parent
a6cfaffa35
commit
c461abbdeb
@@ -124,3 +124,28 @@ export const dnd_sort_by: SharedControlConfig<'DndMetricSelect'> = {
|
||||
datasourceType: datasource?.type,
|
||||
}),
|
||||
};
|
||||
|
||||
export const dnd_size: SharedControlConfig<'DndMetricSelect'> = {
|
||||
...dnd_adhoc_metric,
|
||||
label: t('Bubble Size'),
|
||||
description: t('Metric used to calculate bubble size'),
|
||||
};
|
||||
|
||||
export const dnd_x: SharedControlConfig<'DndMetricSelect'> = {
|
||||
...dnd_adhoc_metric,
|
||||
label: t('X Axis'),
|
||||
description: t('Metric assigned to the [X] axis'),
|
||||
};
|
||||
|
||||
export const dnd_y: SharedControlConfig<'DndMetricSelect'> = {
|
||||
...dnd_adhoc_metric,
|
||||
label: t('Y Axis'),
|
||||
description: t('Metric assigned to the [Y] axis'),
|
||||
};
|
||||
|
||||
export const dnd_secondary_metric: SharedControlConfig<'DndMetricSelect'> = {
|
||||
...dnd_adhoc_metric,
|
||||
label: t('Color Metric'),
|
||||
validators: [],
|
||||
description: t('A metric to use for color'),
|
||||
};
|
||||
|
||||
@@ -70,6 +70,10 @@ import {
|
||||
dnd_adhoc_metric,
|
||||
dnd_adhoc_metrics,
|
||||
dnd_sort_by,
|
||||
dnd_secondary_metric,
|
||||
dnd_size,
|
||||
dnd_x,
|
||||
dnd_y,
|
||||
dndColumnsControl,
|
||||
dndEntity,
|
||||
dndGroupByControl,
|
||||
@@ -389,6 +393,7 @@ const y: SharedControlConfig<'MetricsControl'> = {
|
||||
const size: SharedControlConfig<'MetricsControl'> = {
|
||||
...metric,
|
||||
label: t('Bubble Size'),
|
||||
description: t('Metric used to calculate bubble size'),
|
||||
default: null,
|
||||
};
|
||||
|
||||
@@ -471,7 +476,7 @@ const sharedControls = {
|
||||
color_picker,
|
||||
metric_2,
|
||||
linear_color_scheme,
|
||||
secondary_metric,
|
||||
secondary_metric: enableExploreDnd ? dnd_secondary_metric : secondary_metric,
|
||||
groupby: enableExploreDnd ? dndGroupByControl : groupByControl,
|
||||
columns: enableExploreDnd ? dndColumnsControl : columnsControl,
|
||||
druid_time_origin,
|
||||
@@ -485,9 +490,9 @@ const sharedControls = {
|
||||
orderby: enableExploreDnd ? dnd_sort_by : sort_by,
|
||||
series: enableExploreDnd ? dndSeries : series,
|
||||
entity: enableExploreDnd ? dndEntity : entity,
|
||||
x,
|
||||
y,
|
||||
size,
|
||||
x: enableExploreDnd ? dnd_x : x,
|
||||
y: enableExploreDnd ? dnd_y : y,
|
||||
size: enableExploreDnd ? dnd_size : size,
|
||||
y_axis_format,
|
||||
x_axis_time_format,
|
||||
adhoc_filters: enableExploreDnd ? dnd_adhoc_filters : adhoc_filters,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import { DatasourceMeta } from '../types';
|
||||
|
||||
/**
|
||||
* Convert Dataource columns to column choices
|
||||
* Convert Datasource columns to column choices
|
||||
*/
|
||||
export default function columnChoices(datasource?: DatasourceMeta | null): [string, string][] {
|
||||
return (
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { t, validateNonEmpty } from '@superset-ui/core';
|
||||
import { FeatureFlag, isFeatureEnabled, t, validateNonEmpty } from '@superset-ui/core';
|
||||
import {
|
||||
columnChoices,
|
||||
ControlPanelConfig,
|
||||
ControlPanelState,
|
||||
formatSelectOptions,
|
||||
formatSelectOptionsForRange,
|
||||
sections,
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { dndEntity } from '@superset-ui/chart-controls/lib/shared-controls/dndControls';
|
||||
|
||||
const sortAxisChoices = [
|
||||
['alpha_asc', t('Axis ascending')],
|
||||
@@ -32,6 +34,25 @@ const sortAxisChoices = [
|
||||
['value_desc', t('Metric descending')],
|
||||
];
|
||||
|
||||
const allColumns = {
|
||||
type: 'SelectControl',
|
||||
default: null,
|
||||
description: t('Columns to display'),
|
||||
mapStateToProps: (state: ControlPanelState) => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
validators: [validateNonEmpty],
|
||||
};
|
||||
|
||||
const dndAllColumns = {
|
||||
...dndEntity,
|
||||
description: t('Columns to display'),
|
||||
};
|
||||
|
||||
const columnsConfig = isFeatureEnabled(FeatureFlag.ENABLE_EXPLORE_DRAG_AND_DROP)
|
||||
? dndAllColumns
|
||||
: allColumns;
|
||||
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
sections.legacyRegularTime,
|
||||
@@ -43,27 +64,17 @@ const config: ControlPanelConfig = {
|
||||
{
|
||||
name: 'all_columns_x',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
...columnsConfig,
|
||||
label: 'X Axis',
|
||||
default: null,
|
||||
description: t('Columns to display'),
|
||||
mapStateToProps: state => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
validators: [validateNonEmpty],
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'all_columns_y',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
...columnsConfig,
|
||||
label: 'Y Axis',
|
||||
default: null,
|
||||
description: t('Columns to display'),
|
||||
mapStateToProps: state => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
validators: [validateNonEmpty],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -16,13 +16,37 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { t, validateNonEmpty } from '@superset-ui/core';
|
||||
import { FeatureFlag, isFeatureEnabled, t, validateNonEmpty } from '@superset-ui/core';
|
||||
import {
|
||||
ControlPanelConfig,
|
||||
columnChoices,
|
||||
ControlPanelConfig,
|
||||
ControlPanelState,
|
||||
formatSelectOptions,
|
||||
sections,
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { dndColumnsControl } from '@superset-ui/chart-controls/lib/shared-controls/dndControls';
|
||||
|
||||
const allColumns = {
|
||||
type: 'SelectControl',
|
||||
label: t('Columns'),
|
||||
default: null,
|
||||
description: t('Select the numeric columns to draw the histogram'),
|
||||
mapStateToProps: (state: ControlPanelState) => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
multi: true,
|
||||
validators: [validateNonEmpty],
|
||||
};
|
||||
|
||||
const dndAllColumns = {
|
||||
...dndColumnsControl,
|
||||
description: t('Select the numeric columns to draw the histogram'),
|
||||
validators: [validateNonEmpty],
|
||||
};
|
||||
|
||||
const columnsConfig = isFeatureEnabled(FeatureFlag.ENABLE_EXPLORE_DRAG_AND_DROP)
|
||||
? dndAllColumns
|
||||
: allColumns;
|
||||
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -34,17 +58,7 @@ const config: ControlPanelConfig = {
|
||||
[
|
||||
{
|
||||
name: 'all_columns_x',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
label: t('Columns'),
|
||||
default: null,
|
||||
description: t('Select the numeric columns to draw the histogram'),
|
||||
mapStateToProps: state => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
multi: true,
|
||||
validators: [validateNonEmpty],
|
||||
},
|
||||
config: columnsConfig,
|
||||
},
|
||||
],
|
||||
['adhoc_filters'],
|
||||
|
||||
@@ -16,13 +16,27 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { t } from '@superset-ui/core';
|
||||
import { FeatureFlag, isFeatureEnabled, t } from '@superset-ui/core';
|
||||
import {
|
||||
columnChoices,
|
||||
ControlPanelConfig,
|
||||
ControlPanelState,
|
||||
formatSelectOptions,
|
||||
sections,
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { dndEntity } from '@superset-ui/chart-controls/lib/shared-controls/dndControls';
|
||||
|
||||
const allColumns = {
|
||||
type: 'SelectControl',
|
||||
default: null,
|
||||
mapStateToProps: (state: ControlPanelState) => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
};
|
||||
|
||||
const columnsConfig = isFeatureEnabled(FeatureFlag.ENABLE_EXPLORE_DRAG_AND_DROP)
|
||||
? dndEntity
|
||||
: allColumns;
|
||||
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
@@ -35,25 +49,19 @@ const config: ControlPanelConfig = {
|
||||
{
|
||||
name: 'all_columns_x',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
...columnsConfig,
|
||||
label: t('Longitude'),
|
||||
default: null,
|
||||
description: t('Column containing longitude data'),
|
||||
mapStateToProps: state => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'all_columns_y',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
...columnsConfig,
|
||||
label: t('Latitude'),
|
||||
default: null,
|
||||
description: t('Column containing latitude data'),
|
||||
mapStateToProps: state => ({
|
||||
choices: columnChoices(state.datasource),
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -43,8 +43,8 @@ const config: ControlPanelConfig = {
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[],
|
||||
['series', 'entity'],
|
||||
['series'],
|
||||
['entity'],
|
||||
['x'],
|
||||
['y'],
|
||||
['adhoc_filters'],
|
||||
|
||||
@@ -19,25 +19,27 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import {
|
||||
t,
|
||||
addLocaleData,
|
||||
smartDateFormatter,
|
||||
QueryMode,
|
||||
QueryFormColumn,
|
||||
ChartDataResponseResult,
|
||||
isFeatureEnabled,
|
||||
ensureIsArray,
|
||||
FeatureFlag,
|
||||
isFeatureEnabled,
|
||||
QueryFormColumn,
|
||||
QueryMode,
|
||||
smartDateFormatter,
|
||||
t,
|
||||
} from '@superset-ui/core';
|
||||
import {
|
||||
D3_TIME_FORMAT_OPTIONS,
|
||||
ControlConfig,
|
||||
ColumnOption,
|
||||
ControlStateMapping,
|
||||
ControlConfig,
|
||||
ControlPanelConfig,
|
||||
ControlPanelsContainerProps,
|
||||
sharedControls,
|
||||
sections,
|
||||
ControlStateMapping,
|
||||
D3_TIME_FORMAT_OPTIONS,
|
||||
ExtraControlProps,
|
||||
QueryModeLabel,
|
||||
sections,
|
||||
sharedControls,
|
||||
} from '@superset-ui/chart-controls';
|
||||
|
||||
import i18n from './i18n';
|
||||
@@ -59,7 +61,8 @@ function getQueryMode(controls: ControlStateMapping): QueryMode {
|
||||
* Visibility check
|
||||
*/
|
||||
function isQueryMode(mode: QueryMode) {
|
||||
return ({ controls }: ControlPanelsContainerProps) => getQueryMode(controls) === mode;
|
||||
return ({ controls }: Pick<ControlPanelsContainerProps, 'controls'>) =>
|
||||
getQueryMode(controls) === mode;
|
||||
}
|
||||
|
||||
const isAggMode = isQueryMode(QueryMode.aggregate);
|
||||
@@ -95,6 +98,27 @@ const all_columns: typeof sharedControls.groupby = {
|
||||
visibility: isRawMode,
|
||||
};
|
||||
|
||||
const dnd_all_columns: typeof sharedControls.groupby = {
|
||||
type: 'DndColumnSelect',
|
||||
label: t('Columns'),
|
||||
description: t('Columns to display'),
|
||||
default: [],
|
||||
mapStateToProps({ datasource, controls }, controlState) {
|
||||
const newState: ExtraControlProps = {};
|
||||
if (datasource) {
|
||||
const options = datasource.columns;
|
||||
newState.options = Object.fromEntries(options.map(option => [option.column_name, option]));
|
||||
}
|
||||
newState.queryMode = getQueryMode(controls);
|
||||
newState.externalValidationErrors =
|
||||
isRawMode({ controls }) && ensureIsArray(controlState.value).length === 0
|
||||
? [t('must have a value')]
|
||||
: [];
|
||||
return newState;
|
||||
},
|
||||
visibility: isRawMode,
|
||||
};
|
||||
|
||||
const percent_metrics: typeof sharedControls.metrics = {
|
||||
type: 'MetricsControl',
|
||||
label: t('Percentage metrics'),
|
||||
@@ -149,7 +173,9 @@ const config: ControlPanelConfig = {
|
||||
},
|
||||
{
|
||||
name: 'all_columns',
|
||||
config: all_columns,
|
||||
config: isFeatureEnabled(FeatureFlag.ENABLE_EXPLORE_DRAG_AND_DROP)
|
||||
? dnd_all_columns
|
||||
: all_columns,
|
||||
},
|
||||
],
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user