更新答案

更新答案

我想向pgfgantt包中添加一个命令,该命令在指定日期绘制垂直线(例如今天的线)。以下是我想要得到的(绿线):

在此处输入图片描述

因此我查看了pgfgantt.sty今天的线是如何绘制的,并将这段代码添加到pgfgantt.sty文件中:

\newcommand\drawverticalline[1]{%
 \begingroup%
  \begin{pgfinterruptboundingbox}%
   \begin{scope}
    \gtt@tsstojulian{#2}{\gtt@today@slot}
    \gtt@juliantotimeslot{\gtt@today@slot}{\gtt@today@slot}%
     \pgfmathsetmacro\x@mid{%
       (\gtt@today@slot - 1 + \ganttvalueof{today offset})%
                  * \ganttvalueof{x unit}%
     }%
     \draw [/pgfgantt/today rule]
                (\x@mid pt, \y@upper pt) -- (\x@mid pt, \y@lower pt)
                node [/pgfgantt/today label node] {\ganttvalueof{today label}};%
     \end{scope}
    \end{pgfinterruptboundingbox}%
    \endgroup%
}  

现在通常我可以使用这样的命令:\drawverticalline{2014-05-07}但是当我执行此操作时出现此错误:

! Package PGF Math Error: Unknown function `pt' (in 'pt').

错误来自此代码:

\pgfmathsetmacro\x@mid{%
       (\gtt@today@slot - 1 + \ganttvalueof{today offset})%
                  * \ganttvalueof{x unit}%
     }%

它上面没有pt。所以我决定注释掉它并\x@mid用常量 (5) 替换它,但现在我得到了这个错误:

! Undefined control sequence.

为什么我会收到此错误?该命令已定义!

pgfgantt以下是绘制今天线的代码:

\def\@tempa{none}%
\edef\@tempb{\ganttvalueof{today}}%
\ifx\@tempa\@tempb\else%
  \pgfmathsetmacro\x@mid{%
    (\gtt@today@slot - 1 + \ganttvalueof{today offset})%
    * \ganttvalueof{x unit}%
  }%
  \draw [/pgfgantt/today rule]
    (\x@mid pt, \y@upper pt) -- (\x@mid pt, \y@lower pt)
    node [/pgfgantt/today label node] {\ganttvalueof{today label}};%
\fi%  

平均能量损失

\documentclass{article}
\usepackage[frenchb]{babel}  
\usepackage{pgfgantt}
\usetikzlibrary{shadows}

\begin{document}
\begin{tikzpicture} % optional
   \begin{ganttchart}[x unit=1.8mm, 
                  y unit chart=0.87cm, 
                  time slot format=isodate, 
                  vgrid=*{5}{dotted},
                 ]
                  {2014-04-14}{2014-07-11}
       \gantttitlecalendar{month=name} \\ 

       \ganttbar[progress=100]{title1}{2014-04-14}{2014-04-15} \\

       \ganttbar[progress=100]{title2}{2014-04-15}{2014-04-17} \\

       \drawverticalline{2014-05-07}
   \end{ganttchart}
\end{tikzpicture}
\end{document}

答案1

更新答案

多年后,为了回应 tdgunes 对这个答案的评论,我联系了该软件包的作者,询问这个问题,我很高兴地说,他从 2018 年 1 月 11 日发布到 CTAN 的 v5.0 版本开始,将这个功能添加到了软件包中!

本节中的代码展示了如何使用包中实现的功能。我还在下面保留了原始答案,因为我觉得它在解释必要时修改分布式包的最佳实践方面很有价值。

软件包作者添加了一个\ganttvrule宏,使用方式如下:

\ganttvrule[<options>]{<label-text>}{<time-slot-spec>}

可选参数可以包含样式选项。可用选项在包装手册

此宏仍必须使用甘特图的所有行均已定义。

\documentclass{standalone}
\usepackage{pgfgantt}

\begin{document}
\begin{tikzpicture}
\begin{ganttchart}[
  time slot format=isodate, 
  vgrid=*{5}{dotted},
  today={2014-04-14},
]{2014-04-14}{2014-05-11}
  \gantttitlecalendar{month=name} \\ 
  \ganttbar[progress=100]{title1}{2014-04-14}{2014-04-15} \\
  %\ganttvrule{Fail!}{2014-04-24} % must be placed at the end of the ganttchart environment
  \ganttbar[progress=100]{title2}{2014-04-15}{2014-04-17} \\
  \ganttbar[progress=50]{testing}{2014-04-17}{2014-04-18}
  \ganttvrule{Test 1}{2014-05-07}
  \ganttvrule{Test 2}{2014-04-30}
  \ganttvrule{Test 3}{2014-05-10}
  \ganttvrule{Success}{2014-04-24} % works at the very end
  \ganttset{vrule/.append style={blue}} % change the style
  \ganttvrule{Blue!}{2014-04-28} % check for changed style
    \ganttvrule[vrule/.append style={red, ultra thick}]{Red!}{2014-05-03} % alternate styling method
\end{ganttchart}
\end{tikzpicture}
\end{document}

在此处输入图片描述


原始答案(已被pgfganttv5.0 取代,发布于 2018-01-11)

正如评论中多次提到的那样,直接修改由某些包管理系统(无论是tlmgr、MikTeX 包管理器,还是任何其他系统上的包管理器,[RPM、、pacmannpm])控制的任何文件是一种非常糟糕的想法.™ 除了许可问题之外,即使包管理器没有感到困惑,任何修改将要更新后会丢失,使用这些修改的文档将要被打破。

正确的做法是使用您自己的本地自定义扩展包。我在这里说明了一种方法:

  1. 创建您自己的包pgfgantt-custompgfgantt-custom.sty),加载 TeX 发行版的当前pgfgantt包并从那里添加/修改命令。
  2. 将此文件放在texmf-localLaTeX 可以找到的位置*。

* 参考我应该将自己的.sty文件放在哪里才能使它们可供我的所有.tex文件使用?了解每个主要 TeX 发行版的此过程的完整细节。

因此,请pgfgantt-custom.sty使用以下内容进行创建:

\ProvidesPackage{pgfgantt-custom}[2015/01/10 My local customizations to the pgfgantt package] % name, date, and description of the package
\RequirePackage{pgfgantt} % load the package we're modifying

% some new keys for the style of our "anyday" marker lines
\@gtt@keydef{anyday}{none}
\@gtt@keydef{anyday offset}{1}
\@gtt@stylekeydef{anyday rule}{dashed, line width=1pt}
\@gtt@keydef{anyday label font}{\normalfont}
\@gtt@stylekeydef{anyday label node}{%
  anchor=north, font=\ganttvalueof{anyday label font}%
}

\newcount\gtt@anyday@slot

\newcommand\drawverticalline[2]{%
  \gtt@tsstojulian{#1}{\gtt@anyday@slot}%
  \gtt@juliantotimeslot{\gtt@anyday@slot}{\gtt@anyday@slot}%
  \pgfmathsetmacro\y@upper{%
    \gtt@lasttitleline * \ganttvalueof{y unit title}%
  }%
  \pgfmathsetmacro\y@lower{%
    \gtt@lasttitleline * \ganttvalueof{y unit title}%
      + (\gtt@currentline - \gtt@lasttitleline - 1)%
      * \ganttvalueof{y unit chart}%
  }%
  \pgfmathsetmacro\x@mid{%
    (\gtt@anyday@slot - 1 + \ganttvalueof{anyday offset})%
      * \ganttvalueof{x unit}%
  }%
  \draw [/pgfgantt/anyday rule]
    (\x@mid pt, \y@upper pt) -- (\x@mid pt, \y@lower pt)
    node [/pgfgantt/anyday label node] {#2};%
}

代码细目如下:


\@gtt@keydef/\@gtt@stylekeydef命令:

我创建了一些类似于今日标记样式选项的键,因此如果需要,可以独立于今日标记样式进行更改。默认值与今日标记样式相同。


\newcount\gtt@anyday@slot

这定义了计数器,其中根据pgfgantt内部宏来操作标记的日期以处理不同的日期格式。


现在,主要事件:\drawverticalline接受 2 个参数;第一个是标记的日期,第二个是标记文本(可能为空)。

定义的前两行只是以与 相同的方式处理日期today。现在到了您遇到麻烦的部分。您无法访问\y@upper\y@lower和 ,\x@mid因为它们是在单独的范围内定义的。所以我们必须在这个新命令的范围内重新定义它们。

这样做的副作用是,我们不知道甘特图中是否还有更多行需要绘制(标记today由 内部最后绘制pgfgantt),并且无法将命令推迟到环境末尾。因此,必须在环境末尾(绘制完所有 s 之后)ganttchart使用我们的新宏。\drawverticallineganttchart\ganttbar

剩下的就是绘制标记,用适当的样式键替换,节点文本作为#2第二个参数。

使用示例

\documentclass{standalone}
\usepackage{pgfgantt-custom}

\begin{document}
\begin{tikzpicture}
\begin{ganttchart}[
  time slot format=isodate, 
  vgrid=*{5}{dotted},
  today={2014-04-14},
]{2014-04-14}{2014-05-11}
  \gantttitlecalendar{month=name} \\ 
  \ganttbar[progress=100]{title1}{2014-04-14}{2014-04-15} \\
  %\drawverticalline{2014-04-24}{Fail} must be placed at the end of the ganttchart environment
  \ganttbar[progress=100]{title2}{2014-04-15}{2014-04-17} \\
  \ganttbar[progress=50]{testing}{2014-04-17}{2014-04-18}
  \drawverticalline{2014-05-07}{Test 1}
  \drawverticalline{2014-04-30}{Test 2}
  \drawverticalline{2014-05-10}{Test 3}
  \drawverticalline{2014-04-24}{Success} % works at the very end
  \ganttset{anyday rule/.append style={blue}} % change the style
  \drawverticalline{2014-04-28}{Blue!} % check for changed style
\end{ganttchart}
\end{tikzpicture}
\end{document}

输出:

在此处输入图片描述

您可以取消注释该\drawverticalline{2014-04-24}{Fail}行以查看当我们尚不知道甘特图中的总行数时会发生什么。

相关内容