You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2021/01/29 14:25:41 UTC

[superset] 03/18: fix(explore): preserve metric column order in bar chart (#12417)

This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 368691383b2d0d539525e95df8c99a1683fa7f01
Author: Duy Nguyen Hoang <nh...@gmail.com>
AuthorDate: Thu Jan 28 15:39:00 2021 +0700

    fix(explore): preserve metric column order in bar chart (#12417)
    
    * fix: Preserve Column Order in Bar chart
    
    * Update tests/viz_tests.py to use f-strings style
    
    Co-authored-by: Duy Nguyen <du...@global-fashion-group.com>
---
 superset/viz.py       |   5 ++-
 superset/viz_sip38.py |   4 ++
 tests/viz_tests.py    | 111 ++++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 107 insertions(+), 13 deletions(-)

diff --git a/superset/viz.py b/superset/viz.py
index a2e2b98..63b530c 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -155,7 +155,7 @@ class BaseViz:
         return self._force_cached
 
     def process_metrics(self) -> None:
-        # metrics in TableViz is order sensitive, so metric_dict should be
+        # metrics in Viz is order sensitive, so metric_dict should be
         # OrderedDict
         self.metric_dict = OrderedDict()
         fd = self.form_data
@@ -1706,6 +1706,9 @@ class DistributionBarViz(BaseViz):
             pt = pt.T
             pt = (pt / pt.sum()).T
         pt = pt.reindex(row.index)
+
+        # Re-order the columns adhering to the metric ordering.
+        pt = pt[metrics]
         chart_data = []
         for name, ys in pt.items():
             if pt[name].dtype.kind not in "biufc" or name in self.groupby:
diff --git a/superset/viz_sip38.py b/superset/viz_sip38.py
index 9ec1752..39ae0b7 100644
--- a/superset/viz_sip38.py
+++ b/superset/viz_sip38.py
@@ -1629,6 +1629,10 @@ class DistributionBarViz(DistributionPieViz):
             pt = pt.T
             pt = (pt / pt.sum()).T
         pt = pt.reindex(row.index)
+
+        # Re-order the columns adhering to the metric ordering.
+        pt = pt[metrics]
+
         chart_data = []
         for name, ys in pt.items():
             if pt[name].dtype.kind not in "biufc" or name in groupby:
diff --git a/tests/viz_tests.py b/tests/viz_tests.py
index 09fd3a7..d1232c1 100644
--- a/tests/viz_tests.py
+++ b/tests/viz_tests.py
@@ -79,10 +79,10 @@ class TestBaseViz(SupersetTestCase):
         datasource.type = "table"
         test_viz = viz.BaseViz(datasource, form_data)
         expect_metric_labels = [
-            u"sum__SP_POP_TOTL",
-            u"SUM(SE_PRM_NENR_MA)",
-            u"SUM(SP_URB_TOTL)",
-            u"count",
+            "sum__SP_POP_TOTL",
+            "SUM(SE_PRM_NENR_MA)",
+            "SUM(SP_URB_TOTL)",
+            "count",
         ]
         self.assertEqual(test_viz.metric_labels, expect_metric_labels)
         self.assertEqual(test_viz.all_metrics, expect_metric_labels)
@@ -500,6 +500,7 @@ class TestDistBarViz(SupersetTestCase):
             {"x": "2.0", "y": 29},
             {"x": NULL_STRING, "y": 3},
         ]
+
         self.assertEqual(expected_values, data["values"])
 
     def test_column_nulls(self):
@@ -531,6 +532,92 @@ class TestDistBarViz(SupersetTestCase):
         ]
         self.assertEqual(expected, data)
 
