You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ms...@apache.org on 2026/05/05 10:16:14 UTC

(superset) 01/01: feat(mcp): chart formatting options

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

msyavuz pushed a commit to branch feat/mcp-chart-color-scheme
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0b97cc51701b6ec84cb0c7b78e1c3ab6c629cc69
Author: Mehmet Salih Yavuz <sa...@proton.me>
AuthorDate: Tue May 5 13:15:18 2026 +0300

    feat(mcp): chart formatting options
---
 superset/mcp_service/chart/chart_utils.py          |  9 +++++++-
 superset/mcp_service/chart/schemas.py              | 17 ++++++++++++++
 .../mcp_service/chart/test_chart_utils.py          | 27 ++++++++++++++++++++++
 .../mcp_service/chart/test_new_chart_types.py      | 12 ++++++++++
 4 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/superset/mcp_service/chart/chart_utils.py b/superset/mcp_service/chart/chart_utils.py
index 5b865c1f0dd..48d1d7e8943 100644
--- a/superset/mcp_service/chart/chart_utils.py
+++ b/superset/mcp_service/chart/chart_utils.py
@@ -542,6 +542,12 @@ def add_legend_config(form_data: Dict[str, Any], config: XYChartConfig) -> None:
             form_data["legend_orientation"] = config.legend.position
 
 
+def add_color_scheme(form_data: Dict[str, Any], config: XYChartConfig) -> None:
+    """Add color scheme to form_data when set."""
+    if config.color_scheme:
+        form_data["color_scheme"] = config.color_scheme
+
+
 def add_orientation_config(form_data: Dict[str, Any], config: XYChartConfig) -> None:
     """Add orientation configuration to form_data for bar charts.
 
@@ -714,6 +720,7 @@ def map_xy_config(
     add_axis_config(form_data, config)
     add_legend_config(form_data, config)
     add_orientation_config(form_data, config)
+    add_color_scheme(form_data, config)
 
     return form_data
 
@@ -726,7 +733,7 @@ def map_pie_config(config: PieChartConfig) -> Dict[str, Any]:
         "viz_type": "pie",
         "groupby": [config.dimension.name],
         "metric": metric,
-        "color_scheme": "supersetColors",
+        "color_scheme": config.color_scheme or "supersetColors",
         "show_labels": config.show_labels,
         "show_legend": config.show_legend,
         "label_type": config.label_type,
diff --git a/superset/mcp_service/chart/schemas.py b/superset/mcp_service/chart/schemas.py
index 1fdb4f43ab6..c8c80e620d4 100644
--- a/superset/mcp_service/chart/schemas.py
+++ b/superset/mcp_service/chart/schemas.py
@@ -838,6 +838,14 @@ class PieChartConfig(UnknownFieldCheckMixin):
     )
     row_limit: int = Field(100, description="Max slices", ge=1, le=10000)
     number_format: str = Field("SMART_NUMBER", max_length=50)
+    color_scheme: str | None = Field(
+        None,
+        description=(
+            "Superset color scheme ID (e.g. 'supersetColors', 'lyftColors', "
+            "'googleCategory10c', 'd3Category10'). Defaults to 'supersetColors'."
+        ),
+        max_length=100,
+    )
     show_total: bool = Field(False, description="Show total in center")
     labels_outside: bool = True
     outer_radius: int = Field(70, description="Outer radius % (1-100)", ge=1, le=100)
@@ -1275,6 +1283,15 @@ class XYChartConfig(UnknownFieldCheckMixin):
     x_axis: AxisConfig | None = None
     y_axis: AxisConfig | None = None
     legend: LegendConfig | None = None
+    color_scheme: str | None = Field(
+        None,
+        description=(
+            "Superset color scheme ID (e.g. 'supersetColors', 'lyftColors', "
+            "'googleCategory10c', 'd3Category10'). When omitted, Superset's "
+            "default scheme is used."
+        ),
+        max_length=100,
+    )
     filters: List[FilterConfig] | None = Field(
         None,
         description="Structured filters (column/op/value). "
diff --git a/tests/unit_tests/mcp_service/chart/test_chart_utils.py b/tests/unit_tests/mcp_service/chart/test_chart_utils.py
index 7c2da4e5de7..b2532863ed2 100644
--- a/tests/unit_tests/mcp_service/chart/test_chart_utils.py
+++ b/tests/unit_tests/mcp_service/chart/test_chart_utils.py
@@ -554,6 +554,33 @@ class TestMapXYConfig:
         assert result["show_legend"] is False
         assert result["legend_orientation"] == "top"
 
+    def test_map_xy_config_with_color_scheme(self) -> None:
+        """color_scheme propagates to form_data when set."""
+        config = XYChartConfig(
+            chart_type="xy",
+            x=ColumnRef(name="date"),
+            y=[ColumnRef(name="revenue")],
+            kind="line",
+            color_scheme="lyftColors",
+        )
+
+        result = map_xy_config(config)
+
+        assert result["color_scheme"] == "lyftColors"
+
+    def test_map_xy_config_without_color_scheme(self) -> None:
+        """color_scheme key omitted when not set, leaving Superset default."""
+        config = XYChartConfig(
+            chart_type="xy",
+            x=ColumnRef(name="date"),
+            y=[ColumnRef(name="revenue")],
+            kind="line",
+        )
+
+        result = map_xy_config(config)
+
+        assert "color_scheme" not in result
+
     def test_map_xy_config_with_time_grain_month(self) -> None:
         """Test XY config mapping with monthly time grain"""
         config = XYChartConfig(
diff --git a/tests/unit_tests/mcp_service/chart/test_new_chart_types.py b/tests/unit_tests/mcp_service/chart/test_new_chart_types.py
index 9469f63b39a..9725c52ffed 100644
--- a/tests/unit_tests/mcp_service/chart/test_new_chart_types.py
+++ b/tests/unit_tests/mcp_service/chart/test_new_chart_types.py
@@ -212,6 +212,18 @@ class TestMapPieConfig:
         assert result["adhoc_filters"][0]["operator"] == "=="
         assert result["adhoc_filters"][0]["comparator"] == "US"
 
+    def test_pie_form_data_color_scheme_override(self) -> None:
+        """Explicit color_scheme overrides the supersetColors default."""
+        config = PieChartConfig(
+            chart_type="pie",
+            dimension=ColumnRef(name="product"),
+            metric=ColumnRef(name="revenue", aggregate="SUM"),
+            color_scheme="googleCategory10c",
+        )
+        result = map_pie_config(config)
+
+        assert result["color_scheme"] == "googleCategory10c"
+
     def test_pie_form_data_custom_options(self) -> None:
         config = PieChartConfig(
             chart_type="pie",