Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to build a custom calendar using some features of TikZ. My starting point was a piece of code available in a comment of texample.net.

I would like to know if it is possible to mark some days with symbols different than circles. If you compile the code below, you will see that circles can be easily inserted in the calendar. Now I would like to know if someone could show me how to insert diamonds or triangles or squares and if possible filled with some color.

Thank you in advance for your help.

\documentclass[12pt]{article}
\usepackage{lscape,tikz}
\usepackage[brazil]{babel}
\usepackage[latin1]{inputenc}
\usepackage[margin=1in, paperwidth=15.8in, paperheight=8.5in]{geometry}
\usepackage{geometry}
\usepackage{amsmath,color,graphicx}
\usepackage{amsfonts}
\usepackage{amssymb}
\definecolor{Red}{cmyk}{0,1,1,0}
\def\red{\color{Red}}
\definecolor{Blue}{cmyk}{1,1,0,0}
\def\blue{\color{Blue}}

%%in preamble:
%
\Huge
\usetikzlibrary{arrows,shapes}
\usetikzlibrary{positioning,calendar,er}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes.geometric}

\newcommand{\calrow}[1]{\node[anchor=base east](seg){S};
\node[base right=of seg](ter){T}; \node[base right=of ter](qua){Q};
\node[base right=of qua](qui){Q}; \node[base right=of qui](sex){\ \!S};
\node[base right=of sex](sab){\ \!S}; \node[base right=of sab](dom){D};
\node[black,above=of qui]{\textbf{#1}};}
\newcommand{\calperiod}[1]{\calendar[dates=\the\year-#1-01 to \the\year-#1-last]
if(Sunday) [red] \holidays;}
\newcommand{\holidays}{% holidays in Italy
if (equals=01-15) {\draw (-0.348,0.135) circle (9.0pt);}%
if (equals=01-06) [black!50]%
if (equals=04-04) [black!50]%
if (equals=04-05) [black!50]%
if (equals=04-25) [black!50]%
if (equals=05-01) [black!50]%
if (equals=05-01) [black!50]%
if (equals=06-02) {\draw (-0.25,0.135) circle (9.0pt);}%
if (equals=08-15) [black!50]%
if (equals=11-01) [black!50]%
if (equals=12-08) [black!50]%
if (equals=12-25) [black!50]%
if (equals=12-26) [black!50]%
}
\colorlet{darkgreen}{green!50!black}


\begin{document}

\begin{tikzpicture}
[every calendar/.style={week list}]
%\node[star,draw,minimum size=.4cm,star point ratio=1.0,thick] at (calendar-\the\year-08-29){};
\sffamily
\matrix[%
row 1/.style={black,node distance=.3ex},%
row 3/.style={black,node distance=.3ex},
column sep=1ex,%
draw=black,thick,rounded corners=30pt,%
postaction={decorate,decoration={markings,mark=at position 0.51 with
{\node[fill=white,text=black,font={\bfseries\Large}] (year) {\the\year};}}}
% year on frame: decorations.markings library
]{%
% first row: week day and month
\calrow{Janeiro} & \calrow{Fevereiro} & \calrow{Março} &
\calrow{Abril} & \calrow{Maio} & \calrow{Junho} \\
% second row: calendar
\calperiod{01} & \calperiod{02} & \calperiod{03} &
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[0.4cm]
% third row: week day and month
\calrow{Julho} & \calrow{Agosto} & \calrow{Setembro} &
\calrow{Outubro} & \calrow{Novembro} & \calrow{Dezembro} \\
% forth row: calendar
\calperiod{07} & \calperiod{08} & \calperiod{09} &
\calperiod{10} & \calperiod{11} & \calperiod{12} \\
};
\end{tikzpicture}
\end{document}

Edition. To clean up the code, I remove the repetitions pointed out by Ulrike Fischer as well some useless comments.

share|improve this question
add comment

3 Answers

up vote 9 down vote accepted

If you modify the placement of the days slightly, you can easily add shapes without having to place the shapes using trial and error to find the right coordinates.

By adding

 every day/.style={anchor=base},
  day text={\%d=},rounded corners=0,anchor=base,text height=1ex,text depth=-0.5ex

to the calendar options you align the days in such a way that you can then just add \nodes to the days you want to highlight, without any fiddling around. day text={\%d=} takes care of making single digit days as wide as two digit ones.

By using \node[anchor=base,xshift=0.5ex](seg){S}; to print the first weekday letter, all the weekdays will align nicely with the days.

After these adjustments, you can highlight individual days using things like

if (equals=01-10) {\node [fill=yellow,draw,star] {};}

in the \holidays macro.

Here's the full adjusted code:

\documentclass[12pt]{article}
\usepackage{lscape,tikz}
\usepackage[brazil]{babel}
\usepackage[latin1]{inputenc}
\usepackage[margin=1in, paperwidth=15.8in, paperheight=8.5in]{geometry}
\usepackage{geometry}
\usepackage{amsmath,color,graphicx}
\usepackage{amsfonts}
\usepackage{amssymb}
\definecolor{Red}{cmyk}{0,1,1,0}
\def\red{\color{Red}}
\definecolor{Blue}{cmyk}{1,1,0,0}
\def\blue{\color{Blue}}

%%in preamble:
%
\Huge
\usetikzlibrary{arrows,shapes}
\usetikzlibrary{positioning,calendar,er}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes.geometric}

\newcommand{\calrow}[1]{\node[anchor=base,xshift=0.5ex](seg){S}; % Shift first weekday
\node[base right=of seg](ter){T}; \node[base right=of ter](qua){Q};
\node[base right=of qua](qui){Q}; \node[base right=of qui](sex){\ \!S};
\node[base right=of sex](sab){\ \!S}; \node[base right=of sab](dom){D};
\node[black,above=of qui]{\textbf{#1}};}
\newcommand{\calperiod}[1]{\calendar[dates=\the\year-#1-01 to \the\year-#1-last,
  every day/.style={anchor=base}, % Center days
  day text={\%d=},rounded corners=0,anchor=base,text height=1ex,text depth=-0.5ex] % Make node placement easier
if(Sunday) [red] \holidays;}
\newcommand{\holidays}{
if (equals=01-15) {\node [draw,regular polygon,regular polygon sides=3] {};}
if (equals=01-20) {\node [draw,cloud] {};}
if (equals=01-10) {\node [fill=yellow,draw,star] {};}
if (equals=01-06) [black!50]%
if (equals=04-04) [black!50]%
if (equals=04-05) [black!50]%
if (equals=04-25) [black!50]%
if (equals=05-01) [black!50]%
if (equals=05-01) [black!50]%
if (equals=06-02) {\draw (-0.25,0.135) circle (9.0pt);}%
if (equals=08-15) [black!50]%
if (equals=11-01) [black!50]%
if (equals=12-08) [black!50]%
if (equals=12-25) [black!50]%
if (equals=12-26) [black!50]%
}
\colorlet{darkgreen}{green!50!black}


\begin{document}

\begin{tikzpicture}
[every calendar/.style={week list}]
%\node[star,draw,minimum size=.4cm,star point ratio=1.0,thick] at (calendar-\the\year-08-29){};
\sffamily
\matrix[%
row 1/.style={black,node distance=.3ex},%
row 3/.style={black,node distance=.3ex},
column sep=1ex,%
draw=black,thick,rounded corners=30pt,%
postaction={decorate,decoration={markings,mark=at position 0.51 with
{\node[fill=white,text=black,font={\bfseries\Large}] (year) {\the\year};}}}
% year on frame: decorations.markings library
]{%
% first row: week day and month
\calrow{Janeiro} & \calrow{Fevereiro} & \calrow{Março} &
\calrow{Abril} & \calrow{Maio} & \calrow{Junho} \\
% second row: calendar
\calperiod{01} & \calperiod{02} & \calperiod{03} &
\calperiod{04} & \calperiod{05} & \calperiod{06} \\[0.4cm]
% third row: week day and month
\calrow{Julho} & \calrow{Agosto} & \calrow{Setembro} &
\calrow{Outubro} & \calrow{Novembro} & \calrow{Dezembro} \\
% forth row: calendar
\calperiod{07} & \calperiod{08} & \calperiod{09} &
\calperiod{10} & \calperiod{11} & \calperiod{12} \\
};
\end{tikzpicture}
\end{document}

calendar with shapes

share|improve this answer
    
Such a nice answer Jake. Thank you very much for this code and the explanations. –  Leandro Mar 23 '11 at 5:49
    
+1 ...fantastic! –  wim Jan 3 '12 at 12:21
add comment

You can change the TikZ-drawing command inside if (equals=01-15) {\draw (-0.348,0.135) circle (9.0pt);} (e.g. on line 52) to something that suits you, but need to fiddle with the placement.

A filled circle can be done with {\fill [semitransparent,red] (-.25,.2) circle (.25);}. If you take a look at the "decoration"-section in the TikZ-Manual, you should be able to draw anything you want over the day you choose.

share|improve this answer
    
Hi Habi, thanks for reply. I tried some things we are talking about. For instance : if (equals=2011-03-21) {\filldraw[fill=green!20!white, draw=green] (-0.59,-0.125) rectangle +(0.55,0.5);} But I guess because of the argument in the matrix command rounded corners=30pt this rectangle looks strange when I compile. –  Leandro Mar 22 '11 at 2:22
    
@Leandro: You can correct the problem with the rounded corners by using filldraw[fill=green!20!white, draw=green,rounded corners=0] (-0.59,-0.125) rectangle +(0.55,0.5); –  Jake Mar 22 '11 at 14:07
add comment

What a complicated example! And why do you load babel and tikz twice?

Beside this it is easy to draw something else:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calendar,shapes}
\begin{document}

\begin{tikzpicture}
\makeatletter

\calendar (K) [dates=2011-01-01 to 2011-03-30,week list,
 month label above left,month yshift=45pt, 
 month code={\node (mo)[anchor=west,yshift=-2pt,xshift=-1pt]{\tiny Mo};
             \node (di) at (mo.center)[every month,anchor=center,xshift= \tikz@lib@cal@xshift]{\tiny
             Di};}
             ];

\draw[black](K-2011-01-01) node[starburst,draw]{};

\draw[black](K-2011-02-15) node[regular polygon, regular polygon
sides=6,draw]{~};
\end{tikzpicture}
\end{document}
share|improve this answer
    
Hi Ulrike, thanks for post this. I will remove the repetitions we mention. Thanks for the code. I compiled it but after some tries I did not figure out how to display the initials of the week days ( months are very simple) is it simple ? I don't know why the drawings you suggest are not working in my code. Did you tried ? Perhaps can be a problem with my system. –  Leandro Mar 22 '11 at 2:36
    
I certainly tried my code and it works. I'm using the current tikz/pgf version (v2.10) in miktex. Did you try exactly my code? I added some code to show week days – there exist certainly other ways to get them. –  Ulrike Fischer Mar 22 '11 at 8:34
    
nice example. how would I increase the size of the shapes? –  r m Mar 14 '13 at 16:58
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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