codeant-ai-for-open-source[bot] commented on code in PR #44152: URL: https://github.com/apache/superset/pull/44152#discussion_r3985137869
########## superset/mcp_service/chart/treemap_preview.py: ########## @@ -0,0 +1,293 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Bounded slice-and-dice Treemap previews using explicit rectangle geometry.""" + +from __future__ import annotations + +import math +from typing import Any + +from superset.mcp_service.chart.query_result import ( + metric_result_label, + normalize_chart_query_result, +) +from superset.mcp_service.chart.schemas import ChartError, VegaLitePreview + +# Match the built-in frontend categorical schemes. Unknown schemes are not guessed. +_PALETTES = { + "supersetColors": [ + "#1FA8C9", + "#454E7C", + "#5AC189", + "#FF7F44", + "#666666", + "#E04355", + "#FCC700", + "#A868B7", + "#3CCCCB", + "#A38F79", + "#8FD3E4", + "#A1A6BD", + "#ACE1C4", + "#FEC0A1", + "#B2B2B2", + "#EFA1AA", + "#FDE380", + "#D3B3DA", + "#9EE5E5", + "#D1C6BC", + ], + "lyftColors": [ + "#EA0B8C", + "#6C838E", + "#29ABE2", + "#33D9C1", + "#9DACB9", + "#7560AA", + "#2D5584", + "#831C4A", + "#333D47", + "#AC2077", + ], +} +_MAX_ROWS = 1000 + + +def treemap_ascii( + data: list[dict[str, Any]], form_data: dict[str, Any], width: int = 80 +) -> str | ChartError: + """Show the ordered hierarchy and values rather than unrelated bar geometry.""" + checked = normalize_chart_query_result({"queries": [{"data": data}]}, form_data) + if isinstance(checked, ChartError): + return checked + label = metric_result_label(form_data["metric"]) + assert label is not None + lines = [f"Treemap hierarchy | {label}"] + for row in data[:_MAX_ROWS]: + path = " > ".join(str(row[column]) for column in form_data["groupby"]) + lines.append(f"{path} | {row[label]}") + if len(data) > _MAX_ROWS: + lines.append(f"Showing {_MAX_ROWS} of {len(data)} rows") + return "\n".join(line[:width] for line in lines) + + +def treemap_vega_lite( # noqa: C901 + data: list[dict[str, Any]], form_data: dict[str, Any] +) -> VegaLitePreview | ChartError: + """Render nested metric-proportional rectangles; never substitute scatter/bar marks. + + Vega-Lite has no hierarchy transform. A bounded slice-and-dice layout is + computed here and sent as explicit coordinates, without executable hooks. + Native ECharts layout and dashboard interactions remain available in Explore. + """ + checked = normalize_chart_query_result({"queries": [{"data": data}]}, form_data) + if isinstance(checked, ChartError): + return checked + label = metric_result_label(form_data["metric"]) + assert label is not None + if not data: + return ChartError(error="No Treemap data available.", error_type="NoDataError") + scheme = form_data.get("color_scheme") or "supersetColors" + if ( + scheme not in _PALETTES + or form_data.get("currency_format") + or form_data.get("label_position", "insideTopLeft") != "insideTopLeft" + ): + return ChartError( + error=( + "This Treemap color/currency/label format requires the native " + "Explore renderer; use url or table preview." + ), + error_type="UnsupportedTreemapPreview", + ) + if ( + len(data) > _MAX_ROWS + or any(row[label] < 0 for row in data) + or not any(row[label] > 0 for row in data) + ): + return ChartError( + error=( + "Treemap geometry requires at most 1000 nonnegative rows and " + "a positive total; use table or url preview." + ), + error_type="UnsupportedTreemapPreview", + ) + hierarchy = form_data["groupby"] + if len(hierarchy) > 20 or not math.isfinite(sum(float(row[label]) for row in data)): + return ChartError( + error="Treemap preview requires at most 20 levels and a finite total.", + error_type="UnsupportedTreemapPreview", + ) + nodes: list[dict[str, Any]] = [] + + def layout( + rows: list[dict[str, Any]], + depth: int, + path: list[str], + x: float, + y: float, + width: float, + height: float, + ) -> None: + """Recursively partition the parent rectangle in hierarchy order.""" + groups: dict[tuple[str, str], list[dict[str, Any]]] = {} + for row in rows: + value = row[hierarchy[depth]] + groups.setdefault((type(value).__name__, str(value)), []).append(row) Review Comment: ✅ **Customized review instruction saved!** **Instruction:** > Preserve distinct treemap geometry groups for category values that differ by type, even when their formatted display names and colors match the frontend behavior. **Applied to:** - `superset/mcp_service/chart/treemap_preview.py` --- 💡 *To manage or update this instruction, visit: [CodeAnt AI Settings](https://app.codeant.ai/org/settings/learnings)* -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
