TransWikia.com

TikZ calendar, loading data from .csv

TeX - LaTeX Asked by Vojta Klimes on December 17, 2020

My goal is to have a year calendar with boxes instead of days that get filled according to the type of exercise I did that day. These exercise would be loaded from a .csv file in a format such as:

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

2020-01-02;

where each column is a particular type of activity and I just need to add the date and the code will do the rest.

This is my work so far:

documentclass{article}
usepackage[a4paper, total={8.5in, 11in}]{geometry}
usepackage{csvsimple}
usepackage{tikz}
usetikzlibrary{calendar}
usepackage{pgfcalendar}

begin{document}
defs{0.85} %size of box around day
defss{6.3ex} %space between days
defds{0.02}

defnexer{0.75} %1-1/number of exercise to be put into calendar

defcardio{red}
defstr{blue}
defspo{green}
defoth{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}

I have run into couple of problems, first of all this code won’t work if there are different number of days for each activity, meaning the .csv columns are not the same length. Also csvreader creates this weird effect that the calendar is "doubled" because it draws over itself and I do not know how to get rid of it.

Any help appreciated.

EDIT1: How it looks right now Current state of calendar

One Answer

I think what you want deviate from csv standard. Therefore, you need some custom implementation for your purposes.

enter image description here

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.98daywidth,
          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}

Correct answer by Alan Xiang on December 17, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP