Phase 1 UX + JS transforms: tabs, windowing, percent/grouping, smoothing, stacked series, metadata pass-through, top_n
- Replace tabs with Recent/Trends/Distribution/Tables/Analysis and add sticky controls (interval, domain, window [default 7d], percent, group small, exclude '-' -> Uncached, smoothing toggle). - Client-side transforms: time-window slicing, percent mode, group others (3%), per-report exclusions; stackedBar multi-series; moving average for error_rate. - Generator: pass through optional UX metadata (windows_supported, window_default, group_others_threshold, exclude_values, top_n, stacked, palette) and enforce top_n LIMIT for table reports. - Reports: add status_classes_timeseries and cache_status_timeseries; apply top_n=50 to heavy tables. - Chart manager: add helpers (sliceWindow, excludeValues, toPercent, groupOthers, movingAverage). - URL state + localStorage for context; per-tab filtering for Trends/Distribution/Tables.
This commit is contained in:
parent
9c26ae3e90
commit
fab91d2e04
4 changed files with 442 additions and 59 deletions
|
@ -178,6 +178,16 @@ def _generate_interval(interval: str, domain: Optional[str] = None) -> None:
|
|||
name = definition["name"]
|
||||
query = definition["query"].replace("{bucket}", bucket)
|
||||
query = query.replace("FROM logs", "FROM logs_view")
|
||||
# Apply top_n limit for tables (performance-friendly), if configured
|
||||
top_n = definition.get("top_n")
|
||||
chart_type = definition.get("chart", "line")
|
||||
if top_n and chart_type == "table":
|
||||
try:
|
||||
n = int(top_n)
|
||||
if "LIMIT" not in query.upper():
|
||||
query = f"{query}\nLIMIT {n}"
|
||||
except Exception:
|
||||
pass
|
||||
cur.execute(query)
|
||||
rows = cur.fetchall()
|
||||
headers = [c[0] for c in cur.description]
|
||||
|
@ -203,6 +213,18 @@ def _generate_interval(interval: str, domain: Optional[str] = None) -> None:
|
|||
entry["color"] = definition["color"]
|
||||
if "colors" in definition:
|
||||
entry["colors"] = definition["colors"]
|
||||
# Optional UX metadata passthrough for frontend-only transforms
|
||||
for key in (
|
||||
"windows_supported",
|
||||
"window_default",
|
||||
"group_others_threshold",
|
||||
"exclude_values",
|
||||
"top_n",
|
||||
"stacked",
|
||||
"palette",
|
||||
):
|
||||
if key in definition:
|
||||
entry[key] = definition[key]
|
||||
_render_snippet(entry, out_dir)
|
||||
report_list.append(entry)
|
||||
|
||||
|
@ -266,6 +288,16 @@ def _generate_global() -> None:
|
|||
|
||||
name = definition["name"]
|
||||
query = definition["query"]
|
||||
# Apply top_n limit for tables (performance-friendly), if configured
|
||||
top_n = definition.get("top_n")
|
||||
chart_type = definition.get("chart", "line")
|
||||
if top_n and chart_type == "table":
|
||||
try:
|
||||
n = int(top_n)
|
||||
if "LIMIT" not in query.upper():
|
||||
query = f"{query}\nLIMIT {n}"
|
||||
except Exception:
|
||||
pass
|
||||
cur.execute(query)
|
||||
rows = cur.fetchall()
|
||||
headers = [c[0] for c in cur.description]
|
||||
|
@ -291,6 +323,18 @@ def _generate_global() -> None:
|
|||
entry["color"] = definition["color"]
|
||||
if "colors" in definition:
|
||||
entry["colors"] = definition["colors"]
|
||||
# Optional UX metadata passthrough for frontend-only transforms
|
||||
for key in (
|
||||
"windows_supported",
|
||||
"window_default",
|
||||
"group_others_threshold",
|
||||
"exclude_values",
|
||||
"top_n",
|
||||
"stacked",
|
||||
"palette",
|
||||
):
|
||||
if key in definition:
|
||||
entry[key] = definition[key]
|
||||
_render_snippet(entry, out_dir)
|
||||
report_list.append(entry)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue