我的目标是制作一个年历,日历上用方框代替日期,并根据我当天所做的锻炼类型进行填写。这些锻炼将从 .csv 文件中加载,格式如下:
2020-01-01;2020-01-01;2020-01-03
2020-01-02; ...
其中每一列都代表一种特定类型的活动,我只需要添加日期,代码就会完成剩下的工作。
这是我迄今为止的工作:
\documentclass{article}
\usepackage[a4paper, total={8.5in, 11in}]{geometry}
\usepackage{csvsimple}
\usepackage{tikz}
\usetikzlibrary{calendar}
\usepackage{pgfcalendar}
\begin{document}
\def\s{0.85} %size of box around day
\def\ss{6.3ex} %space between days
\def\ds{0.02}
\def\nexer{0.75} %1-1/number of exercise to be put into calendar
\def\cardio{red}
\def\str{blue}
\def\spo{green}
\def\oth{orange}
\begin{tikzpicture}[every calendar/.style={
week list, month label above centered, day xshift=\ss, day yshift=\ss,
day code = {
\draw (-0.5*\s,0.5*\s) -- (0.5*\s,0.5*\s) -- (0.5*\s,-0.5*\s) -- (-0.5*\s,-0.5*\s) -- cycle;
}
}]
\csvreader[no head, separator=semicolon]{cal.csv}{1=\dcar,2=\dstr,3=\dspo,4=\doth}{
\calendar
[dates=2020-01-01 to 2020-01-last]
if (equals=\dcar) {\filldraw[\cardio] (-0.5*\s+\ds,0.5*\s-\ds) --
(0.5*\s-\ds,0.5*\s-\ds) --
(0.5*\s-\ds,-0.5*\s+\s*\nexer+\ds) --
(-0.5*\s+\ds,-0.5*\s+\s*\nexer+\ds) -- cycle;}
if (equals=\dstr) {\filldraw[\str,yshift=-5] (-0.5*\s+\ds,0.5*\s-\ds) --
(0.5*\s-\ds,0.5*\s-\ds) --
(0.5*\s-\ds,-0.5*\s+\s*\nexer+\ds) --
(-0.5*\s+\ds,-0.5*\s+\s*\nexer+\ds) -- cycle;}
if (equals=\dspo) {\filldraw[\spo,yshift=-10] (-0.5*\s+\ds,0.5*\s-\ds) --
(0.5*\s-\ds,0.5*\s-\ds) --
(0.5*\s-\ds,-0.5*\s+\s*\nexer+\ds) --
(-0.5*\s+\ds,-0.5*\s+\s*\nexer+\ds) -- cycle;}
if (equals=\doth) {\filldraw[\oth,yshift=-15] (-0.5*\s+\ds,0.5*\s-\ds) --
(0.5*\s-\ds,0.5*\s-\ds) --
(0.5*\s-\ds,-0.5*\s+\s*\nexer+\ds) --
(-0.5*\s+\ds,-0.5*\s+\s*\nexer+\ds) -- cycle;};}
\end{tikzpicture}
\end{document}
我遇到了几个问题,首先,如果每个活动的天数不同,即 .csv 列的长度不同,则此代码将无法运行。此外,csvreader 会产生这种奇怪的效果,即日历“翻倍”,因为它会覆盖自身,我不知道如何消除它。
任何帮助均感激不尽。
答案1
我认为您想要的与 csv 标准不同。因此,您需要一些自定义实现来满足您的目的。
\documentclass{article}
\usepackage[a4paper, total={8.5in, 11in}]{geometry}
\usepackage{csvsimple}
\usepackage{tikz}
\usetikzlibrary{calendar}
\usepackage{pgfcalendar}
\usepackage{expl3}
% sample csv file
\begin{filecontents*}{cal.csv}
2020-01-01;2020-01-10;2020-01-03
2020-01-02;2020-01-10;2020-01-05;2020-01-25
2020-01-06;2020-01-16;2020-01-03
2020-01-08;2020-01-09;2020-01-23
\end{filecontents*}
\newlength{\daywidth}
\setlength{\daywidth}{5.0ex} %size of box around day
\newlength{\dayinterval}
\setlength{\dayinterval}{6.3ex} %space between days
\newlength{\dayitemheight}
\setlength{\dayitemheight}{0.8ex}
\newlength{\dayiteminterval}
\setlength{\dayiteminterval}{0.2ex}
\ExplSyntaxOn
\seq_new:N \g_doc_dates_seq
\cs_set:Npn \doc_read_file:n #1 {
\ior_open:Nn \g_tmpa_ior {#1}
\seq_gclear:N \g_doc_dates_seq
\ior_str_map_inline:Nn \g_tmpa_ior {
\str_set:Nx \l_tmpa_str {\tl_trim_spaces:n {##1}}
\str_if_empty:NF \l_tmpa_str {
\seq_gput_right:NV \g_doc_dates_seq \l_tmpa_str
}
}
\ior_close:N \g_tmpa_ior
}
\cs_set:Npn \doc_draw_command:nnn #1#2#3 {
\node[#1,#2] at (#3.north) {};
}
\cs_generate_variant:Nn \regex_split:nnN {nVN}
\cs_generate_variant:Nn \doc_draw_command:nnn {xnx}
\newcommand{\drawfilerow}[3]{
\iow_term:x {show: \fp_eval:n {-(#2 + 0.5) * (1.0ex)}pt}
\int_compare:nT {1 <= #2 <= \seq_count:N \g_doc_dates_seq} {
\tl_set:Nx \l_tmpa_tl {\seq_item:Nn \g_doc_dates_seq {#2}}
\regex_split:nVN {;} \l_tmpa_tl \l_tmpa_seq
\seq_map_inline:Nn \l_tmpa_seq {
\str_set:Nx \l_tmpa_str {\tl_trim_spaces:n {##1}}
\str_if_empty:NF \l_tmpa_str {
\doc_draw_command:xnx {
minimum~width=0.98\daywidth,
minimum~height=\dayitemheight,
yshift=\fp_eval:n {-(#2 - 1) * (\dayitemheight + \dayiteminterval) -0.2pt}pt,
anchor=north,
inner~sep=0pt,
outer~sep=0pt
} {fill=#3} {#1-\str_use:N \l_tmpa_str};
}
}
}
}
\newcommand{\readcalendarfile}[1]{
\doc_read_file:n {#1}
}
\ExplSyntaxOff
\begin{document}
% read "csv" file
\readcalendarfile{cal.csv}
\begin{tikzpicture}[every calendar/.style={
week list,
month label above centered,
day xshift=\dayinterval,
day yshift=\dayinterval,
day code = {
\node[minimum width=\daywidth,
minimum height=\daywidth,
name=\pgfcalendarsuggestedname,
draw=black] {};
}
}]
\calendar (mycal) [dates=2020-01-01 to 2020-01-last];
% use contents from "csv" file
\drawfilerow{mycal}{1}{red};
\drawfilerow{mycal}{2}{blue};
\drawfilerow{mycal}{3}{green};
\drawfilerow{mycal}{4}{orange};
\end{tikzpicture}
\end{document}