fix: 用量行 pace 列真 0 窗口不再缺席,diff=0 三角位画等号

Claude 5h 空闲时接口回 utilization 0、resets_at null,算不出 time_pct,
渲染器整列跳过 pace 导致该行进度条比别行长。数据层对 pct=0 且无重置时刻的
窗口记 time_pct=0;基类 _usage_row 只要有百分比就画 pace(缺 time_pct 按 0)。
diff=0 时三角位由留空改为画等宽等号「=」,预留逻辑从宽版下沉到基类,小屏同样齐平。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 15:33:21 +08:00
parent f96ae29590
commit d35f233ef3
4 changed files with 17 additions and 14 deletions

File diff suppressed because one or more lines are too long

View File

@@ -334,7 +334,7 @@ GPT_WINDOWS = (
def usage_from_raw(now, raw, windows, title): def usage_from_raw(now, raw, windows, title):
"""原始快照 → 渲染结构Claude / ChatGPT 通用)。 """原始快照 → 渲染结构Claude / ChatGPT 通用)。
raw 形如 {five_hour:{utilization, resets_at, window?}, seven_day:{...}, <scoped 键>:{...}|null, updated_at?} raw 形如 {five_hour:{utilization, resets_at, window?}, seven_day:{...}, <scoped 键>:{...}|null, updated_at?}
utilization 为已用百分比resets_at 为 epoch 秒或 ISOwindow 为该窗口真实长度秒(缺省用 windows 表的常量);缺哪个窗口哪个显示 "--" utilization 为已用百分比resets_at 为 epoch 秒或 ISOwindow 为该窗口真实长度秒(缺省用 windows 表的常量);缺哪个窗口哪个显示 "--"(宽版按 0 画utilization 为 0 且 resets_at 为 null 的空闲窗口记 time_pct=0保证 pace 列不缺席
time_pct时间已流逝%)与 pace 按传入的 now **现算**——所以推送端只需推原始快照,服务端渲染时 pace 仍随时钟准确推进。 time_pct时间已流逝%)与 pace 按传入的 now **现算**——所以推送端只需推原始快照,服务端渲染时 pace 仍随时钟准确推进。
结构契约renderer 依赖):{title, warn, ok, pace_tol, updated?, bars:[{k, label, pct(0~100 或 None), time_pct?, reset?, scoped}]} 结构契约renderer 依赖):{title, warn, ok, pace_tol, updated?, bars:[{k, label, pct(0~100 或 None), time_pct?, reset?, scoped}]}
pct ≥ warn 时该条进度条与百分比转红(宽版另按 ok/warn 分 绿/黑/红 三档,百分比随条色); pct ≥ warn 时该条进度条与百分比转红(宽版另按 ok/warn 分 绿/黑/红 三档,百分比随条色);
@@ -349,6 +349,8 @@ def usage_from_raw(now, raw, windows, title):
bar = {"k": k, "label": label, "pct": pct, "scoped": scoped} bar = {"k": k, "label": label, "pct": pct, "scoped": scoped}
win = int(seg.get("window") or win) win = int(seg.get("window") or win)
tp = _window_time_pct(seg.get("resets_at"), win, now) tp = _window_time_pct(seg.get("resets_at"), win, now)
if pct is not None and tp is None and pct == 0:
tp = 0 # 窗口空闲utilization 0 且 resets_at null5h 窗口重置后常见):窗口尚未开始,已流逝 0%、pace 持平
if pct is not None and tp is not None: if pct is not None and tp is not None:
bar["time_pct"] = tp bar["time_pct"] = tp
rs = _fmt_reset(seg.get("resets_at"), win) rs = _fmt_reset(seg.get("resets_at"), win)

View File

