
내 목표는 그날 내가 한 운동 유형에 따라 날짜가 채워지는 대신 상자가 있는 1년 달력을 만드는 것입니다. 이러한 연습은 다음과 같은 형식으로 .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}