和matrix

和matrix

根据主题答案带有 tikz 的日历我尝试将日期名称翻译成德语。但是,不知为何,对齐效果不太好。我该如何解决这个问题?

截屏

Enter image description here

平均能量损失

\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};
    ...
}

calendar

带有左对齐日期标签的完整代码:

\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)。

2-letter weekdays

3-letter weekdays

设置时仍需要进行一些轻微的手动调整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}

输出

enter image description here

相关内容