{#- Shared helpers: bilingual chrome text + dumb SVG renderers (panel-ui-refresh design D3/D4). Geometry comes from panel.charts; these macros only render. -#} {% macro th(zh, en='') -%} {{ zh }}{% if en %} {{ en }}{% endif %} {%- endmacro %} {% macro lbl(zh, en='') -%} {{ zh }}{% if en %} {{ en }}{% endif %} {%- endmacro %} {#- Column chart: g = charts.bar_geometry(...) -#} {% macro svg_bars(g) -%} {% for b in g.bars %} {{ b.title }} {{ b.label }} {% endfor %} {%- endmacro %} {#- Sparkline: g = charts.sparkline_geometry(...) -#} {% macro svg_sparkline(g) -%} {% if g.points %} {% endif %} {%- endmacro %} {#- Stacked ok/err timeline: g = charts.timeline_geometry(...) -#} {% macro svg_timeline(g) -%} {% for c in g.cols %} {% if c.ok_h %}{{ c.title }}{% endif %} {% if c.err_h %}{{ c.title }}{% endif %} {% endfor %} {%- endmacro %} {#- Progress bar rendered as SVG so fill width is an attribute, not inline CSS -#} {% macro svg_progress(value, maximum, w=120, h=10) -%} {% set fraction = (value / maximum) if maximum else 0 %} {% set fraction = [[fraction, 1] | min, 0] | max %} {% set fw = (w * fraction) | round(1) %} {% if fw > 0 %}{% endif %} {%- endmacro %} {#- Freshness heatmap tiles: g = charts.heatmap_tiles(...); link_prefix makes each tile drill into the filtered detail table, active_key outlines the currently selected bucket -#} {% macro svg_heatmap(g, link_prefix=None, active_key=None) -%} {% for t in g.tiles %} {% if link_prefix %}{% endif %} {{ t.title }} {{ t.count }} {{ t.label }} {{ t.threshold }} {% if link_prefix %}{% endif %} {% endfor %} {%- endmacro %} {% macro legend_freshness() -%}
新鲜 ≤7d fresh 老化 7–30d aging 过期 >30d stale 无观测 never
{%- endmacro %}