Tikzpicture 中的单元格宽度由于文本宽度而产生错误

Tikzpicture 中的单元格宽度由于文本宽度而产生错误

我有以下代码。

% DIN-A4 doublesided year calendar
% Author: Robert Krause
% License : Creative Commons attribution license
% Submitted to TeXample.net on 13 July 2012
\documentclass[landscape,a4paper, ngerman, 10pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz}           % Use the calendar.sty style

\usepackage{translator} % German Month and Day names
\usepackage{fancyhdr}       % header and footer
\usepackage{fix-cm}     % Large year in header

\usepackage[landscape, headheight = 2cm, margin=.5cm,
  top = 3.2cm, nofoot]{geometry}
\usetikzlibrary{calc}
\usetikzlibrary{calendar}
%%%<
\usepackage{verbatim}
\usepackage[tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
%%%>


\renewcommand*\familydefault{\sfdefault}

% User defined
\def\year{2013}
% Names of Holidays are inserted by employing this macro
\def\termin#1#2{
  \node [anchor=north west, text width= 3.4cm] at
    ($(cal-#1.north west)+(3.0em, 0em)$) {\tiny{#2}};
}

%Header
\renewcommand{\headrulewidth}{0.0pt}
\setlength{\headheight}{7ex}
\chead{
  \fontsize{35}{45}\selectfont\textbf{Kalendar \year Sachsen-Anhalt}\hfill
}
\rhead{
    \fontsize{20}{30}\selectfont\textbf{Kalendar\textit{pedia\\}}
    \Large\textbf{Ferienkalender}
}
%Footer
\cfoot{\footnotesize\texttt{http://www.texample.net/}}



\begin{document}
\pagestyle{fancy}
\begin{center}
\begin{tikzpicture}[every day/.style={anchor = north}]
\calendar[
  dates=\year-01-01 to \year-12-31,
  name=cal,
  day yshift = 3.0em,
  day code=
  {
    % print days name
    \node[name=\pgfcalendarsuggestedname,every day,shape=rectangle,
    minimum width=1.8cm, minimum height= .53cm, text width = 2.4cm, draw = black]{\tikzdaytext};
    \draw (-1.8, -.1ex) node[anchor = west]{\footnotesize%
    \pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}};
  },
  execute before day scope=
  {
    \ifdate{day of month=1}
    {
      % Shift right
      \pgftransformxshift{2.4cm}
      % Print month name
      \draw (-1,0) node [shape=rectangle, minimum height= .53cm, minimum width= 1.8cm,
        text width = 2.4cm, fill = white, text= black, draw = black, text centered]
        {\textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth}}};
    }{}
    \ifdate{workday}
    {
      % normal days are white
      \tikzset{every day/.style={fill=white}}
      % Vacation (Germany, Baden-Wuerrtemberg) gray background
      \ifdate{between=2012-12-24 and 2013-01-05}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-03-25 and 2013-04-05}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-05-21 and 2013-06-01}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-07-25 and 2013-09-07}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-10-28 and 2013-10-30}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-12-23 and 2014-01-04}{%
        \tikzset{every day/.style={fill=gray!30}}}{ddd}
    }{}
    % Saturdays and half holidays (Christma's and New year's eve)
    \ifdate{Saturday}{\tikzset{every day/.style={fill=yellow!10}}}{asd}
    \ifdate{equals=12-24}{\tikzset{every day/.style={fill=red!10}}}{}
    \ifdate{equals=12-31}{\tikzset{every day/.style={fill=red!10}}}{}
    % Sundays and full holidays
    \ifdate{Sunday}{\tikzset{every day/.style={fill=green!20}}}{}
    \ifdate{equals=01-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=01-06}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=05-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=10-03}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=11-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=12-25}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=12-26}{\tikzset{every day/.style={fill=red!20}}}{}
    % Christian holidays
    \ifdate{equals=2013-03-29}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-04-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-05-09}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-05-20}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-05-30}{\tikzset{every day/.style={fill=red!20}}}{}
  },
 execute at begin day scope=
  {
    % each day is shifted down according to the day of month
    \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
  }
];
% names of days....






