TikZ-Kalender, Daten werden aus CSV geladen

TikZ-Kalender, Daten werden aus CSV geladen

Mein Ziel ist ein Jahreskalender mit Kästchen statt Tagen, die je nach Art der Übung, die ich an dem Tag gemacht habe, ausgefüllt werden. Diese Übungen würden aus einer CSV-Datei in einem Format wie diesem geladen:

2020-01-01;2020-01-01;2020-01-03

02.01.2020; ...

wobei jede Spalte einen bestimmten Aktivitätstyp darstellt und ich nur das Datum hinzufügen muss und der Code den Rest erledigt.

Dies ist meine bisherige Arbeit:

\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}

Ich bin auf ein paar Probleme gestoßen. Erstens funktioniert dieser Code nicht, wenn es für jede Aktivität eine unterschiedliche Anzahl von Tagen gibt, was bedeutet, dass die CSV-Spalten nicht die gleiche Länge haben. Außerdem erzeugt CSVReader diesen seltsamen Effekt, dass der Kalender „doppelt“ wird, weil er sich selbst überzieht, und ich weiß nicht, wie ich das loswerden kann.

Jede Hilfe ist willkommen.

EDIT1: So sieht es jetzt ausAktueller Stand des Kalenders

Antwort1

Ich denke, dass das, was Sie wollen, vom CSV-Standard abweicht. Daher benötigen Sie für Ihre Zwecke eine benutzerdefinierte Implementierung.

Bildbeschreibung hier eingeben

\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}

verwandte Informationen