Calendario TikZ, cargando datos desde .csv

Calendario TikZ, cargando datos desde .csv

Mi objetivo es tener un calendario anual con casillas en lugar de días que se van llenando según el tipo de ejercicio que hice ese día. Estos ejercicios se cargarían desde un archivo .csv en un formato como el siguiente:

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

2020-01-02; ...

donde cada columna es un tipo particular de actividad y solo necesito agregar la fecha y el código hará el resto.

Este es mi trabajo hasta ahora:

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

Me he encontrado con un par de problemas. En primer lugar, este código no funcionará si hay una cantidad diferente de días para cada actividad, lo que significa que las columnas .csv no tienen la misma longitud. Además, csvreader crea este extraño efecto de que el calendario se "duplica" porque se dibuja sobre sí mismo y no sé cómo deshacerme de él.

Cualquier ayuda se agradece.

EDIT1: Cómo se ve ahoraEstado actual del calendario

Respuesta1

Creo que lo que quieres es desviarse del estándar csv. Por lo tanto, necesita alguna implementación personalizada para sus propósitos.

ingrese la descripción de la imagen aquí

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

información relacionada