我正在用 Ti 整理一个多月日历钾Z 并且看到月份标签中有一些尴尬和不受欢迎的对齐,尽管使用了month label above centered
。特别是,月份标签似乎只在第一个六列,而不是全部七:
我在下面以最小的上下文重现了我的代码。 两个问题:这是怎么回事?我该如何纠正这种对齐?
\documentclass[letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calendar,shapes}
\makeatletter%
\tikzstyle{week list sunday}=[
% Note that we cannot extend from week list,
% the execute before day scope is cumulative
execute before day scope={%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{
% On first of month, except when first date in calendar.
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
\pgftransformyshift{-\pgf@y}
}}{}%
},
execute at begin day scope={%
% Because for TikZ Monday is 0 and Sunday is 6,
% we can't directly use \pgfcalendarcurrentweekday,
% but instead we define \c@pgf@counta (basically) as:
% (\pgfcalendarcurrentweekday + 1) % 7
\pgfmathsetlength\pgf@x{\tikz@lib@cal@xshift}%
\ifnum\pgfcalendarcurrentweekday=6
\c@pgf@counta=0
\else
\c@pgf@counta=\pgfcalendarcurrentweekday
\advance\c@pgf@counta by 1
\fi
\pgf@x=\c@pgf@counta\pgf@x
% Shift to the right position for the day.
\pgftransformxshift{\pgf@x}
},
execute after day scope={
% Week is done, shift to the next line.
\ifdate{Saturday}{
% But not if it's already the last day of the month.
\ifdate{end of month=1}{}{
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
\pgftransformyshift{-\pgf@y}
}%
}{}%
},
% This should be defined, glancing from the source code.
tikz@lib@cal@width=7
]
\tikzoption{day headings}{\tikzstyle{day heading}=[#1]}
\tikzstyle{every calendar}=[week list sunday,
month label above centered,
month text=\textbf{\%mt~\%y-},
day xshift = 0.5cm,
day letter headings]
\tikzstyle{every day}=[anchor=base]
\tikzstyle{day heading}=[]
\tikzstyle{day letter headings}=[
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\pgf@ya}{\tikz@lib@cal@yshift}%
\pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
\pgftransformyshift{-\pgf@ya}
\foreach \d/\l in {0/S,1/M,2/T,3/W,4/T,5/F,6/S} {
\pgf@xa=\d\pgf@xa%
\pgftransformxshift{\pgf@xa}%
\pgftransformyshift{\pgf@ya}%
\node[every day,day heading]{\l};%
}
}{}%
}%
]
\makeatother%
% ==================================================
\begin{document}
\begin{tikzpicture}
\calendar (K) [dates=2013-01-01 to 2013-03-last]
if (weekend) [black!40];
\draw[black](K-2013-01-21) circle (0.6em);
\draw[black](K-2013-02-13) circle (0.6em);
\draw[black](K-2013-03-10) circle (0.6em);
\draw[black](K-2013-03-31) circle (0.6em);
\end{tikzpicture}
\end{document}
答案1
tikz@lib@cal@width
例如,您可以将值增加到7.8
:
\documentclass[letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calendar,shapes}
\makeatletter%
\tikzstyle{week list sunday}=[
% Note that we cannot extend from week list,
% the execute before day scope is cumulative
execute before day scope={%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{
% On first of month, except when first date in calendar.
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
\pgftransformyshift{-\pgf@y}
}}{}%
},
execute at begin day scope={%
% Because for TikZ Monday is 0 and Sunday is 6,
% we can't directly use \pgfcalendarcurrentweekday,
% but instead we define \c@pgf@counta (basically) as:
% (\pgfcalendarcurrentweekday + 1) % 7
\pgfmathsetlength\pgf@x{\tikz@lib@cal@xshift}%
\ifnum\pgfcalendarcurrentweekday=6
\c@pgf@counta=0
\else
\c@pgf@counta=\pgfcalendarcurrentweekday
\advance\c@pgf@counta by 1
\fi
\pgf@x=\c@pgf@counta\pgf@x
% Shift to the right position for the day.
\pgftransformxshift{\pgf@x}
},
execute after day scope={
% Week is done, shift to the next line.
\ifdate{Saturday}{
% But not if it's already the last day of the month.
\ifdate{end of month=1}{}{
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
\pgftransformyshift{-\pgf@y}
}%
}{}%
},
% This should be defined, glancing from the source code.
tikz@lib@cal@width=7.8
]
\tikzoption{day headings}{\tikzstyle{day heading}=[#1]}
\tikzstyle{every calendar}=[week list sunday,
month label above centered,
month text=\textbf{\%mt~\%y-},
day xshift = 0.5cm,
day letter headings]
\tikzstyle{every day}=[anchor=base]
\tikzstyle{day heading}=[]
\tikzstyle{day letter headings}=[
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\pgf@ya}{\tikz@lib@cal@yshift}%
\pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
\pgftransformyshift{-\pgf@ya}
\foreach \d/\l in {0/S,1/M,2/T,3/W,4/T,5/F,6/S} {
\pgf@xa=\d\pgf@xa%
\pgftransformxshift{\pgf@xa}%
\pgftransformyshift{\pgf@ya}%
\node[every day,day heading]{\l};%
}
}{}%
}%
]
\makeatother%
% ==================================================
\begin{document}
\begin{tikzpicture}
\calendar (K) [dates=2013-01-01 to 2013-03-last]
if (weekend) [black!40];
\draw[black](K-2013-01-21) circle (0.6em);
\draw[black](K-2013-02-13) circle (0.6em);
\draw[black](K-2013-03-10) circle (0.6em);
\draw[black](K-2013-03-31) circle (0.6em);
\end{tikzpicture}
\end{document}
答案2
我认为这是 pgf 中的一个错误。您使用键month label above centered
将月份名称放在日期上方,这在文件中定义tikzlibrarycalendar.code.tex
为
\tikzset{month label above centered/.style={%
execute before day scope={%
\ifdate{day of month=1}{%
{
\pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
\pgf@xb=\tikz@lib@cal@width\pgf@xa%
\advance\pgf@xb by-\pgf@xa%
\pgf@xb=.5\pgf@xb%
\pgftransformxshift{\pgf@xb}%
\pgftransformxshift{-1.5ex}%
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
\pgftransformyshift{1.25\pgf@y}
\tikzmonthcode%
}
}{}},
every month/.append style={anchor=base}
}}
显然,有一个额外的\pgftransformxshift{-1.5ex}
,这是造成错位的原因。如果您month label above centered
在代码中用上面的定义替换,但删除\pgftransformxshift{-1.5ex}
,您将获得正确的对齐。这是您修改后的 MWE:
\documentclass[letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calendar,shapes}
\makeatletter%
\tikzstyle{week list sunday}=[
% Note that we cannot extend from week list,
% the execute before day scope is cumulative
execute before day scope={%
\ifdate{day of month=1}{\ifdate{equals=\pgfcalendarbeginiso}{}{
% On first of month, except when first date in calendar.
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@month@yshift}%
\pgftransformyshift{-\pgf@y}
}}{}%
},
execute at begin day scope={%
% Because for TikZ Monday is 0 and Sunday is 6,
% we can't directly use \pgfcalendarcurrentweekday,
% but instead we define \c@pgf@counta (basically) as:
% (\pgfcalendarcurrentweekday + 1) % 7
\pgfmathsetlength\pgf@x{\tikz@lib@cal@xshift}%
\ifnum\pgfcalendarcurrentweekday=6
\c@pgf@counta=0
\else
\c@pgf@counta=\pgfcalendarcurrentweekday
\advance\c@pgf@counta by 1
\fi
\pgf@x=\c@pgf@counta\pgf@x
% Shift to the right position for the day.
\pgftransformxshift{\pgf@x}
},
execute after day scope={
% Week is done, shift to the next line.
\ifdate{Saturday}{
% But not if it's already the last day of the month.
\ifdate{end of month=1}{}{
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
\pgftransformyshift{-\pgf@y}
}%
}{}%
},
% This should be defined, glancing from the source code.
tikz@lib@cal@width=7
]
\tikzoption{day headings}{\tikzstyle{day heading}=[#1]}
\tikzstyle{every calendar}=[week list sunday,
% Replace this:
% month label above centered
% With this modified extract from 'tikzlibrarycalendar.code.tex':
execute before day scope={%
\ifdate{day of month=1}{%
{
\pgfmathsetlength{\pgf@xa}{\tikz@lib@cal@xshift}%
\pgf@xb=\tikz@lib@cal@width\pgf@xa%
\advance\pgf@xb by-\pgf@xa%
\pgf@xb=.5\pgf@xb%
\pgftransformxshift{\pgf@xb}%
% \pgftransformxshift{-1.5ex}% Removed misalignment
\pgfmathsetlength{\pgf@y}{\tikz@lib@cal@yshift}%
\pgftransformyshift{1.25\pgf@y}
\tikzmonthcode%
}
}{}},
every month/.append style={anchor=base}
% End of replacement text. Comma follows.
,
month text=\textbf{\%mt~\%y-},
day xshift = 0.5cm,
day letter headings]
\tikzstyle{every day}=[anchor=base]
\tikzstyle{day heading}=[]
\tikzstyle{day letter headings}=[
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\pgf@ya}{\tikz@lib@cal@yshift}%
\pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
\pgftransformyshift{-\pgf@ya}
\foreach \d/\l in {0/S,1/M,2/T,3/W,4/T,5/F,6/S} {
\pgf@xa=\d\pgf@xa%
\pgftransformxshift{\pgf@xa}%
\pgftransformyshift{\pgf@ya}%
\node[every day,day heading]{\l};%
}
}{}%
}%
]
\makeatother%
% ==================================================
\begin{document}
\begin{tikzpicture}
\calendar (K) [dates=2013-01-01 to 2013-03-last]
if (weekend) [black!40];
\draw[black](K-2013-01-21) circle (0.6em);
\draw[black](K-2013-02-13) circle (0.6em);
\draw[black](K-2013-03-10) circle (0.6em);
\draw[black](K-2013-03-31) circle (0.6em);
\end{tikzpicture}
\end{document}