TikZ 日历中的月份标签未对齐

TikZ 日历中的月份标签未对齐

我正在用 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}

TikZ 日历中的月份标签未对齐

答案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}

相关内容