@@ -162,16 +162,21 @@ class DashboardRenderer:
def _pace(self, xr, cy, diff): def _pace(self, xr, cy, diff):
"""时间维度对比pace = 用量% 时间%>0 超前↑红;<0 节余↓黑;=0 持平。 """时间维度对比pace = 用量% 时间%>0 超前↑红;<0 节余↓黑;=0 持平。
数值(FPACE默认 F13)两位补零、右端对齐 xr小三角(6)紧贴其左;均竖直居中 cy。返回整体宽度供左侧定位。""" 数值(FPACE默认 F13)两位补零、右端对齐 xr小三角(6)紧贴其左;均竖直居中 cy。返回整体宽度供左侧定位。
diff=0持平/无数据)三角位画一个与三角等宽的等号「=」2026-09-14 用户要求,原为留空,后曾用「-」——pace 列每行等宽,各行进度条右端齐平。"""
up = diff > 0 up = diff > 0
color = self._pace_color(diff) color = self._pace_color(diff)
txt = f"{abs(int(diff)):02d}" txt = f"{abs(int(diff)):02d}"
tw = self._tw(txt, self.FPACE) tw = self._tw(txt, self.FPACE)
self._mid(xr, cy, txt, self.FPACE, fill=color, bold=self.k, align="r") self._mid(xr, cy, txt, self.FPACE, fill=color, bold=self.k, align="r")
if diff == 0:
return tw
TRI_GAP, TRI = 4 * self.k, 6 * self.k TRI_GAP, TRI = 4 * self.k, 6 * self.k
self.tri(xr - tw - TRI_GAP - TRI / 2, cy, TRI, up=up, fill=color) cx = xr - tw - TRI_GAP - TRI / 2
if diff != 0:
self.tri(cx, cy, TRI, up=up, fill=color)
else:
k = self.k # 等号「=」:两道横杠,各宽 6k、厚 k中间隔 2k整体以 cy 为中心
for top in (cy - 2 * k, cy + k):
self.d.rectangle([cx - TRI / 2, top, cx + TRI / 2 - 1, top + k - 1], fill=color)
return tw + TRI_GAP + TRI return tw + TRI_GAP + TRI
def _usage_row(self, x0, x1, y, bar, warn, label_w=None): def _usage_row(self, x0, x1, y, bar, warn, label_w=None):
@@ -195,8 +200,9 @@ class DashboardRenderer:
self._mid(x0, cy, bar["k"], self.F13, bold=lb) self._mid(x0, cy, bar["k"], self.F13, bold=lb)
# 右侧从右往左pace(最右) → 百分比 → 进度条 # 右侧从右往左pace(最右) → 百分比 → 进度条
pct_r = x1 pct_r = x1
if ok and "time_pct" in bar: if ok:
pace_w = self._pace(x1, cy, pct - int(bar["time_pct"])) # 有百分比就必画 pace 列time_pct 缺失(窗口无重置时刻)按 0 差值画 "00",不能整列省掉——否则该行进度条会变长、右端错位
pace_w = self._pace(x1, cy, pct - int(bar["time_pct"]) if "time_pct" in bar else 0)
pct_r = x1 - pace_w - G2 pct_r = x1 - pace_w - G2
pct_txt = f"{pct:02d}%" if ok else "--" pct_txt = f"{pct:02d}%" if ok else "--"
self._mid(pct_r, cy, pct_txt, self.F16, fill=color, bold=k, align="r", track=PCT_TRACK) # 百分比 F16 self._mid(pct_r, cy, pct_txt, self.F16, fill=color, bold=k, align="r", track=PCT_TRACK) # 百分比 F16

View File

@@ -75,11 +75,6 @@ class E1002Renderer(DashboardRenderer):
bar = dict(bar, pct=0, time_pct=0, _null=True) bar = dict(bar, pct=0, time_pct=0, _null=True)
return super()._usage_row(x0, x1, y, bar, warn, label_w=label_w) return super()._usage_row(x0, x1, y, bar, warn, label_w=label_w)
def _pace(self, xr, cy, diff):
"""宽版diff=0持平/无数据)不画三角,但**仍预留三角位**6 + 间隙 4使每行 pace 列等宽、进度条右端齐平。"""
w = super()._pace(xr, cy, diff)
return w if diff != 0 else w + 10 * self.k
def _usage_colors(self, ok, pct, warn, bar): def _usage_colors(self, ok, pct, warn, bar):
"""进度条填充、边框、百分比数字三者同色pct ≤ ok 绿「健康」其间黑「正常」pct ≥ warn 红「危险」无数据_null黑。""" """进度条填充、边框、百分比数字三者同色pct ≤ ok 绿「健康」其间黑「正常」pct ≥ warn 红「危险」无数据_null黑。"""
if not ok or bar.get("_null"): if not ok or bar.get("_null"):