From 2bf767346c6e5a0148857689b20d4041f4a01a45 Mon Sep 17 00:00:00 2001
From: Aleksandr Lesnenko <alxnddr@users.noreply.github.com>
Date: Fri, 24 Feb 2023 22:15:58 -0300
Subject: [PATCH] stack area chart with breakouts (#28625)

---
 .../visualizations/lib/settings/graph.js      | 19 +++++---
 .../lib/settings/graph.unit.spec.js           | 46 +++++++++++++++++++
 src/metabase/pulse/render/body.clj            |  4 +-
 3 files changed, 62 insertions(+), 7 deletions(-)
 create mode 100644 frontend/src/metabase/visualizations/lib/settings/graph.unit.spec.js

diff --git a/frontend/src/metabase/visualizations/lib/settings/graph.js b/frontend/src/metabase/visualizations/lib/settings/graph.js
index 1d98fa1d9a0..a08bf5d95b1 100644
--- a/frontend/src/metabase/visualizations/lib/settings/graph.js
+++ b/frontend/src/metabase/visualizations/lib/settings/graph.js
@@ -358,12 +358,19 @@ export const STACKABLE_SETTINGS = {
       }
       return true;
     },
-    getDefault: ([{ card, data }], settings) =>
+    getDefault: ([{ card, data }], settings) => {
       // legacy setting and default for D-M-M+ charts
-      settings["stackable.stacked"] ||
-      (card.display === "area" && settings["graph.metrics"].length > 1)
-        ? "stacked"
-        : null,
+      if (settings["stackable.stacked"]) {
+        return settings["stackable.stacked"];
+      }
+
+      const shouldStack =
+        card.display === "area" &&
+        (settings["graph.metrics"].length > 1 ||
+          settings["graph.dimensions"].length > 1);
+
+      return shouldStack ? "stacked" : null;
+    },
     getHidden: (series, settings) => {
       const displays = series.map(single => settings.series(single).display);
       const stackableDisplays = displays.filter(display =>
@@ -371,7 +378,7 @@ export const STACKABLE_SETTINGS = {
       );
       return stackableDisplays.length <= 1;
     },
-    readDependencies: ["graph.metrics", "series"],
+    readDependencies: ["graph.metrics", "graph.dimensions", "series"],
   },
   "stackable.stack_display": {
     section: t`Display`,
diff --git a/frontend/src/metabase/visualizations/lib/settings/graph.unit.spec.js b/frontend/src/metabase/visualizations/lib/settings/graph.unit.spec.js
new file mode 100644
index 00000000000..75fbc9c1a6e
--- /dev/null
+++ b/frontend/src/metabase/visualizations/lib/settings/graph.unit.spec.js
@@ -0,0 +1,46 @@
+import { STACKABLE_SETTINGS } from "./graph";
+
+describe("STACKABLE_SETTINGS", () => {
+  describe("stackable.stack_type", () => {
+    describe("getDefault", () => {
+      const getDefault = STACKABLE_SETTINGS["stackable.stack_type"].getDefault;
+
+      it("should return stacked if area chart has more than 1 metric", () => {
+        const value = getDefault([{ card: { display: "area" } }], {
+          "graph.metrics": ["foo", "bar"],
+          "graph.dimensions": [],
+        });
+
+        expect(value).toBe("stacked");
+      });
+
+      it("should return stacked if area chart has more than 1 dimension", () => {
+        const value = getDefault([{ card: { display: "area" } }], {
+          "graph.metrics": [],
+          "graph.dimensions": ["foo", "bar"],
+        });
+
+        expect(value).toBe("stacked");
+      });
+
+      it("should return null if area chart has 1 metric and 1 dimension", () => {
+        const value = getDefault([{ card: { display: "area" } }], {
+          "graph.metrics": ["foo"],
+          "graph.dimensions": ["bar"],
+        });
+
+        expect(value).toBeNull();
+      });
+
+      it("should return the legacy 'stackable.stacked' value if present", () => {
+        const value = getDefault([{ card: { display: "area" } }], {
+          "stackable.stacked": "normalized",
+          "graph.metrics": ["foo", "bar"],
+          "graph.dimensions": ["bar"],
+        });
+
+        expect(value).toBe("normalized");
+      });
+    });
+  });
+});
diff --git a/src/metabase/pulse/render/body.clj b/src/metabase/pulse/render/body.clj
index 936bab5ffe1..0ba8a833d97 100644
--- a/src/metabase/pulse/render/body.clj
+++ b/src/metabase/pulse/render/body.clj
@@ -347,7 +347,9 @@
                       (= (:stackable.stack_type viz-settings) "stacked")
                       (and
                        (= (:display card) :area)
-                       (> (count (:graph.metrics viz-settings)) 1)))]
+                       (or
+                        (> (count (:graph.metrics viz-settings)) 1)
+                        (> (count (:graph.dimensions viz-settings)) 1))))]
     (if stacked
       (assoc viz-settings :stackable.stack_type "stacked")
       viz-settings)))
-- 
GitLab