diff --git a/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx b/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx
index ac82bb490c3..8a2e52819d7 100644
--- a/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx
+++ b/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx
@@ -28,6 +28,7 @@ class ControlPanelsContainer extends React.Component {
this.getControlData = this.getControlData.bind(this);
}
getControlData(controlName) {
+ const control = this.props.controls[controlName];
// Identifying mapStateToProps function to apply (logic can't be in store)
let mapF = controls[controlName].mapStateToProps;
@@ -38,9 +39,9 @@ class ControlPanelsContainer extends React.Component {
}
// Applying mapStateToProps if needed
if (mapF) {
- return Object.assign({}, this.props.controls[controlName], mapF(this.props.exploreState));
+ return Object.assign({}, control, mapF(this.props.exploreState, control));
}
- return this.props.controls[controlName];
+ return control;
}
sectionsToRender() {
return sectionsToRender(this.props.form_data.viz_type, this.props.datasource_type);
diff --git a/superset/assets/javascripts/explore/stores/controls.jsx b/superset/assets/javascripts/explore/stores/controls.jsx
index 7ef5a3e60e0..3d33873c3c5 100644
--- a/superset/assets/javascripts/explore/stores/controls.jsx
+++ b/superset/assets/javascripts/explore/stores/controls.jsx
@@ -28,6 +28,36 @@ export const D3_TIME_FORMAT_OPTIONS = [
['%H:%M:%S', '%H:%M:%S | 01:32:10'],
];
+const timeColumnOption = {
+ verbose_name: 'Time',
+ column_name: '__timestamp',
+ description: (
+ 'A reference to the [Time] configuration, taking granularity into ' +
+ 'account'),
+};
+
+const groupByControl = {
+ type: 'SelectControl',
+ multi: true,
+ label: 'Group by',
+ default: [],
+ includeTime: false,
+ description: 'One or many controls to group by',
+ optionRenderer: c => ,
+ valueRenderer: c => ,
+ valueKey: 'column_name',
+ mapStateToProps: (state, control) => {
+ const newState = {};
+ if (state.datasource) {
+ newState.options = state.datasource.columns.filter(c => c.groupby);
+ if (control && control.includeTime) {
+ newState.options.push(timeColumnOption);
+ }
+ }
+ return newState;
+ },
+};
+
export const controls = {
datasource: {
type: 'DatasourceControl',
@@ -323,33 +353,12 @@ export const controls = {
'to find in the [country] column',
},
- groupby: {
- type: 'SelectControl',
- multi: true,
- label: 'Group by',
- default: [],
- description: 'One or many controls to group by',
- optionRenderer: c => ,
- valueRenderer: c => ,
- valueKey: 'column_name',
- mapStateToProps: state => ({
- options: (state.datasource) ? state.datasource.columns.filter(c => c.groupby) : [],
- }),
- },
+ groupby: groupByControl,
- columns: {
- type: 'SelectControl',
- multi: true,
+ columns: Object.assign({}, groupByControl, {
label: 'Columns',
- default: [],
description: 'One or many controls to pivot as columns',
- optionRenderer: c => ,
- valueRenderer: c => ,
- valueKey: 'column_name',
- mapStateToProps: state => ({
- options: (state.datasource) ? state.datasource.columns : [],
- }),
- },
+ }),
all_columns: {
type: 'SelectControl',
diff --git a/superset/assets/javascripts/explore/stores/store.js b/superset/assets/javascripts/explore/stores/store.js
index 2cd2874c266..af809ed2fa5 100644
--- a/superset/assets/javascripts/explore/stores/store.js
+++ b/superset/assets/javascripts/explore/stores/store.js
@@ -52,7 +52,7 @@ export function getControlsState(state, form_data) {
controlNames.forEach((k) => {
const control = Object.assign({}, controls[k], controlOverrides[k]);
if (control.mapStateToProps) {
- Object.assign(control, control.mapStateToProps(state));
+ Object.assign(control, control.mapStateToProps(state, control));
delete control.mapStateToProps;
}
diff --git a/superset/assets/javascripts/explore/stores/visTypes.js b/superset/assets/javascripts/explore/stores/visTypes.js
index 4dd2700c5ea..1df8e11c726 100644
--- a/superset/assets/javascripts/explore/stores/visTypes.js
+++ b/superset/assets/javascripts/explore/stores/visTypes.js
@@ -337,10 +337,15 @@ export const visTypes = {
controlSetRows: [
['groupby', 'columns'],
['metrics', 'pandas_aggfunc'],
- ['number_format', 'combine_metric', 'pivot_margins'],
+ ['number_format', 'combine_metric'],
+ ['pivot_margins'],
],
},
],
+ controlOverrides: {
+ groupby: { includeTime: true },
+ columns: { includeTime: true },
+ },
},
separator: {
diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py
index b836a153e14..6759d2c9079 100644
--- a/superset/connectors/sqla/models.py
+++ b/superset/connectors/sqla/models.py
@@ -376,6 +376,10 @@ class SqlaTable(Model, BaseDatasource):
template_processor = self.get_template_processor(**template_kwargs)
db_engine_spec = self.database.db_engine_spec
+ if DTTM_ALIAS in groupby:
+ groupby.remove(DTTM_ALIAS)
+ is_timeseries = True
+
# For backward compatibility
if granularity not in self.dttm_cols:
granularity = self.main_dttm_col