feat(custom-tooltip): custom tooltip on deck.gl charts (#34276)

This commit is contained in:
Richard Fogaca Nienkotter
2025-09-16 11:11:19 -03:00
committed by GitHub
parent bc6859a99d
commit a66737cb05
62 changed files with 4599 additions and 421 deletions

View File

@@ -27,6 +27,7 @@ from superset.common.query_object_factory import QueryObjectFactory
from superset.daos.chart import ChartDAO
from superset.daos.datasource import DatasourceDAO
from superset.models.slice import Slice
from superset.superset_typing import Column
from superset.utils.core import DatasourceDict, DatasourceType, is_adhoc_column
if TYPE_CHECKING:
@@ -120,8 +121,82 @@ class QueryContextFactory: # pylint: disable=too-few-public-methods
) -> QueryObject:
self._apply_granularity(query_object, form_data, datasource)
self._apply_filters(query_object)
self._add_tooltip_columns(query_object, form_data)
return query_object
def _add_tooltip_columns(
self,
query_object: QueryObject,
form_data: dict[str, Any] | None,
) -> None:
"""Add tooltip columns to the query object."""
if not form_data:
return
tooltip_columns = self._extract_tooltip_columns(form_data)
if not tooltip_columns:
return
existing_columns = self._get_existing_column_names(query_object.columns)
self._append_missing_tooltip_columns(
query_object, tooltip_columns, existing_columns
)
def _get_existing_column_names(self, columns: list[Column]) -> set[str]:
"""Extract column names from existing columns."""
column_names: set[str] = set()
for col in columns:
if isinstance(col, dict):
column_name = col.get("column_name")
if column_name and isinstance(column_name, str):
column_names.add(column_name)
elif isinstance(col, str):
column_names.add(col)
return column_names
def _append_missing_tooltip_columns(
self,
query_object: QueryObject,
tooltip_columns: list[str],
existing_columns: set[str],
) -> None:
"""Append missing tooltip columns to query object."""
for col in tooltip_columns:
if col not in existing_columns:
column_def = self._find_column_definition(query_object, col)
query_object.columns.append(column_def or col)
def _find_column_definition(
self, query_object: QueryObject, column_name: str
) -> Any | None:
"""Find column definition from datasource."""
if not (
query_object.datasource and hasattr(query_object.datasource, "columns")
):
return None
return next(
(
c
for c in query_object.datasource.columns
if c.column_name == column_name
),
None,
)
def _extract_tooltip_columns(self, form_data: dict[str, Any]) -> list[str]:
"""Extract column names from tooltip_contents configuration."""
tooltip_columns = []
if tooltip_contents := form_data.get("tooltip_contents", []):
for item in tooltip_contents:
if isinstance(item, str):
tooltip_columns.append(item)
elif isinstance(item, dict) and item.get("item_type") == "column":
column_name = item.get("column_name")
if column_name:
tooltip_columns.append(column_name)
return tooltip_columns
def _apply_granularity( # noqa: C901
self,
query_object: QueryObject,
@@ -139,6 +214,8 @@ class QueryContextFactory: # pylint: disable=too-few-public-methods
filter_to_remove = None
if is_adhoc_column(x_axis): # type: ignore
x_axis = x_axis.get("sqlExpression")
if isinstance(x_axis, dict) and "sqlExpression" in x_axis:
x_axis = x_axis.get("sqlExpression")
if x_axis and x_axis in temporal_columns:
filter_to_remove = x_axis
x_axis_column = next(