% Print name of Holidays
\termin{\year-01-01}{Neujahr}
\termin{\year-01-06}{Heilige Drei Könige}
\termin{2013-03-29}{Karfreitag}
\termin{2013-03-31}{Ostersonntag}
\termin{2013-04-01}{Ostermontag}
\termin{\year-05-01}{Tag der Arbeit}
\termin{2013-05-09}{Christi Himmelfahrt}
\termin{2013-05-19}{Pfingstsonntag}
\termin{2013-05-20}{Pfingstmontag}
\termin{2013-05-30}{Fronleichnam}
\end{tikzpicture}
\end{center}
\end{document} 

它给了我以下输出。 有错误的图像

但是,我需要以下带有调整列和文本的输出。

在此处输入图片描述

答案1

下面的代码似乎有效。

在此处输入图片描述

我还没有看过 Texample 上的原始代码做了什么,但有一些关键点:

  • 我没有使用两个不同的节点来表示日期编号和日期名称,而是将它们放在同一个节点中,节点文本定义为

    \rlap{\tikzdaytext}\hspace{1em} {\footnotesize\pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}}
    

    意思\rlap\tikzdaytext放置在一个宽度为零的框中,框的内容 ( \tikzdaytext) 从右侧伸出框。在其后留出 1em 的水平空间 (\hspace ),这样可以使星期名称对齐。

  • 对于月节点和日节点,使用相同的text widthminimum width无关紧要,所以我删除了它。关于节点宽度需要注意两点:

    • 节点的总宽度取决于inner sep节点的宽度,即节点内容到边框的距离(默认值为 0.333em)以及内容的宽度。例如,text width=2cm内容宽度为 2cm,因此总宽度为 2cm + 2*0.333em。
    • 在 A4 纸上留出一点空间来打印 12 个月,意味着节点的总宽度不能超过 2.2 厘米,所以text width必须小于这个值。
  • 负责将每个月向右移动的代码是\pgftransformxshift{<some length>}。根据上面的讨论,必须将其设置为\pgftransformxshift{<the value used for text width>+0.666em}

  • 我修改了\termin宏。我没有使用 将节点放置在日期节点左上角右侧一定距离的位置,而是anchor=north west使用 将节点放置在右上角anchor=north east。我还减少了text width以避免重叠。

  • 要在日历后面添加一个灰色框,您可以例如添加\usetikzlibrary{fit, backgrounds}到序言中,然后添加

    \scoped[on background layer]
      \node [draw, gray, fit=(current bounding box), inner sep=2pt] {};
    

    就在之前\end{tikzpicture}就在所有日历内容

    定义inner sep日历和盒子边缘之间的空间。


% DIN-A4 doublesided year calendar
% Author: Robert Krause
% License : Creative Commons attribution license
% Submitted to TeXample.net on 13 July 2012
\documentclass[landscape,a4paper, ngerman, 10pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz}           % Use the calendar.sty style

\usepackage{translator} % German Month and Day names
\usepackage{fancyhdr}       % header and footer
\usepackage{fix-cm}     % Large year in header

\usepackage[landscape, headheight = 2cm, margin=.5cm,
  top = 3.2cm, nofoot]{geometry}
