資料格式如下:
[
{
"event": {
"id": "2013",
"startTime": "00:57:00",
"endTime": "07:56:00",
"title": "list 1",
"backgroundColor": "#f6c79f",
"textColor": "#8c725b",
"order": 2014
}
},
{
"event": {
"id": "2016",
"startTime": "00:51:59",
"endTime": "06:57:00",
"title": "list 2",
"backgroundColor": "#a7bff7",
"textColor": "#5f6d8c",
"order": 2017
}
},
{
"event": {
"id": "2019",
"startTime": "00:11:00",
"endTime": "11:35:00",
"title": "list 3",
"backgroundColor": "#beea91",
"textColor": "#728c57",
"order": 2020
}
},
{
"event": {
"id": "2022",
"startTime": "09:01:00",
"endTime": "13:18:00",
"title": "list 4",
"backgroundColor": "#d1b1ff",
"textColor": "#73618c",
"order": 2023
}
}
]
需求描述:
在1天的座標地圖上(00:00 - 24:00),繪製每個數據,
可能得示意圖如下:
1.根據資料的startTime
和endTime
可以求資料在Y 軸上的座標(表現為top以及height值,已實作)
2.由於每個時間段都可能相交(一個事件的時間段(startTime - endTime)的一部分在另一個一個事件的時間段中,叫做相交),則在X 軸上相交的事件平分X軸的寬度
(表現為left和width值)
2.1.如果一個事件沒有與任何事件相交,則這個事件的寬度是100%
2.2 如果相交平分的話,必須order
越大,位置越靠前
2.3 一個事件可能和另一個事件相交,也可能和另外幾個事件相交
我的問題是如何實現X軸平分寬度且定位left的演算法?也就是每個元素的left和width值得演算法
補充內容:A與B相交,B與C相交,A與C不相交,則ABC也是平分
大致寫了一下,基本思路是
先將全部task依order從大到小排序(此部分省略)
按start end產生task對象, 使用figure對象的add_one,依序加入figure。
插入一個對象時,判斷已有對像中與其相重疊的對象,使其left為最大的重疊對象的left+1,同時更新最大width
最後使用is_overlap方法檢測tasks中的沒有與任何事件相交的事件,並標記出來,這些事件left設為0,width設為100%,除了這些事件以外的事件,寬度設為1/max_width, left設為1/max_width*(left-1) (這部省略)
以下代碼為2和3的步驟
二維分組
先縱向分組(
VGroups
)。凡之間有相交關係的事件分入同一組。各組之間是獨立的(組間不相交)。分組演算法是:將每個事件看做節點,若兩個節點相交,則連一邊。這樣得到一個圖,分組即求此圖的連通分量。可以用深度優先搜尋或廣度優先搜尋等演算法求連通分量。縱向組內再橫向分組(
HGroups
)。凡之間沒有相交關係的事件分入同一組(組內不相交)。這一步的作用是壓縮可以並列顯示的事件數,利用沒有佔用的空間。這樣在縱橫兩個維度分組後,再轉換成圖形就是直截了當了。
測驗
附:Mahematica 代碼
@saigyouyou
有可能是這樣的