Skip to content

v3.9.0: Diagram Style Editor(顏色/字型/軸/標籤互動式編輯) - #5

Draft
FormosaRes wants to merge 4 commits into
mainfrom
claude/pyadr-diagram-styling-kcv69t
Draft

v3.9.0: Diagram Style Editor(顏色/字型/軸/標籤互動式編輯)#5
FormosaRes wants to merge 4 commits into
mainfrom
claude/pyadr-diagram-styling-kcv69t

Conversation

@FormosaRes

Copy link
Copy Markdown
Owner

目的

讓使用者針對 AgeCalc diagram(DFN/DFI/DFW/DFA/DFC/DFD/DFR)的顏色、字型、線寬、軸刻度、legend、以及每張圖的 title/x/y 標籤做互動式編輯,不必改 code。整合進現有 DiagramPlot 的 refresh 迴路,不是獨立子程式。

做法

Step 1 — 中央 style dict(Utilities.py

  • _get_style() 從 pyADR/classic 兩檔改為「base 預設 ← preset ← 使用者 overrides」三層合併。
  • 新增 publication(IsoplotR 風 muted 色 + tick 朝內 + 四邊框 + minor ticks)與 presentation(同配色、字級/線寬放大)preset。
  • 散落在各 plot function 的 matplotlib hardcode(legend loc/fontsize/framealpha、label/tick/annot 字級、迴歸/連接/WMA/邊框線寬、tick 方向、grid、大氣 marker 色、軸標籤文字)一律改讀 dict。
  • GROUP_COLORS 集中到 Utilities 單一真相 + 去重(原本 NTNU 與 Utilities 各一份),新增色盲安全的 GROUP_COLORS_CVD
  • 新 API:set_style_overrides / get_style_overrides / available_styles,helper _txt / _fs / _legend_kw / _resolve_group_colors / _apply_frame

Step 2 — UI/DiagramStyleEditor.py(新檔)

  • 左側分頁(顏色 / 字型 / 線條&Marker / Legend / 軸 / 文字標籤)+ 頂部 preset 下拉(改任一參數自動切 custom)+ 右側大圖置中預覽(讀 .work/<target>.png,auto-scale,圖為主體)+ Reset/Cancel/Apply/OK。non-modal 單例。

掛鉤

  • NTNU_DataReduction DiagramPlots_SH sidebar 與 AutoPipeline AgeCalcPage Plot Controls 各加一顆 ⚙,開同一 dialog、寫同一份 overrides,Apply → 既有 SH_apply_axes / _refresh_diagrams 重畫。兩 app Style 下拉同步加 Publication / Presentation。

向後相容 / 影響

  • pyADR / classic 兩 preset 的合併結果與舊 dict 逐鍵一致;字級類 override 為 None 時以 _fs() 完全略過該 kwarg,matplotlib 預設不變 → 未開 editor、preset 維持 pyADR 時輸出與 v3.8.93 相同。
  • DFR 微調:改用共用 _apply_frame(),pyADR 下 axes facecolor 由預設白改 transparent(與 DFW/DFA/DFC 一致),classic 下多 minor ticks。純外觀一致化,中心值/誤差不變。

驗證

  • 四檔 ast.parse 通過。
  • style 系統單元測試:向後相容(pyADR/classic 逐鍵)、overrides merge/clear、per-target text override、group color resolution 全數通過。
  • DiagramStyleEditor 以 QT_QPA_PLATFORM=offscreen 實際開啟並截圖:分頁 / preset 切換 / target 預覽 / _collect_overrides_get_style 合併(group[0]=#2a78d6、tick_dir=in、ticks_top_right=True)全正常。
  • ⚠️ 待辦(發 Release 前):NO.65 muscovite 端對端數值比對(確認 pyADR preset 下輸出 bit-identical),留待有樣品資料的環境跑。此 PR 先開 draft。

檔案

  • Utilities.py(style 系統 + 各 plot function 套用)
  • UI/DiagramStyleEditor.py(新)
  • NTNU_DataReduction.pyAutoPipeline.py(Style 下拉選項 + ⚙ 入口 + handler)
  • .work/.app_info.txt 3.8.93 → 3.9.0、CHANGELOG.mdREADME.md

🤖 Generated with Claude Code

https://claude.ai/code/session_013DhiyS8YrAJ2MeSGoo5Pyt


Generated by Claude Code

claude and others added 4 commits July 2, 2026 01:30
新功能:讓使用者針對 AgeCalc diagram(DFN/DFI/DFW/DFA/DFC/DFD/DFR)的
顏色、字型、線寬、軸刻度、legend、各圖 title/x/y 標籤做互動式編輯,
整合進現有 DiagramPlot refresh 迴路,非獨立子程式。

- Step 1 中央 style dict:_get_style() 改「base ← preset ← overrides」三層合併;
  新增 publication / presentation preset;散落的 matplotlib hardcode
  (legend/字級/線寬/tick/grid/atm marker/軸標籤)一律改讀 dict。
  pyADR/classic 合併結果與舊 dict 逐鍵一致,字級 override 為 None 時
  以 _fs() 略過 kwarg,既有輸出不變。
- GROUP_COLORS 集中到 Utilities 單一真相 + 去重,新增色盲安全的
  GROUP_COLORS_CVD;resolution: editor > caller > preset。
- Step 2 UI/DiagramStyleEditor.py:左分頁控件 + 右側大圖置中預覽 + preset
  下拉(改參數自動切 custom) + Reset/Apply/OK,non-modal 單例。
- 雙入口共用:NTNU DiagramPlots_SH sidebar 與 AutoPipeline AgeCalcPage
  各加 ⚙,寫同一份 set_style_overrides,Apply 走既有 SH_apply_axes /
  _refresh_diagrams 重畫;兩 app Style 下拉加 Publication/Presentation。

驗證:四檔 ast.parse 通過;style 系統單元測試(向後相容 + overrides
merge/clear + text override + group resolution)通過;dialog offscreen
截圖確認分頁/preset/target 預覽/overrides 合併正常。NO.65 端對端數值
比對待有樣品資料環境再跑,再發 Release tag。

DFR 微調:改用共用 _apply_frame(),pyADR 下 axes facecolor 由白改
transparent(與其他 spectra 一致),中心值/誤差不變。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013DhiyS8YrAJ2MeSGoo5Pyt
按 ⚙ 開 DiagramStyleEditor 時若發生例外(Qt slot 未捕捉例外會 abort 整個
app),改為顯示錯誤對話框而非直接關閉。最常見原因:執行資料夾的
Utilities.py 未同步到新版(缺 set_style_overrides)。

- NTNU_DataReduction._open_style_editor / AutoPipeline._open_style_editor:
  整段包 try/except,失敗顯示 traceback。
- 新增 hasattr(Utilities, 'set_style_overrides') 前置檢查,舊版直接跳
  「請同步 Utilities.py」提示。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013DhiyS8YrAJ2MeSGoo5Pyt
_bg_check_update / checkVersion 原本用 current == latest,只比相等不比
大小,抓 main 的 .app_info.txt 一不相同就報「有更新」。本地版本領先
GitHub main(開發機/pre-Release)或 raw.githubusercontent CDN 快取造成
短暫不一致時就會誤報要求更新到舊版(回報:Update Available v3.8.93 /
You're on v3.9.0)。

新增 App._ver_newer(remote, local) 做數字序 tuple 比較(去 v 前綴、
補零對齊、3.10.0 > 3.9.0 不被字串序騙),兩處改成只有遠端嚴格較新
才提示。不動科學輸出。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
App 是純控制器類別(非 QWidget),_open_style_editor 卻用
DiagramStyleEditor(self, ...) 把 App 當 parent 傳給 QDialog.__init__
→ TypeError: QDialog argument 1 has unexpected type 'App'。守衛裡的
QMessageBox.critical(self, ...) 又把 App 當 parent 再拋一次 TypeError
→ 未捕捉 → PyQt5 abort 整個進程。所以「一按就關、連錯誤框都沒有」。

修法:dialog 與 warning/critical 三處 parent self → self.widget
(App 的頂層 QStackedWidget,是 QWidget)。AutoPipeline 端在
AgeCalcPage(QWidget) 內 self 本身是 widget,不受影響。純 UI 修正,
不動科學輸出。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants