from __future__ import annotations from collections import defaultdict from typing import Any from src.domain.entities.chart_instance import ChartInstance from src.domain.entities.field_binding import FieldBinding def _get_binding(bindings: list[FieldBinding], axis: str) -> FieldBinding | None: for b in bindings: if b.axis == axis: return b return None def build_map_option(chart: ChartInstance, data: list[dict]) -> dict[str, Any]: """Geo map chart builder.""" region_bind = _get_binding(chart.bindings, "region") val_bind = _get_binding(chart.bindings, "value") if not region_bind or not val_bind: return {"series": []} groups: dict[str, list[float]] = defaultdict(list) ordered: list[str] = [] for row in data: region = str(row.get(region_bind.column_name, "")) val = row.get(val_bind.column_name, 0) if region not in ordered: ordered.append(region) if isinstance(val, (int, float)): groups[region].append(val) map_data = [ {"name": r, "value": sum(groups[r]) if groups[r] else 0} for r in ordered ] all_values = [d["value"] for d in map_data] min_val = min(all_values) if all_values else 0 max_val = max(all_values) if all_values else 1 return { "tooltip": {"trigger": "item"}, "visualMap": { "min": min_val, "max": max_val, "left": "left", "top": "bottom", "text": ["High", "Low"], "calculable": True, }, "series": [ { "type": "map", "map": "china", "roam": True, "data": map_data, "emphasis": {"label": {"show": True}}, } ], }