6

Based on the answer of the topic calendar with tikz I tried to translate the names of the days to German. However, it somehow doesn't align very well. How can I fix this?

Screenshot

Enter image description here

MWE

\documentclass[tikz,border=5]{standalone}
\usepackage[utf8]{inputenc}
\renewcommand\familydefault\sfdefault
\usetikzlibrary{positioning,calendar}

\colorlet{darkgreen}{green!50!black}

\newcommand{\calrow}[1]{%
\node[anchor=base east](Mon){Mo};
\node[base right=of Mon](Tue){Di};
\node[base right=of Tue](Wed){Mi};
\node[base right=of Wed](Thu){Do};
\node[base right=of Thu](Fri){Fr};
\node[base right=of Fri](Sat){Sa};
\node[base right=of Sat](Sun){So};
\node[darkgreen, above=of Thu]{\textbf{#1}};
}

\newcommand{\calperiod}[2][\currentyear]{%
  \calendar[dates=\currentyear-#2-01 to \currentyear-#2-last]
    if (Sunday) [black!50];}
\edef\currentyear{\the\year}

\begin{document}
\begin{tikzpicture}[every calendar/.style={week list},
year label/.style={
  fill=white,text=darkgreen,font=\bfseries\Large
}, current year/.store in=\currentyear,
current year=2017]
\matrix[%
row 1/.style={darkgreen,node distance=.3ex},%
row 3/.style={darkgreen,node distance=.3ex},
row 5/.style={darkgreen,node distance=.3ex},
row 7/.style={darkgreen,node distance=.3ex},
column sep=1ex,%
draw=darkgreen,thick,rounded corners=5pt
]{%

% first row: week day and month
\calrow{Januar} & \calrow{Februar} & \calrow{März} \\
\calperiod{01} & \calperiod{02} & \calperiod{03} \\[1ex]

% second row: calendar
\calrow{April} & \calrow{Mai} & \calrow{Juni} \\
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[1ex]

% third row: week day and month
\calrow{Juli} & \calrow{August} & \calrow{September} \\
\calperiod{07} & \calperiod{08} & \calperiod{09} \\[1ex]

% forth row: calendar
\calrow{Oktober} & \calrow{November} & \calrow{Dezember} \\
\calperiod{10} & \calperiod{11} & \calperiod{12} \\[1ex]\\
};

\end{tikzpicture}
\end{document}

My problem

I don't know how to modify

\newcommand{\calrow}[1]{%
    \node[anchor=base east](Mon){Mo};
    \node[base right=of Mon](Tue){Di};
    \node[base right=of Tue](Wed){Mi};
    \node[base right=of Wed](Thu){Do};
    \node[base right=of Thu](Fri){Fr};
    \node[base right=of Fri](Sat){Sa};
    \node[base right=of Sat](Sun){So};
    \node[darkgreen, above=of Thu]{\textbf{#1}};
    }

to get things to align perfectly.

  • 1
    You can influence the horizontal distance between days by adding day xshift=19pt or another length fo your choice to \begin{tikzpicture} (see chapter 45, page 525 of the pgf manual) – leandriis Dec 31 '17 at 12:35
7

The spacing between days can be controlled using the day xshift option of \calendar. Note that this spacing is measured between the east anchors of consecutive days.

\calendar[dates=\currentyear-#2-01 to \currentyear-#2-last, day xshift=1.8em]

We can then set the space between east anchors of consecutive day labels to be the same:

\newcommand{\calrow}[1]{\node[anchor=east] (Mon){Mo};
    \node[right=1.8em of Mon.east, anchor=east](Tue){Di};
    ...
}

Edit: If you want the day labels to left-align with the day numbers, one solution is to use a phantom node that has the width of a day number (i.e., 24), and then place the day labels based on their west anchor:

\newcommand{\calrow}[1]{
    % phantom node
    \node[anchor=east, draw=none] (start) {\phantom{24}};
    % left-aligned nodes
    \node[anchor=west] at (start.west) (Mon){Mo};
    \node[right=1.8em of Mon.west, anchor=west](Tue){Di};
    ...
}

calendar

Full code with left-aligned day labels:

\documentclass[tikz,border=5]{standalone}
\renewcommand\familydefault\sfdefault
\usetikzlibrary{positioning,calendar}

\colorlet{darkgreen}{green!50!black}
\colorlet{holiday}{black!50}
\newcommand{\calrow}[1]{
    % phantom node
    \node[anchor=east, draw=none] (start) {\phantom{24}};
    % left-aligned nodes
    \node[anchor=west] at (start.west) (Mon){Mo};
    \node[right=1.8em of Mon.west, anchor=west](Tue){Di}; \node[right=1.8em of Tue.west, anchor=west](Wed){Mi};
    \node[right=1.8em of Wed.west, anchor=west](Thu){Do}; \node[right=1.8em of Thu.west, anchor=west](Fri){Fr};
    \node[right=1.8em of Fri.west, anchor=west](Sat){Sa}; \node[right=1.8em of Sat.west, anchor=west](Sun){So};
    \node[darkgreen, above=of Thu]{\textbf{#1}};
}

\newcommand{\calperiod}[2][\currentyear]{%
    \calendar[dates=\currentyear-#2-01 to \currentyear-#2-last, day xshift=1.8em]
    if (Sunday) [holiday] \holidays;}
\edef\currentyear{\the\year}
\newcommand{\holidays}{% holidays in Italy
    if (equals=01-01) [holiday]%
    if (equals=01-06) [holiday]%
    if (equals=04-04) [holiday]%
    if (equals=04-05) [holiday]%
    if (equals=04-25) [holiday]%
    if (equals=05-01) [holiday]%
    if (equals=05-01) [holiday]%
    if (equals=06-02) [holiday]%
    if (equals=08-15) [holiday]%
    if (equals=11-01) [holiday]%
    if (equals=12-08) [holiday]%
    if (equals=12-25) [holiday]%
    if (equals=12-26) [holiday]%
}
\begin{document}
    \begin{tikzpicture}[every calendar/.style={week list},
    year label/.style={
        fill=white,text=darkgreen,font=\bfseries\Large
    }, current year/.store in=\currentyear,
    current year=2017]
    \matrix[%
    row 1/.style={darkgreen,node distance=.3ex},%
    row 3/.style={darkgreen,node distance=.3ex},
    row 5/.style={darkgreen,node distance=.3ex},
    row 7/.style={darkgreen,node distance=.3ex},
    column sep=1ex,%
    draw=darkgreen,thick,rounded corners=5pt,%
    append after command={ 
        \pgfextra{\edef\matrixname{\tikzlastnode}}
        node [year label/.try, right=1ex of \matrixname.south west] {\currentyear}
        node [year label/.try, right=1ex of \matrixname.north west] {\currentyear}
        node [year label/.try, left=1ex of \matrixname.south east] {\currentyear}
        node [year label/.try, left=1ex of \matrixname.north east] {\currentyear}
    }
    ]{%

        % first row: week day and month
        \calrow{Januar} & \calrow{Februar} & \calrow{M\"arz} \\
        \calperiod{01} & \calperiod{02} & \calperiod{03} \\[1ex]

        % second row: calendar
        \calrow{April} & \calrow{Mai} & \calrow{Juni} \\
        \calperiod{04} & \calperiod{05} & \calperiod{06} \\[1ex]

        % third row: week day and month
        \calrow{Juli} & \calrow{August} & \calrow{September} \\
        \calperiod{07} & \calperiod{08} & \calperiod{09} \\[1ex]

        % forth row: calendar
        \calrow{Oktober} & \calrow{November} & \calrow{Dezember} \\
        \calperiod{10} & \calperiod{11} & \calperiod{12} \\[1ex]\\
    };

    \end{tikzpicture}
\end{document}
  • Your solution seems to right align with the numbers below. How would you modify your solution to left align with the numbers below? – Sr. Schneider Dec 31 '17 at 12:47
  • 1
    @Sr.Schneider you can use a phantom node for that. See my edited answer. – javi_gg1 Dec 31 '17 at 14:02
  • Now there's only the centered version missing ;-) – Sr. Schneider Dec 31 '17 at 15:56
  • 1
    @Sr.Schneider Just replace all instances of west inside the definition of \calrow with center ;) – javi_gg1 Dec 31 '17 at 16:20
  • Is the phantom node necessary for the centered version? – Sr. Schneider Dec 31 '17 at 16:25
7

I wanted to see if I could make the process a bit smarter and avoid having to manually tinker with too many lengths. I take one weekday ("Mo") as a reference, measure its width, and then use that to set various things in the code. Additionally, there is a parameter \padding which can be adjusted as needed. It can now cope with three-letter weekdays as well (whether or not that is a good idea in the first place shall be left as an exercise to the reader -- it can start looking a bit cramped, though again, \padding).

2-letter weekdays

3-letter weekdays

Some slight manual fiddling was still required by setting every day/.append style={inner xsep=0.2ex}, though now that it's set up, it doesn't seem to require changing anymore (at least not in the few different configurations I've tried out). Maybe somebody can a nice way of automating that too.

\documentclass[tikz,border=5]{standalone}
\usepackage[utf8]{inputenc}
\renewcommand\familydefault\sfdefault
\usetikzlibrary{positioning,calendar}

\colorlet{darkgreen}{green!50!black}

% Adjust formatting here
\newcommand*\refday{Mo}
\newlength\padding
\setlength\padding{0.25ex} % Set as needed

\newcommand{\calrow}[1]{%
    \begin{scope}[every node/.style={
        anchor=east,
        align=right,% or left, depending on preference
        inner sep=0,
        outer sep=\padding,
        minimum width={width("\refday")},
        text width={width("\refday")}
    }
]
        \node[anchor=base east](Mon){Mo};
        \node[base right=0mm of Mon](Tue){Di};
        \node[base right=0mm of Tue](Wed){Mi};
        \node[base right=0mm of Wed](Thu){Do};
        \node[base right=0mm of Thu](Fri){Fr};
        \node[base right=0mm of Fri](Sat){Sa};
        \node[base right=0mm of Sat](Sun){So};
    \end{scope}%
    \node[darkgreen, above=of Thu]{\textbf{#1}};
}

\newcommand{\calperiod}[2][\currentyear]{%
  \calendar[dates=\currentyear-#2-01 to \currentyear-#2-last]
    if (Sunday) [black!50];}
\edef\currentyear{\the\year}

\begin{document}
\begin{tikzpicture}[
    day xshift={width("\refday") + 2 * \padding},% Double the outer sep of the \calrow scope
    every day/.append style={inner xsep=0.2ex},
    every calendar/.style={week list},
    year label/.style={
        fill=white,text=darkgreen,font=\bfseries\Large
    },
    current year/.store in=\currentyear,
    current year=2017]
\matrix[%
row 1/.style={darkgreen,node distance=.3ex},%
row 3/.style={darkgreen,node distance=.3ex},
row 5/.style={darkgreen,node distance=.3ex},
row 7/.style={darkgreen,node distance=.3ex},
column sep=1ex,%
draw=darkgreen,thick,rounded corners=5pt
]{%

% first row: week day and month
\calrow{Januar} & \calrow{Februar} & \calrow{März} \\
\calperiod{01} & \calperiod{02} & \calperiod{03} \\[1ex]

% second row: calendar
\calrow{April} & \calrow{Mai} & \calrow{Juni} \\
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[1ex]

% third row: week day and month
\calrow{Juli} & \calrow{August} & \calrow{September} \\
\calperiod{07} & \calperiod{08} & \calperiod{09} \\[1ex]

% forth row: calendar
\calrow{Oktober} & \calrow{November} & \calrow{Dezember} \\
\calperiod{10} & \calperiod{11} & \calperiod{12} \\[1ex]\\
};

\end{tikzpicture}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.