mirror of
https://github.com/apache/superset.git
synced 2026-05-21 15:55:10 +00:00
feat(mcp): add display_name and native_viz_types to chart type plugins
Each ChartTypePlugin now declares:
- display_name: human-readable label for the chart_type discriminator
(e.g. "Line / Bar / Area / Scatter Chart", "Pivot Table")
- native_viz_types: dict mapping every Superset-internal viz_type the
plugin produces to a user-friendly name
(e.g. {"echarts_timeseries_line": "Line Chart", "echarts_area": "Area Chart"})
The registry gains display_name_for_viz_type(viz_type) which searches
all plugins' native_viz_types maps, replacing the need for a separate
viz_type_display_names.json or viz_type_names.py module.
ChartInfo gains a chart_type_display_name field populated via the registry,
so list_charts / get_chart_info return human-readable chart type names.
The MCP system instructions now reference display names rather than
internal viz_type identifiers.
This commit is contained in:
@@ -222,10 +222,14 @@ Time grain for temporal x-axis (time_grain parameter):
|
||||
- PT1H (hourly), P1D (daily), P1W (weekly), P1M (monthly), P1Y (yearly)
|
||||
|
||||
Chart Types in Existing Charts (viewable via list_charts/get_chart_info):
|
||||
- pie, big_number, big_number_total, funnel, gauge_chart
|
||||
- echarts_timeseries_line, echarts_timeseries_bar, echarts_timeseries_area
|
||||
- pivot_table_v2, heatmap_v2, sankey_v2, sunburst_v2, treemap_v2
|
||||
- word_cloud, world_map, box_plot, bubble, mixed_timeseries
|
||||
Each chart returned by list_charts / get_chart_info includes a
|
||||
chart_type_display_name field with a human-readable name. Use that name
|
||||
when referring to chart types — do NOT expose raw viz_type identifiers.
|
||||
Common display names: Line Chart, Bar Chart, Area Chart, Scatter Plot,
|
||||
Pie Chart, Table, Interactive Table, Pivot Table, Big Number,
|
||||
Big Number with Trendline, Mixed Timeseries Chart, Custom Template Chart,
|
||||
Funnel Chart, Gauge Chart, Heatmap, Sankey Chart, Sunburst, Treemap,
|
||||
Word Cloud, World Map, Box Plot, Bubble Chart.
|
||||
|
||||
Query Examples:
|
||||
- List all tables:
|
||||
|
||||
@@ -46,6 +46,15 @@ class ChartTypePlugin(Protocol):
|
||||
#: Discriminator value matching ChartConfig's chart_type field.
|
||||
chart_type: str
|
||||
|
||||
#: Human-readable name shown to users (e.g. "Line / Bar / Area / Scatter").
|
||||
display_name: str
|
||||
|
||||
#: Maps every Superset-internal viz_type this plugin can produce to a
|
||||
#: user-facing display name, e.g. {"echarts_timeseries_line": "Line Chart"}.
|
||||
#: Used by the registry to resolve display names for existing charts without
|
||||
#: needing a separate JSON mapping file.
|
||||
native_viz_types: dict[str, str]
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
config: dict[str, Any],
|
||||
@@ -148,6 +157,8 @@ class BaseChartPlugin:
|
||||
"""
|
||||
|
||||
chart_type: str = ""
|
||||
display_name: str = ""
|
||||
native_viz_types: dict[str, str] = {}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -30,6 +30,11 @@ class BigNumberChartPlugin(BaseChartPlugin):
|
||||
"""Plugin for big_number chart type."""
|
||||
|
||||
chart_type = "big_number"
|
||||
display_name = "Big Number"
|
||||
native_viz_types = {
|
||||
"big_number": "Big Number with Trendline",
|
||||
"big_number_total": "Big Number",
|
||||
}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -30,6 +30,10 @@ class HandlebarsChartPlugin(BaseChartPlugin):
|
||||
"""Plugin for handlebars chart type (custom HTML template charts)."""
|
||||
|
||||
chart_type = "handlebars"
|
||||
display_name = "Handlebars (Custom Template)"
|
||||
native_viz_types = {
|
||||
"handlebars": "Custom Template Chart",
|
||||
}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -30,6 +30,10 @@ class MixedTimeseriesChartPlugin(BaseChartPlugin):
|
||||
"""Plugin for mixed_timeseries chart type."""
|
||||
|
||||
chart_type = "mixed_timeseries"
|
||||
display_name = "Mixed Timeseries"
|
||||
native_viz_types = {
|
||||
"mixed_timeseries": "Mixed Timeseries Chart",
|
||||
}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -30,6 +30,10 @@ class PieChartPlugin(BaseChartPlugin):
|
||||
"""Plugin for pie chart type."""
|
||||
|
||||
chart_type = "pie"
|
||||
display_name = "Pie / Donut Chart"
|
||||
native_viz_types = {
|
||||
"pie": "Pie Chart",
|
||||
}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -30,6 +30,10 @@ class PivotTableChartPlugin(BaseChartPlugin):
|
||||
"""Plugin for pivot_table chart type."""
|
||||
|
||||
chart_type = "pivot_table"
|
||||
display_name = "Pivot Table"
|
||||
native_viz_types = {
|
||||
"pivot_table_v2": "Pivot Table",
|
||||
}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -30,6 +30,11 @@ class TableChartPlugin(BaseChartPlugin):
|
||||
"""Plugin for table chart type."""
|
||||
|
||||
chart_type = "table"
|
||||
display_name = "Table"
|
||||
native_viz_types = {
|
||||
"table": "Table",
|
||||
"ag-grid-table": "Interactive Table",
|
||||
}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -30,6 +30,13 @@ class XYChartPlugin(BaseChartPlugin):
|
||||
"""Plugin for xy chart type (line, bar, area, scatter)."""
|
||||
|
||||
chart_type = "xy"
|
||||
display_name = "Line / Bar / Area / Scatter Chart"
|
||||
native_viz_types = {
|
||||
"echarts_timeseries_line": "Line Chart",
|
||||
"echarts_timeseries_bar": "Bar Chart",
|
||||
"echarts_area": "Area Chart",
|
||||
"echarts_timeseries_scatter": "Scatter Plot",
|
||||
}
|
||||
|
||||
def pre_validate(
|
||||
self,
|
||||
|
||||
@@ -72,6 +72,25 @@ def is_registered(chart_type: str) -> bool:
|
||||
return chart_type in _REGISTRY
|
||||
|
||||
|
||||
def display_name_for_viz_type(viz_type: str) -> str | None:
|
||||
"""Return the user-facing display name for a Superset-internal viz_type.
|
||||
|
||||
Searches every registered plugin's ``native_viz_types`` mapping.
|
||||
Returns None if no plugin recognises the viz_type.
|
||||
|
||||
Example::
|
||||
|
||||
display_name_for_viz_type("echarts_timeseries_line") # "Line Chart"
|
||||
display_name_for_viz_type("pivot_table_v2") # "Pivot Table"
|
||||
display_name_for_viz_type("unknown_type") # None
|
||||
"""
|
||||
for plugin in _REGISTRY.values():
|
||||
name = plugin.native_viz_types.get(viz_type)
|
||||
if name is not None:
|
||||
return name
|
||||
return None
|
||||
|
||||
|
||||
def get_registry() -> "_RegistryProxy":
|
||||
"""Return a proxy object for registry access (convenience wrapper)."""
|
||||
return _RegistryProxy()
|
||||
@@ -88,3 +107,6 @@ class _RegistryProxy:
|
||||
|
||||
def is_registered(self, chart_type: str) -> bool:
|
||||
return chart_type in _REGISTRY
|
||||
|
||||
def display_name_for_viz_type(self, viz_type: str) -> str | None:
|
||||
return display_name_for_viz_type(viz_type)
|
||||
|
||||
@@ -101,7 +101,14 @@ class ChartInfo(BaseModel):
|
||||
|
||||
id: int | None = Field(None, description="Chart ID")
|
||||
slice_name: str | None = Field(None, description="Chart name")
|
||||
viz_type: str | None = Field(None, description="Visualization type")
|
||||
viz_type: str | None = Field(None, description="Visualization type (internal ID)")
|
||||
chart_type_display_name: str | None = Field(
|
||||
None,
|
||||
description=(
|
||||
"User-friendly chart type name (e.g. 'Line Chart', 'Pivot Table'). "
|
||||
"Use this field when referring to chart types — never expose viz_type."
|
||||
),
|
||||
)
|
||||
datasource_name: str | None = Field(None, description="Datasource name")
|
||||
datasource_type: str | None = Field(None, description="Datasource type")
|
||||
url: str | None = Field(None, description="Chart explore page URL")
|
||||
@@ -488,11 +495,20 @@ def serialize_chart_object(chart: ChartLike | None) -> ChartInfo | None:
|
||||
# Extract structured filter information
|
||||
filters_info = extract_filters_from_form_data(chart_form_data)
|
||||
|
||||
_viz_type = getattr(chart, "viz_type", None)
|
||||
try:
|
||||
from superset.mcp_service.chart.registry import display_name_for_viz_type
|
||||
|
||||
_display_name = display_name_for_viz_type(_viz_type) if _viz_type else None
|
||||
except Exception:
|
||||
_display_name = None
|
||||
|
||||
return sanitize_chart_info_for_llm_context(
|
||||
ChartInfo(
|
||||
id=chart_id,
|
||||
slice_name=getattr(chart, "slice_name", None),
|
||||
viz_type=getattr(chart, "viz_type", None),
|
||||
viz_type=_viz_type,
|
||||
chart_type_display_name=_display_name,
|
||||
datasource_name=getattr(chart, "datasource_name", None),
|
||||
datasource_type=getattr(chart, "datasource_type", None),
|
||||
url=chart_url,
|
||||
|
||||
Reference in New Issue
Block a user