+    def test_column_metrics_in_order(self):
+        form_data = {
+            "metrics": ["z_column", "votes", "a_column"],
+            "adhoc_filters": [],
+            "groupby": ["toppings"],
+            "columns": [],
+        }
+        datasource = self.get_datasource_mock()
+        df = pd.DataFrame(
+            {
+                "toppings": ["cheese", "pepperoni", "cheese", "pepperoni"],
+                "role": ["engineer", "engineer", None, None],
+                "votes": [3, 5, 1, 2],
+                "a_column": [3, 5, 1, 2],
+                "z_column": [3, 5, 1, 2],
+            }
+        )
+        test_viz = viz.DistributionBarViz(datasource, form_data)
+        data = test_viz.get_data(df)
+
+        expected = [
+            {
+                "key": "z_column",
+                "values": [{"x": "pepperoni", "y": 3.5}, {"x": "cheese", "y": 2.0}],
+            },
+            {
+                "key": "votes",
+                "values": [{"x": "pepperoni", "y": 3.5}, {"x": "cheese", "y": 2.0}],
+            },
+            {
+                "key": "a_column",
+                "values": [{"x": "pepperoni", "y": 3.5}, {"x": "cheese", "y": 2.0}],
+            },
+        ]
+
+        self.assertEqual(expected, data)
+
+    def test_column_metrics_in_order_with_breakdowns(self):
+        form_data = {
+            "metrics": ["z_column", "votes", "a_column"],
+            "adhoc_filters": [],
+            "groupby": ["toppings"],
+            "columns": ["role"],
+        }
+        datasource = self.get_datasource_mock()
+        df = pd.DataFrame(
+            {
+                "toppings": ["cheese", "pepperoni", "cheese", "pepperoni"],
+                "role": ["engineer", "engineer", None, None],
+                "votes": [3, 5, 1, 2],
+                "a_column": [3, 5, 1, 2],
+                "z_column": [3, 5, 1, 2],
+            }
+        )
+        test_viz = viz.DistributionBarViz(datasource, form_data)
+        data = test_viz.get_data(df)
+
+        expected = [
+            {
+                "key": f"z_column, {NULL_STRING}",
+                "values": [{"x": "pepperoni", "y": 2}, {"x": "cheese", "y": 1}],
+            },
+            {
+                "key": "z_column, engineer",
+                "values": [{"x": "pepperoni", "y": 5}, {"x": "cheese", "y": 3}],
+            },
+            {
+                "key": f"votes, {NULL_STRING}",
+                "values": [{"x": "pepperoni", "y": 2}, {"x": "cheese", "y": 1}],
+            },
+            {
+                "key": "votes, engineer",
+                "values": [{"x": "pepperoni", "y": 5}, {"x": "cheese", "y": 3}],
+            },
+            {
+                "key": f"a_column, {NULL_STRING}",
+                "values": [{"x": "pepperoni", "y": 2}, {"x": "cheese", "y": 1}],
+            },
+            {
+                "key": "a_column, engineer",
+                "values": [{"x": "pepperoni", "y": 5}, {"x": "cheese", "y": 3}],
+            },
+        ]
+
+        self.assertEqual(expected, data)
+
 
 class TestPairedTTest(SupersetTestCase):
     def test_get_data_transforms_dataframe(self):
@@ -1179,18 +1266,18 @@ class TestTimeSeriesViz(SupersetTestCase):
         viz_data = test_viz.get_data(df)
         expected = [
             {
-                u"values": [
-                    {u"y": 4, u"x": u"2018-02-20T00:00:00"},
-                    {u"y": 4, u"x": u"2018-03-09T00:00:00"},
+                "values": [
+                    {"y": 4, "x": "2018-02-20T00:00:00"},
+                    {"y": 4, "x": "2018-03-09T00:00:00"},
                 ],
-                u"key": (u"Real Madrid Basket",),
+                "key": ("Real Madrid Basket",),
             },
             {
-                u"values": [
-                    {u"y": 2, u"x": u"2018-02-20T00:00:00"},
-                    {u"y": 2, u"x": u"2018-03-09T00:00:00"},
+                "values": [
+                    {"y": 2, "x": "2018-02-20T00:00:00"},
+                    {"y": 2, "x": "2018-03-09T00:00:00"},
                 ],
-                u"key": (u"Real Madrid C.F.\U0001f1fa\U0001f1f8\U0001f1ec\U0001f1e7",),
+                "key": ("Real Madrid C.F.\U0001f1fa\U0001f1f8\U0001f1ec\U0001f1e7",),
             },
         ]
         self.assertEqual(expected, viz_data)