superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: Allow specifying sort criteria on Table viz (#3460)
Date Thu, 14 Sep 2017 03:18:49 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 816c517  Allow specifying sort criteria on Table viz (#3460)
816c517 is described below

commit 816c517f0fafe32373165930af0a03e320ce7758
Author: Maxime Beauchemin <maximebeauchemin@gmail.com>
AuthorDate: Wed Sep 13 20:18:47 2017 -0700

    Allow specifying sort criteria on Table viz (#3460)
    
    * Allow to specify sort criteria on table viz
    
    * Better handling of ordering
---
 .../explore/components/ControlPanelsContainer.jsx  |  9 +++---
 .../assets/javascripts/explore/stores/controls.jsx |  7 +++++
 .../assets/javascripts/explore/stores/visTypes.js  |  4 ++-
 superset/assets/visualizations/table.js            | 18 ++++++++++--
 superset/connectors/sqla/models.py                 | 33 +++++++++++++---------
 superset/viz.py                                    |  5 ++++
 6 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx b/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx
index dfa958c..198529a 100644
--- a/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx
+++ b/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx
@@ -65,10 +65,11 @@ class ControlPanelsContainer extends React.Component {
             </Alert>
           }
           {this.sectionsToRender().map((section) => {
-            const hasErrors = section.controlSetRows.some(rows => rows.some((s) =>
{
-              const errors = ctrls[s].validationErrors;
-              return errors && (errors.length > 0);
-            }));
+            const hasErrors = section.controlSetRows.some(rows => rows.some(s => (
+                ctrls[s] &&
+                ctrls[s].validationErrors &&
+                (ctrls[s].validationErrors.length > 0)
+            )));
             return (
               <ControlPanelSection
                 key={section.label}
diff --git a/superset/assets/javascripts/explore/stores/controls.jsx b/superset/assets/javascripts/explore/stores/controls.jsx
index c885233..b87e988 100644
--- a/superset/assets/javascripts/explore/stores/controls.jsx
+++ b/superset/assets/javascripts/explore/stores/controls.jsx
@@ -669,6 +669,13 @@ export const controls = {
     }),
   },
 
+  order_desc: {
+    type: 'CheckboxControl',
+    label: 'Sort Descending',
+    default: true,
+    description: 'Whether to sort descending or ascending',
+  },
+
   rolling_type: {
     type: 'SelectControl',
     label: 'Rolling',
diff --git a/superset/assets/javascripts/explore/stores/visTypes.js b/superset/assets/javascripts/explore/stores/visTypes.js
index 4f9ebb8..6f4f7ce 100644
--- a/superset/assets/javascripts/explore/stores/visTypes.js
+++ b/superset/assets/javascripts/explore/stores/visTypes.js
@@ -51,6 +51,7 @@ export const sections = {
         ['metrics'],
         ['groupby'],
         ['limit', 'timeseries_limit_metric'],
+        ['order_desc', null],
       ],
     },
     {
@@ -324,7 +325,8 @@ export const visTypes = {
         description: 'Use this section if you want a query that aggregates',
         controlSetRows: [
           ['groupby', 'metrics'],
-          ['include_time'],
+          ['include_time', null],
+          ['timeseries_limit_metric', 'order_desc'],
         ],
       },
       {
diff --git a/superset/assets/visualizations/table.js b/superset/assets/visualizations/table.js
index 80808af..6985a25 100644
--- a/superset/assets/visualizations/table.js
+++ b/superset/assets/visualizations/table.js
@@ -139,10 +139,22 @@ function tableVis(slice, payload) {
   fixDataTableBodyHeight(
       container.find('.dataTables_wrapper'), height);
   // Sorting table by main column
-  if (metrics.length > 0) {
-    const mainMetric = metrics[0];
-    datatable.column(data.columns.indexOf(mainMetric)).order('desc').draw();
+  let sortBy;
+  if (fd.timeseries_limit_metric) {
+    // Sort by as specified
+    sortBy = fd.timeseries_limit_metric;
+  } else if (metrics.length > 0) {
+    // If not specified, use the first metric from the list
+    sortBy = metrics[0];
   }
+  if (sortBy) {
+    datatable.column(data.columns.indexOf(sortBy)).order(fd.order_desc ? 'desc' : 'asc');
+  }
+  if (fd.timeseries_limit_metric && metrics.indexOf(fd.timeseries_limit_metric) <
0) {
+    // Hiding the sortBy column if not in the metrics list
+    datatable.column(data.columns.indexOf(sortBy)).visible(false);
+  }
+  datatable.draw();
   container.parents('.widget').find('.tooltip').remove();
 }
 
diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py
index 03c8c54..245da8a 100644
--- a/superset/connectors/sqla/models.py
+++ b/superset/connectors/sqla/models.py
@@ -378,6 +378,8 @@ class SqlaTable(Model, BaseDatasource):
         template_processor = self.get_template_processor(**template_kwargs)
         db_engine_spec = self.database.db_engine_spec
 
+        orderby = orderby or []
+
         # For backward compatibility
         if granularity not in self.dttm_cols:
             granularity = self.main_dttm_col
@@ -392,15 +394,12 @@ class SqlaTable(Model, BaseDatasource):
             raise Exception(_(
                 "Datetime column not provided as part table configuration "
                 "and is required by this type of chart"))
+        if not groupby and not metrics and not columns:
+            raise Exception(_("Empty query?"))
         for m in metrics:
             if m not in metrics_dict:
                 raise Exception(_("Metric '{}' is not valid".format(m)))
         metrics_exprs = [metrics_dict.get(m).sqla_col for m in metrics]
-        timeseries_limit_metric = metrics_dict.get(timeseries_limit_metric)
-        timeseries_limit_metric_expr = None
-        if timeseries_limit_metric:
-            timeseries_limit_metric_expr = \
-                timeseries_limit_metric.sqla_col
         if metrics_exprs:
             main_metric_expr = metrics_exprs[0]
         else:
@@ -512,13 +511,16 @@ class SqlaTable(Model, BaseDatasource):
         else:
             qry = qry.where(and_(*where_clause_and))
         qry = qry.having(and_(*having_clause_and))
-        if groupby:
-            direction = desc if order_desc else asc
-            qry = qry.order_by(direction(main_metric_expr))
-        elif orderby:
-            for col, ascending in orderby:
-                direction = asc if ascending else desc
-                qry = qry.order_by(direction(col))
+
+        if not orderby and not columns:
+            orderby = [(main_metric_expr, not order_desc)]
+
+        for col, ascending in orderby:
+            direction = asc if ascending else desc
+            print('-='*20)
+            print([col, ascending])
+            print('-='*20)
+            qry = qry.order_by(direction(col))
 
         if row_limit:
             qry = qry.limit(row_limit)
@@ -538,12 +540,15 @@ class SqlaTable(Model, BaseDatasource):
             )
             subq = subq.where(and_(*(where_clause_and + [inner_time_filter])))
             subq = subq.group_by(*inner_groupby_exprs)
+
             ob = inner_main_metric_expr
-            if timeseries_limit_metric_expr is not None:
-                ob = timeseries_limit_metric_expr
+            if timeseries_limit_metric:
+                timeseries_limit_metric = metrics_dict.get(timeseries_limit_metric)
+                ob = timeseries_limit_metric.sqla_col
             direction = desc if order_desc else asc
             subq = subq.order_by(direction(ob))
             subq = subq.limit(timeseries_limit)
+
             on_clause = []
             for i, gb in enumerate(groupby):
                 on_clause.append(
diff --git a/superset/viz.py b/superset/viz.py
index bb4c594..0e952b3 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -351,11 +351,16 @@ class TableViz(BaseViz):
                 "Choose either fields to [Group By] and [Metrics] or "
                 "[Columns], not both"))
 
+        sort_by = fd.get('timeseries_limit_metric')
         if fd.get('all_columns'):
             d['columns'] = fd.get('all_columns')
             d['groupby'] = []
             order_by_cols = fd.get('order_by_cols') or []
             d['orderby'] = [json.loads(t) for t in order_by_cols]
+        elif sort_by:
+            if sort_by not in d['metrics']:
+                d['metrics'] += [sort_by]
+            d['orderby'] = [(sort_by, not fd.get("order_desc", True))]
 
         d['is_timeseries'] = self.should_be_timeseries()
         return d

-- 
To stop receiving notification emails like this one, please contact
['"commits@superset.apache.org" <commits@superset.apache.org>'].

Mime
View raw message