- 新增 _calculate_lane_conflicts_v2() 分開返回標籤重疊和線穿框分數 - 修改泳道選擇算法,優先選擇無標籤重疊的泳道 - 兩階段搜尋:優先側別無可用泳道則嘗試另一側 - 增強日誌輸出,顯示標籤範圍和詳細衝突分數 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
118 lines
3.4 KiB
Markdown
118 lines
3.4 KiB
Markdown
# 時間軸標籤避碰改進(v2.0)
|
||
|
||
## 問題
|
||
原始實現中,標籤只有簡單的上下(或左右)交錯,導致當事件密集時會出現文字框重疊、遮蔽的問題。
|
||
|
||
## 解決方案 v2.0 - 智能 2D 避碰 + 折線連接
|
||
|
||
### 1. **二維智能避碰演算法**
|
||
```python
|
||
def _calculate_label_positions(events, start_date, end_date):
|
||
- 計算每個標籤在時間軸上的 2D 佔用範圍
|
||
- 偵測水平重疊衝突
|
||
- 嘗試水平偏移(左右移動標籤)
|
||
- 如果同層無法容納,自動分配到新層級
|
||
- 支援無限層級擴展
|
||
```
|
||
|
||
**避碰策略**:
|
||
1. 先嘗試在同一層級無偏移放置
|
||
2. 如有衝突,嘗試向左偏移 (1x, 2x, 3x 間距)
|
||
3. 仍有衝突,嘗試向右偏移 (1x, 2x, 3x 間距)
|
||
4. 都無法容納,創建新層級
|
||
|
||
### 2. **折線連接(Polyline)**
|
||
- **舊版本**:直線連接(事件點 → 標籤)
|
||
- **新版本**:Z 形折線連接
|
||
- 水平時間軸:垂直線 → 水平線 → 垂直線
|
||
- 垂直時間軸:水平線 → 垂直線 → 水平線
|
||
- 使用 Plotly `path` 繪製平滑折線
|
||
|
||
**折線路徑(水平時間軸)**:
|
||
```
|
||
事件點 (event_x, 0)
|
||
↓ 垂直線
|
||
中間點 (event_x, mid_y)
|
||
→ 水平線
|
||
轉折點 (label_x, mid_y)
|
||
↓ 垂直線
|
||
標籤位置 (label_x, label_y)
|
||
```
|
||
|
||
### 3. **動態標籤位置**
|
||
- **垂直位置**:根據層級自動計算(上下交錯)
|
||
- **水平位置**:根據避碰演算法動態偏移
|
||
- **連接線**:自動調整路徑適應偏移
|
||
|
||
### 4. **關鍵參數**
|
||
- `label_width_ratio = 0.08`: 標籤寬度約為時間軸的 8%(增加)
|
||
- `min_horizontal_gap = 0.015`: 最小水平間距為時間軸的 1.5%
|
||
- `layer_spacing = 0.6`: 層級間距(增加)
|
||
- 動態 Y/X 軸範圍調整
|
||
|
||
### 5. **效果**
|
||
- ✅ 2D 智能避碰(垂直 + 水平)
|
||
- ✅ 標籤可以左右偏移避免重疊
|
||
- ✅ 使用折線優雅連接標籤與事件點
|
||
- ✅ 根據事件密度自動調整層級數
|
||
- ✅ 視覺更清晰、更專業
|
||
|
||
## 視覺改進對比
|
||
|
||
### 舊版本
|
||
- ❌ 只有垂直避碰(上下層級)
|
||
- ❌ 標籤 x 位置固定,無法偏移
|
||
- ❌ 直線連接,密集時會交叉
|
||
- ❌ 容易出現重疊
|
||
|
||
### 新版本 v2.0
|
||
- ✅ 2D 避碰(垂直層級 + 水平偏移)
|
||
- ✅ 標籤可動態左右移動
|
||
- ✅ Z 形折線連接,路徑清晰
|
||
- ✅ 智能避免重疊
|
||
|
||
## 調整建議
|
||
如果標籤仍有重疊,可調整以下參數(在 `backend/renderer_timeline.py`):
|
||
|
||
```python
|
||
# 第 80 行:增加標籤寬度估計(更保守)
|
||
label_width_ratio = 0.10 # 從 0.08 增加到 0.10
|
||
|
||
# 第 84 行:增加最小水平間距
|
||
min_horizontal_gap = total_seconds * 0.02 # 從 0.015 增加到 0.02
|
||
|
||
# 第 226/420 行:增加層級間距
|
||
layer_spacing = 0.8 # 從 0.6 增加到 0.8
|
||
```
|
||
|
||
## 測試方法
|
||
```batch
|
||
start_dev.bat
|
||
```
|
||
然後訪問 http://localhost:12010 並測試三個示範檔案。
|
||
|
||
## 技術細節
|
||
|
||
### 折線路徑格式
|
||
使用 SVG Path 語法:
|
||
- `M x,y`:移動到起點
|
||
- `L x,y`:直線到指定點
|
||
|
||
範例:
|
||
```
|
||
M 2024-01-15,0 L 2024-01-15,0.3 L 2024-01-16,0.3 L 2024-01-16,0.6
|
||
```
|
||
|
||
### 避碰演算法複雜度
|
||
- 時間複雜度:O(n × m × k)
|
||
- n = 事件數
|
||
- m = 平均層級數
|
||
- k = 偏移嘗試次數(最多7次)
|
||
- 空間複雜度:O(n × m)
|
||
|
||
### 改進方向
|
||
未來可考慮:
|
||
1. 使用力導向演算法優化標籤位置
|
||
2. 支援標籤尺寸動態計算(根據文字長度)
|
||
3. 添加標籤碰撞預覽功能
|