
私の目標は、その日に行ったエクササイズの種類に応じて記入される、日数ではなくボックス付きの年間カレンダーを作成することです。これらのエクササイズは、次のような形式の .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 は、カレンダーがそれ自体の上に描画されるため、カレンダーが「2 倍」になるという奇妙な効果を生み出しますが、これを取り除く方法がわかりません。
ご協力いただければ幸いです。
答え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}