fix: improve chart axis readability in html report

This commit is contained in:
kim
2026-04-02 18:47:44 +08:00
parent 7dd47a51ff
commit c5e570f382
2 changed files with 28 additions and 14 deletions
+25 -14
View File
@@ -157,15 +157,15 @@ def _format_duration(value: float) -> str:
def _render_bar_chart(title: str, items: Iterable[HistogramBin | CategoryCount]) -> str: def _render_bar_chart(title: str, items: Iterable[HistogramBin | CategoryCount]) -> str:
rows = list(items) rows = list(items)
width = 680 width = 520
height = 320 height = 360
margin_left = 110 margin_left = 72
margin_right = 24 margin_right = 20
margin_top = 24 margin_top = 32
margin_bottom = 48 margin_bottom = 88
plot_width = width - margin_left - margin_right plot_width = width - margin_left - margin_right
plot_height = height - margin_top - margin_bottom plot_height = height - margin_top - margin_bottom
bar_gap = 12 bar_gap = 10
bar_width = plot_width / max(len(rows), 1) - bar_gap bar_width = plot_width / max(len(rows), 1) - bar_gap
max_count = max((item.count for item in rows), default=1) max_count = max((item.count for item in rows), default=1)
pieces = [ pieces = [
@@ -179,12 +179,14 @@ def _render_bar_chart(title: str, items: Iterable[HistogramBin | CategoryCount])
x = margin_left + index * (bar_width + bar_gap) + bar_gap / 2 x = margin_left + index * (bar_width + bar_gap) + bar_gap / 2
y = margin_top + plot_height - bar_height y = margin_top + plot_height - bar_height
text_x = x + bar_width / 2 text_x = x + bar_width / 2
label_y = margin_top + plot_height + 32
pieces.append( pieces.append(
f'<rect x="{x:.2f}" y="{y:.2f}" width="{bar_width:.2f}" height="{bar_height:.2f}" class="bar" />' f'<rect x="{x:.2f}" y="{y:.2f}" width="{bar_width:.2f}" height="{bar_height:.2f}" class="bar" />'
) )
pieces.append(f'<text x="{text_x:.2f}" y="{y - 8:.2f}" class="count">{item.count}</text>') pieces.append(f'<text x="{text_x:.2f}" y="{y - 8:.2f}" class="count">{item.count}</text>')
pieces.append( pieces.append(
f'<text x="{text_x:.2f}" y="{margin_top + plot_height + 20:.2f}" class="label">{escape(item.label)}</text>' f'<text x="{text_x:.2f}" y="{label_y:.2f}" class="label" '
f'transform="rotate(-18 {text_x:.2f} {label_y:.2f})">{escape(item.label)}</text>'
) )
pieces.append("</svg></section>") pieces.append("</svg></section>")
@@ -285,20 +287,21 @@ def _write_html(
.card p {{ margin: 0; font-size: 1.6rem; color: var(--text); }} .card p {{ margin: 0; font-size: 1.6rem; color: var(--text); }}
.charts {{ .charts {{
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(520px, 1fr));
gap: 18px; gap: 18px;
}} }}
svg {{ width: 100%; height: auto; overflow: visible; }} svg {{ display: block; width: 100%; height: auto; overflow: visible; }}
.bar {{ fill: var(--accent); opacity: 0.9; }} .bar {{ fill: var(--accent); opacity: 0.9; }}
.axis {{ stroke: var(--line); stroke-width: 1.5; }} .axis {{ stroke: var(--line); stroke-width: 2; }}
.label {{ .label {{
fill: var(--muted); fill: var(--muted);
font-size: 10px; font-size: 16px;
text-anchor: middle; text-anchor: end;
font-weight: 600;
}} }}
.count {{ .count {{
fill: var(--text); fill: var(--text);
font-size: 11px; font-size: 18px;
text-anchor: middle; text-anchor: middle;
font-weight: 700; font-weight: 700;
}} }}
@@ -328,6 +331,14 @@ def _write_html(
color: var(--muted); color: var(--muted);
overflow-wrap: anywhere; overflow-wrap: anywhere;
}} }}
@media (max-width: 1120px) {{
.charts {{ grid-template-columns: 1fr; }}
}}
@media (max-width: 640px) {{
main {{ padding: 28px 16px 48px; }}
h1 {{ font-size: 1.9rem; }}
.card, .chart, .meta {{ padding: 16px; }}
}}
</style> </style>
</head> </head>
<body> <body>
+3
View File
@@ -67,3 +67,6 @@ def test_write_report_bundle_creates_json_csv_and_html(tmp_path: Path) -> None:
assert "错误清单" in html_text assert "错误清单" in html_text
assert "moov atom not found" in html_text assert "moov atom not found" in html_text
assert "<svg" in html_text assert "<svg" in html_text
assert "grid-template-columns: repeat(auto-fit, minmax(520px, 1fr));" in html_text
assert "font-size: 16px;" in html_text
assert "font-size: 18px;" in html_text