\usetikzlibrary{calc}
\usetikzlibrary{calendar}
\usetikzlibrary{fit}
\usetikzlibrary{backgrounds}
%%%<
\usepackage{verbatim}
\usepackage[tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
%%%>


\renewcommand*\familydefault{\sfdefault}

% User defined
\def\year{2013}
% Names of Holidays are inserted by employing this macro
\def\termin#1#2{%
\node [anchor=north east, text width=1.5cm,font=\tiny,align=right] at (cal-#1.north east) {#2};
}

%Header
\renewcommand{\headrulewidth}{0.0pt}
\setlength{\headheight}{7ex}
\chead{
  \fontsize{35}{45}\selectfont\textbf{Kalendar \year Sachsen-Anhalt}\hfill
}
\rhead{
    \fontsize{20}{30}\selectfont\textbf{Kalendar\textit{pedia\\}}
    \Large\textbf{Ferienkalender}
}
%Footer
\cfoot{\footnotesize\texttt{http://www.texample.net/}}



\begin{document}
\pagestyle{fancy}
\begin{center}
\begin{tikzpicture}[every day/.style={anchor = north}]
\calendar[
  dates=\year-01-01 to \year-12-31,
  name=cal,
  day yshift = 3.0em,
  day code=
  {
    % print days name
    \node[
      name=\pgfcalendarsuggestedname,
      every day,
      minimum height=.53cm,
      text width = 2.1cm,
      draw = black,
      yshift=-1.5pt] 
       {\rlap{\tikzdaytext}\hspace{1em} {\footnotesize\pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}}};
  },
  execute before day scope=
  {
    \ifdate{day of month=1}
    {
      % Shift right
      \pgftransformxshift{2.1cm+0.666em} % 0.666 = 2 * default inner sep of nodes
      % Print month name
      \node [
          minimum height=.53cm,
          text width = 2.1cm,
          fill = white,
          draw = black,
          text centered
        ]
        {\strut\textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth}}};
    }{}
    \ifdate{workday}
    {
      % normal days are white
      \tikzset{every day/.style={fill=white}}
      % Vacation (Germany, Baden-Wuerrtemberg) gray background
      \ifdate{between=2012-12-24 and 2013-01-05}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-03-25 and 2013-04-05}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-05-21 and 2013-06-01}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-07-25 and 2013-09-07}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-10-28 and 2013-10-30}{%
        \tikzset{every day/.style={fill=gray!30}}}{}
      \ifdate{between=2013-12-23 and 2014-01-04}{%
        \tikzset{every day/.style={fill=gray!30}}}{ddd}
    }{}
    % Saturdays and half holidays (Christma's and New year's eve)
    \ifdate{Saturday}{\tikzset{every day/.style={fill=yellow!10}}}{asd}
    \ifdate{equals=12-24}{\tikzset{every day/.style={fill=red!10}}}{}
    \ifdate{equals=12-31}{\tikzset{every day/.style={fill=red!10}}}{}
    % Sundays and full holidays
    \ifdate{Sunday}{\tikzset{every day/.style={fill=green!20}}}{}
    \ifdate{equals=01-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=01-06}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=05-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=10-03}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=11-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=12-25}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=12-26}{\tikzset{every day/.style={fill=red!20}}}{}
    % Christian holidays
    \ifdate{equals=2013-03-29}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-04-01}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-05-09}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-05-20}{\tikzset{every day/.style={fill=red!20}}}{}
    \ifdate{equals=2013-05-30}{\tikzset{every day/.style={fill=red!20}}}{}
  },
 execute at begin day scope=
  {
    % each day is shifted down according to the day of month
    \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
  }
];
% names of days....


% Print name of Holidays
\termin{\year-01-01}{Neujahr}
\termin{\year-01-06}{Heilige Drei Könige}
\termin{2013-03-29}{Karfreitag}
\termin{2013-03-31}{Ostersonntag}
\termin{2013-04-01}{Ostermontag}
\termin{\year-05-01}{Tag der Arbeit}
\termin{2013-05-09}{Christi Himmelfahrt}
\termin{2013-05-19}{Pfingstsonntag}
\termin{2013-05-20}{Pfingstmontag}
\termin{2013-05-30}{Fronleichnam}


\scoped[on background layer]
\node [fit=(current bounding box), % means the node just fits around everything in the tikzpicture
       draw, % draw outline
       fill, % and fill
       gray, % with this colour
%       inner sep=-0.5\pgflinewidth % and with this amount of space between frame and content
       % with -0.5\pgflinewidth the framn will overlap with the edges of the vells
       % if you want a gap, use some positive value, e.g.
       inner sep=2pt
] {};

\end{tikzpicture}
\end{center}
\end{document} 

相关内容