TiKZ 日历日列表向下,每列一个月

TiKZ 日历日列表向下,每列一个月

我正在尝试制作一个日历,每列显示一个月,每个月是一个day list downward。到目前为止,我只能通过为每个月创建一个日历并使用xshift手动定位它们来实现这一点。也许有更好的方法来实现这一点,那就是使用execute before day scope,但我不知道该怎么做。

有什么提示吗?

这是我当前的实现:

\documentclass[margin=2mm, crop]{standalone}

\usepackage{tikz}
\usetikzlibrary{calendar}

\begin{document}
\begin{tikzpicture}
  \calendar
      [
        dates=2022-10-01 to 2022-10-31,
        name=oct,
        day list downward,
        month label above left,
      ]
      if (weekend) [gray];

  \calendar
      [
        dates=2022-11-01 to 2022-11-30,
        name=nov,
        day list downward,
        month yshift=1em,
        month label above left,
        xshift=5cm,
      ]
      if (weekend) [gray];

  \calendar
      [
        dates=2022-12-01 to 2022-12-31,
        name=dec,
        day list downward,
        month label above left,
        xshift=10cm,
      ]
      if (weekend) [gray];

  \calendar
      [
        dates=2023-01-01 to 2023-01-31,
        name=jan,
        day list downward,
        month label above left,
        xshift=15cm,
      ]
      if (weekend) [gray];
\end{tikzpicture}
\end{document}

它看起来像:

样本

PS:之所以这么长xshift是因为我将通过引用日历中的特定节点来为日期添加注释。例如:

\node [anchor=base west] at (cal-2022-01-01.base east) {Foo};

答案1

不断day list downward地将坐标系向下移动,为了回到顶部,您需要将坐标系移回顶部(这可以通过数学方式完成,需要代码找出一个月的最后一天或使用顶部的坐标)。

我相信,我们自己实现起来更容易,day list downward months horizontal style每天的日常转换都是在本地进行的(而不是像样式那样在全球范围内day list downward进行的)。每个月的第一天,month xshift(存储在中的\tikz@lib@cal@month@xshift)长度都会向右移动 - 但对于日历的第一个月则不会,只有当您的图片中不仅仅有日历时才会注意到。

对于逐日转换(day yshift将存储在中\tikz@lib@cal@yshift),我们需要1从月份的日期中减去(或调整样式month label above left)。代码

\if0\pgfcalendarcurrentday\else\pgfcalendarcurrentday\fi

吞噬前导(→ 、→ 、…、→等) 0,以便可以在 PGFMath 中使用。(前导零被解释为八进制数。)\pgfcalendarcurrentday0110221010

代码

\documentclass[margin=2mm, tikz]{standalone}
\usetikzlibrary{calendar}
\makeatletter
\tikzset{
  day list downward months horizontal/.style={
    tikz@lib@cal@width=1,
    execute at begin day scope={
      \pgftransformyshift{
        -(\if0\pgfcalendarcurrentday\else\pgfcalendarcurrentday\fi - 1)
        *(\tikz@lib@cal@yshift)}
    },
    execute before day scope={
      \ifdate{day of month=1}{
        \ifdate{equals=\pgfcalendarbeginiso}{}{
          \pgftransformxshift{\tikz@lib@cal@month@xshift}
        }
      }{}
    }
  }
}
\makeatother
\begin{document}
\begin{tikzpicture}
  \calendar[
        dates=2022-10-01 to 2023-01-31,
        day list downward months horizontal,
        month label above left,
        month xshift=5cm,
        month text={\%mt \%y0}
      ]
      if (weekend) [gray];
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案2

我们可以使用“日期列表左侧”,然后将其旋转为垂直。

\centering
\begin{tikzpicture}[every month/.style={rotate=-90, font=\ttfamily\bfseries, color=green!50!black}, % month label style
        every day/.append style={anchor=mid}]
    \foreach \x in {1,...,12}
    \calendar[rotate=-90, % rotate -90deg
        yshift=2 * \x em,
        dates=\year-\x-1 to \year-\x-last,
% set month text to short name
        month text = \pgfcalendarmonthshortname{\pgfcalendarcurrentmonth},
% circle today
        execute at begin day scope={\ifdate{equals=\year-\month-\day}{\node[draw=red!80, circle, radius=8pt, fill=red!50] at (0,0){};}{}
% put the year number on top and adjust position
                    \ifdate{equals=6-01}{\node[font=\Huge\ttfamily, color=green!50!red, yshift=3cm] at (0,0){\pgfcalendarcurrentyear};}{}
            },
        month label left,
        day list right]
    if(workday)[green!30!red]
    if(weekend)[green!50!black];
\end{tikzpicture}

在此处输入图片描述

相关内容