根据主题答案带有 tikz 的日历我尝试将日期名称翻译成德语。但是,不知为何,对齐效果不太好。我该如何解决这个问题?
截屏
平均能量损失
\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}
我的问题
我不知道如何修改
\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}};
}
让所有事物完美地排列。
答案1
day xshift
可以使用选项来控制天数之间的间隔\calendar
。请注意,此间隔是在east
连续几天的锚点之间测量的。
\calendar[dates=\currentyear-#2-01 to \currentyear-#2-last, day xshift=1.8em]
然后,我们可以将连续日期标签的锚点之间的空间设置east
为相同:
\newcommand{\calrow}[1]{\node[anchor=east] (Mon){Mo};
\node[right=1.8em of Mon.east, anchor=east](Tue){Di};
...
}
编辑:如果您希望日期标签与日期数字左对齐,一种解决方案是使用具有日期数字宽度(即 24)的幻影节点,然后根据其west
锚点放置日期标签:
\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};
...
}
带有左对齐日期标签的完整代码:
\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}
答案2
我想看看我能否让这个过程更智能一些,避免手动调整太多的长度。我以一个星期天(“Mo”)作为参考,测量它的宽度,然后用它来设置代码中的各种内容。此外,还有一个\padding
可以根据需要调整的参数。它现在也可以处理三个字母的星期天(这是否是一个好主意,首先应该留给读者练习——不过,它可能看起来有点局促\padding
)。
设置时仍需要进行一些轻微的手动调整every day/.append style={inner xsep=0.2ex}
,但现在已经设置好了,似乎不再需要更改(至少在我尝试过的几种不同配置中不需要更改)。也许有人也可以找到一种很好的自动化方法。
\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}
答案3
和matrix
weekday above
如果你使用如下定义的样式
\tikzset{
every weekday/.style={anchor=south east, node contents=\%w.},
weekday above/.style={
if = {(day of month=1) [days={append after command={
node [at={(\tikzlastnode.north east)},
alias=@firstweekday, every weekday]}}]},
if = {(day of month=2, day of month=3, day of month=4,
day of month=5, day of month=6, day of month=7) [
days={append after command={
node [at={(@firstweekday.south east-|\tikzlastnode.south east)},
every weekday]}}]}}}
你可以让calendar
做的工作放在工作日
every calendar/.append style = weekday above
还有一种样式叫做,month label above centered
但是它的水平放置不是很精确。
但是,我们可以使用星期四的节点将月份的节点放置在其上方,方法是定义:
\tikzset{
weekday above and month label centered above weekdays/.style={
weekday above, every weekday/.append style={
name=\pgfcalendarprefix-weekday-\pgfcalendarcurrentweekday},
if = {(day of month=8) {\tikzmonthcode}},
every month/.style={
at=(\pgfcalendarprefix-weekday-3.north), anchor=south}}}
代码
\documentclass[ngerman,multi=tikzpicture,varwidth=false,border=5]{standalone}
\usepackage{babel,translator,tikz}
\usepackage[utf8]{inputenc}
\renewcommand\familydefault\sfdefault
\usetikzlibrary{calendar}
\colorlet{darkgreen}{green!50!black}
\newcommand{\calperiod}[2][\pgfkeysvalueof{/tikz/current year}]{%
\calendar[dates=#1-#2-01 to #1-#2-last] if (Sunday) [black!50];}
\tikzset{
current year/.initial=2017,
every weekday/.style={anchor=south east, node contents=\%w.},
weekday above/.style={
if = {(day of month=1) [days={append after command={
node [at={(\tikzlastnode.north east)}, alias=@firstweekday, every weekday]}}]},
if = {(day of month=2, day of month=3, day of month=4, day of month=5, day of month=6,
day of month=7) [ days={append after command={
node[at={(@firstweekday.south east-|\tikzlastnode.south east)}, every weekday]}}]}},
weekday above and month label centered above weekdays/.style={
weekday above, every weekday/.append style={
name=\pgfcalendarprefix-weekday-\pgfcalendarcurrentweekday},
if = {(day of month=8) {\tikzmonthcode}},
every month/.style={at=(\pgfcalendarprefix-weekday-3.north), anchor=south}}}
\begin{document}
\tikz[every calendar/.style={
week list, weekday above and month label centered above weekdays,
every month/.append style={darkgreen, anchor=south, font=\bfseries}},
day xshift=4ex]
\matrix[row sep=3ex, column sep=2ex,
draw=darkgreen, thick, rounded corners=5pt,
every weekday/.append style=darkgreen,
]{
\calperiod{01} & \calperiod{02} & \calperiod{03} \\
\calperiod{04} & \calperiod{05} & \calperiod{06} \\
\calperiod{07} & \calperiod{08} & \calperiod{09} \\
\calperiod{10} & \calperiod{11} & \calperiod{12} \\
};
\end{document}
没有matrix
但是我们也可以让calendar
所有的事情都不需要使用像下面定义的matrix
样式week list three columns
\tikzset{
current week in month/.initial=0,
week list three columns/.style={
execute before day scope=%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{%
\pgftransformyshift
{\pgfkeysvalueof{/tikz/current week in month}*(\tikz@lib@cal@yshift)}%
\pgfkeyssetvalue{/tikz/current week in month}{0}
\pgftransformxshift
{(mod(\numexpr\%m0-1\relax,3) ? 1 : -2) * (\tikz@lib@cal@month@xshift)}%
\pgftransformyshift{!mod(\numexpr\%m0-1\relax,3)*
-(\tikz@lib@cal@month@yshift)}}}{},
execute at begin day scope=%
\pgftransformxshift{\pgfcalendarcurrentweekday*(\tikz@lib@cal@xshift)},
execute after day scope=%
\ifdate{Sunday}{%
\pgftransformyshift{-(\tikz@lib@cal@yshift)}%
\pgfmathadd@{\pgfkeysvalueof{/tikz/current week in month}}{1}%
\pgfkeyslet{/tikz/current week in month}\pgfmathresult}{},
tikz@lib@cal@width=7, month xshift=32ex, month yshift=26ex}}
该backgrounds
库用于在整个图片周围绘制一个矩形。
代码
\documentclass[ngerman,multi=tikzpicture,varwidth=false,border=5,convert]{standalone}
\usepackage{babel,translator,tikz}
\usepackage[utf8]{inputenc}
\renewcommand\familydefault\sfdefault
\usetikzlibrary{calendar,backgrounds}
\colorlet{darkgreen}{green!50!black}
\makeatletter
\tikzset{
week list three columns/.style={
execute before day scope=%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{%
\pgftransformyshift
{\pgfkeysvalueof{/tikz/current week in month}*(\tikz@lib@cal@yshift)}%
\pgfkeyssetvalue{/tikz/current week in month}{0}
\pgftransformxshift
{(mod(\numexpr\%m0-1\relax,3) ? 1 : -2) * (\tikz@lib@cal@month@xshift)}%
\pgftransformyshift{!mod(\numexpr\%m0-1\relax,3)*
-(\tikz@lib@cal@month@yshift)}}}{},
execute at begin day scope=%
\pgftransformxshift{\pgfcalendarcurrentweekday*(\tikz@lib@cal@xshift)},
execute after day scope=%
\ifdate{Sunday}{%
\pgftransformyshift{-(\tikz@lib@cal@yshift)}%
\pgfmathadd@{\pgfkeysvalueof{/tikz/current week in month}}{1}%
\pgfkeyslet{/tikz/current week in month}\pgfmathresult}{},
tikz@lib@cal@width=7, month xshift=32ex, month yshift=26ex}}
\makeatother
\tikzset{
current year/.initial=2017, current week in month/.initial=0,
every weekday/.style={anchor=south east, node contents=\%w.},
weekday above/.style={
if = {(day of month=1) [days={append after command={
node [at={(\tikzlastnode.north east)}, alias=@firstweekday, every weekday]}}]},
if = {(day of month=2, day of month=3, day of month=4, day of month=5, day of month=6,
day of month=7) [ days={append after command={
node[at={(@firstweekday.south east-|\tikzlastnode.south east)}, every weekday]}}]}},
weekday above and month label centered above weekdays/.style={
weekday above, every weekday/.append style={
name=\pgfcalendarprefix-weekday-\pgfcalendarcurrentweekday},
if = {(day of month=8) {\tikzmonthcode}},
every month/.style={at=(\pgfcalendarprefix-weekday-3.north), anchor=south}}}
\begin{document}
\tikz[background rectangle/.style={draw=darkgreen, thick, rounded corners=5pt},
show background rectangle]
\calendar [
week list three columns,
weekday above and month label centered above weekdays,
every month/.append style={darkgreen, font=\bfseries},
every weekday/.append style=darkgreen,
day xshift=4ex, dates=2017-01-01 to 2017-12-31];
\end{document}