背景
使用Graphviz自动将格式化日记按照月份生成图片,出来后效果不错。无论日记、未来规划还是其他事情记录都可以使用该种方式。
模式是:将事情按照格式化写入指定文件比如riji.log 然后执行脚本生成Graphviz,将事件自动生成到时间线上面
主体代码
- 代码
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
msi=int(sys.argv[1])
dsi=int(sys.argv[2])
mei=int(sys.argv[3])
dei=int(sys.argv[4])
file_path=sys.argv[5]
year="23"
mdays=[31,28,31, 30,31,30, 31,31,30, 31,30,31]
def gen_mon(msi,mei,dsi,dei):
print("\nnode [fontsize=20, shape=box, style=filled fillcolor=lightgreen];")
for m in range(msi, mei+1):
if m == msi:
ds=int(dsi)
else:
ds=1
if m==mei:
de=dei
if de > mdays[m-1]:
de = mdays[m-1]
else:
de=mdays[m-1]
print("\n{:>02}.{:>02}".format(year,m))
def gen_day(msi,mei,dsi,dei):
print("\nnode [fontsize=20, shape=box, style=filled fillcolor=lightgray];")
for m in range(msi, mei+1):
if m == msi:
ds=int(dsi)
else:
ds=1
if m==mei:
de=dei
if de > mdays[m-1]:
de = mdays[m-1]
else:
de=mdays[m-1]
print("\n{:>02}.{:>02}->".format(year,m))
for i in range(ds, de+1):
if i!=de:
print("{:>02}{:>02}->".format(m,i))
else:
print("{:>02}{:>02}".format(m,i))
def gen_rank_same(msi,mei,dsi,dei):
print("# rank")
print("\nnode [fontsize=20, shape=box, style=filled fillcolor=cyan];")
for m in range(msi, mei+1):
if m == msi:
ds=int(dsi)
else:
ds=1
if m==mei:
de=dei
if de > mdays[m-1]:
de = mdays[m-1]
else:
de=mdays[m-1]
print("\n#{:>02}.{:>02}".format(year,m))
septimelist=[3,6,9,12]
seasonlist=[3,6,9,12]
for i in range(ds, de+1):
if (m in seasonlist) and (i == 30):
print("{ rank=same; %02d%02d -> season_%02d%02d}" %(m,i, m,i))
elif (m in septimelist) and (i==22):
print("{ rank=same; %02d%02d -> jieqi_zhifen%02d%02d}" %(m,i, m,i))
else:
print("{ rank=same; %02d%02d }" %(m,i))
def gen_head():
print("digraph timeline {")
print('size = "7,8";')
def gen_tail():
print("}")
def _print_riji_event_label(lines):
# 遍历每一行,打印label
print("\n# event label")
for line in lines:
if len(line) < 10:
continue
# 2023-09-12 周一;Graphviz年时间线 def
ldate=line[5:7]+line[8:10]
print("\n## " + ldate)
line=line[10:]
line = line.replace('\n','').replace(";", ";").replace(",",";") #逗号也是一个分隔符
la=line.split(';')
for i in range(0, len(la)):
if len(la[i]) < 2:
continue
if i == 0: #第一个不标数字 是星期
seq=""
weekenddaylist=["周六", "周日"]
la[i]=la[i].replace(" ",'').replace(",", '')
if la[i] in weekenddaylist:
weekendcolor="style=filled fillcolor=lightgreen"
else:
weekendcolor="style=filled fillcolor=coral"
else:
seq="{:>02d}:".format(i)
weekendcolor=""
print("d_env_"+ldate + "_" + str(i) + " [label=\"" + seq + la[i] + "\" " + weekendcolor +"];")
def _print_riji_event_ranksame(lines):
print("\n# ranks=same")
for line in lines:
if len(line) < 10:
continue
ldate=line[5:7]+line[8:10]
line=line[9:]
line = line.replace('\n','').replace(";", ";").replace(",",";") #逗号也是一个分隔符
la=line.split(';')
print("{ rank=same; " + ldate),
for i in range(0, len(la)):
if len(la[i]) < 2:
continue
print("-> d_env_" + ldate + "_" + str(i)),
print("}")
def gen_riji_event():
print("\nnode [fontsize=20, shape=box, style=filled fillcolor=lightblue];")
#读取文件riji.log到list中
#file_path = "riji.log"
with open(file_path, "r") as file:
lines=file.readlines()
#linearray=lines.split('\n')
_print_riji_event_label(lines)
_print_riji_event_ranksame(lines)
def gen_total():
gen_head()
gen_mon(msi, mei, dsi, dei)
gen_day(msi, mei, dsi, dei)
gen_rank_same(msi, mei, dsi, dei)
gen_riji_event()
gen_tail()
def main():
gen_total()
main()
#python riji.py 9 1 9 31 riji.log > 1.gv
脚本会将周末和工作日进行简单着色区分
- 测试文件:riji.log
2023-09-10 周日;t10; t10-abc
2023-09-09 周六;t9; ti_kaj;
2023-09-08 周五;t8
2023-09-07 周四;
2023-09-06 周三;
2023-09-05 周二;t5; teat5; 喂马;劈柴;周游世界
2023-09-04 周一;t4
2023-09-03 周日;t3; t3-2
2023-09-02 周六;t2
2023-09-01 周五;test1
文件格式:
日期 星期;事件1;事件2
例子:
2023-09-01 周五;test1
需要用分号隔开
执行和效果
- 执行:
python riji.py 9 1 9 31 riji.log> 1.gv
指定开始结束日期,以及输出到gv文件,然后生成的dot使用Graphviz打开
- 效果
技巧
- 可以生成日记图,项目进展图,项目规划图,其他计划图等时间线相关的
- 将事情按照格式化写入riji.log 然后执行脚本生成Graphviz,将事件自动生成到时间线上面
- todo: 未来添加年份等自动生成方式
- 依赖格式化文件
- 每个item不要有逗号 逗号是一个事件分隔符(为了适配csv)
- 通过excel编辑 然后导出为csv可以直接使用,csv格式中日期需要以1900-09-10这种方式
综述
Graphviz图形化展示,结合timeline,结合文件自动生成,极大的提高了展示的效率和体感。python自动化生成可以将源数据和展示数据分开显示,这样可以针对很多其他场景极大的提高使用效率。