大家好,伟大的 TeX 人 :)
我正在尝试创建一个时间线
但侧面标有月份,并且线条与日期相连。
我一直在尝试修改chronology
包装,但是“年份”指示太过深入。
我一直在尝试使用 TikZ,但不幸的是,我真的无法产生任何接近所需输出的东西。
您将如何解决这个问题?如果尝试解决同样的问题,您将如何构建您的代码?
答案1
这是我的解决方案。首先,您通过 指定条目\timeentry{time}{description}
,然后通过 绘制时间线\drawtimeline
。它会自动缩放到您的时间条目的高度。在 的行之间=====
有一些参数可用于影响外观(间距等)。您还可以更改命令以使用颜色、细/粗线和其他内容:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}
\newdimen\XCoord
\newdimen\YCoord
\newcommand*{\ExtractCoordinate}[1]{\path (#1); \pgfgetlastxy{\XCoord}{\YCoord};}%
\begin{document}
% ============================= modify these for altered appearence
\pgfmathsetmacro{\mintime}{0}
\pgfmathsetmacro{\maxtime}{15}
\newcommand{\timeunit}{Months}
\pgfmathtruncatemacro{\timeintervals}{15}
\pgfmathsetmacro{\scaleitemseparation}{4}
\pgfmathsetmacro{\timenodewidth}{2cm}
\newcounter{itemnumber}
\setcounter{itemnumber}{0}
\newcommand{\lastnode}{n-0}
% =============================
\newcommand{\timeentry}[2]{% time, description
\stepcounter{itemnumber}
\node[below right,minimum width=\timenodewidth, text width=\timenodewidth-1mm] (n-\theitemnumber) at (\lastnode.south west) {#1};
\node[right] at (n-\theitemnumber.east) {#2};
\edef\lastnode{n-\theitemnumber}
\expandafter\edef\csname nodetime\theitemnumber \endcsname{#1}
}
\newcommand{\drawtimeline}{%
\draw[very thick,-latex] (0,0) -- ($(\lastnode.south west)-(\scaleitemseparation,0)+(0,-1)$);
\ExtractCoordinate{n-\theitemnumber.south}
\pgfmathsetmacro{\yposition}{\YCoord/28.452755}
\foreach \x in {1,...,\theitemnumber}
{ \pgfmathsetmacro{\timeposition}{\yposition/(\maxtime-\mintime)*\csname nodetime\x \endcsname}
%\node[right] at (0,\timeposition) {\yposition};
\draw (0,\timeposition) -- (0.5,\timeposition) -- ($(n-\x.west)-(0.5,0)$) -- (n-\x.west);
}
\foreach \x in {0,...,\timeintervals}
{ \pgfmathsetmacro{\labelposition}{\yposition/(\maxtime-\mintime)*\x}
\node[left] (label-\x) at (-0.2,\labelposition) {\x\ \timeunit};
\draw (label-\x.east) -- ++ (0.2,0);
}
}
\begin{tikzpicture}
\node[inner sep=0] (n-0) at (\scaleitemseparation,0) {};
\timeentry{1}{The first entry.}
\timeentry{1.2}{The second entry.}
\timeentry{1.23456}{The third entry.}
\timeentry{3}{Entry number \theitemnumber}
\timeentry{5}{Entry number \theitemnumber}
\timeentry{5.1}{Entry number \theitemnumber}
\timeentry{5.2}{Entry number \theitemnumber}
\timeentry{5.3}{Entry number \theitemnumber}
\timeentry{5.4}{Entry number \theitemnumber}
\timeentry{5.5}{Entry number \theitemnumber}
\timeentry{5.6}{Entry number \theitemnumber}
\timeentry{6}{Entry number \theitemnumber}
\timeentry{7}{Entry number \theitemnumber}
\timeentry{8}{Entry number \theitemnumber}
\timeentry{9}{Entry number \theitemnumber}
\timeentry{10}{Entry number \theitemnumber}
\timeentry{11}{Entry number \theitemnumber}
\timeentry{11.1}{Entry number \theitemnumber}
\timeentry{11.2}{Entry number \theitemnumber}
\timeentry{11.3}{Entry number \theitemnumber}
\timeentry{11.5}{Entry number \theitemnumber}
\timeentry{11.7}{Entry number \theitemnumber}
\timeentry{11.9}{Entry number \theitemnumber}
\timeentry{13}{Entry number \theitemnumber}
\timeentry{15}{Entry number \theitemnumber}
\drawtimeline
\end{tikzpicture}
\end{document}
答案2
这是一个半自动解决方案:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,calc,calendar}
\newcommand{\ts}{\textunderscore}
\begin{document}
\begin{tikzpicture}
\foreach \x[count=\xi from 4] in {1,...,5} {
\node[anchor=north,text width=2cm,align=center,font={\tiny\sffamily}] (time\x) at (0,-\x cm) {\pgfcalendarmonthname{\xi} 2012};}
\matrix (m) at (2,-1) [
anchor=north west,
matrix of nodes,
nodes={font=\sffamily\tiny,inner sep=0},
row sep=1pt,
column sep=2mm,
column 2/.style={text width=9cm,align=left}
]{
0.00000 &entering nautilus-main.c:main()\\
0.00222 &nautilus-main.c calling gnome\ts program\ts init()\\
0.16386 &nautilus\ts application\ts instance\ts init() calling signal\ts connect\ts on\ts gnome\ts vfs\ts get\ts volume\ts monitor\\
1.16386 &nautilus\ts application\ts instance\ts init() finished signal\ts connect\ts on\ts gnome\ts vfs\ts get\ts volume\ts monitor\\
1.16386 &nautilus\ts application\ts instance\ts init() had enough of calling signal\ts connect\ts on\ts gnome\ts vfs\ts get\ts volume\ts monitor\\
2.56386 &nautilus\ts application\ts instance\ts init() enjoying the idle\ts CPU\ts time\\
2.57386 &nautilus\ts application\ts instance\ts init() enjoying the idle\ts CPU\ts time\\
2.58386 &nautilus\ts application\ts instance\ts init() enjoying the idle\ts CPU\ts time\\
2.59386 &nautilus\ts application\ts instance\ts init() enjoying the idle\ts CPU\ts time\\
};
\foreach \x in {4,5} {\draw (m-\x-1.west) --++(-2mm,0) -- ([xshift=5mm]$(time1)!0.2!(time2)$) --++(-5mm,0);}
\foreach \x in {6,...,9} {\draw (m-\x-1.west) --++(-2mm,0) -- ([xshift=5mm]$(time2)!0.5!(time3)$) --++(-5mm,0);}
\end{tikzpicture}
\end{document}
基本上,我们只是在左侧向下绘制一个月列表,没有太多自动化。然后,我们还在它旁边放了一个矩阵。然后剩下的部分是绘制连接,其中有多少与特定日期节点相关也是手动定义的。您可以进一步修改以满足您的需求。
答案3
我真的很喜欢这个解决方案汤姆·邦巴迪尔,但想
\timeentry
添加一个开关来决定是否显示时间位置(命令的第一个参数)- 增加输出的高度-它非常扁平
- 允许一个文档中有多个时间线(具有不同的设置)
因此,我修改了汤姆的解决方案:
\documentclass{article}
%TIMELINE START
\usepackage{tikz,ifthen}
\usetikzlibrary{calc,arrows}
\newboolean{displaytimeposition}
\newcounter{itemnumber}
\providecommand{\lastnode}{n-0}
\newdimen\XCoord
\newdimen\YCoord
\newcommand*{\ExtractCoordinate}[1]{\path (#1); \pgfgetlastxy{\XCoord}{\YCoord};}%
\newcommand{\timeentry}[2]{% time, description
\stepcounter{itemnumber}
\node[below right,minimum width=\timenodewidth, text width=\timenodewidth-1mm] (n-\theitemnumber) at (\lastnode.south west) {\ifthenelse{\boolean{displaytimeposition}}{#1}{#2}};
\ifdisplaytimeposition
\node[right] at (n-\theitemnumber.east) {#2};
\fi
\edef\lastnode{n-\theitemnumber}
\expandafter\edef\csname nodetime\theitemnumber \endcsname{#1}
}
\newcommand{\drawtimeline}{%
\ExtractCoordinate{n-\theitemnumber.south}
\pgfmathsetmacro{\yposition}{\YCoord/\timelineScaleY}
\foreach \x in {1,...,\theitemnumber}
{ \pgfmathsetmacro{\timeposition}{\yposition/(\maxtime-\mintime)*\csname nodetime\x \endcsname}
%\node[right] at (0,\timeposition) {\yposition};
\draw (0,\timeposition) -- (0.5,\timeposition) -- ($(n-\x.west)-(0.5,0)$) -- (n-\x.west);
}
\foreach \x in {0,...,\timeintervals}
{ \pgfmathsetmacro{\labelposition}{\yposition/(\maxtime-\mintime)*\x}
\node[left] (label-\x) at (-0.2,\labelposition) {\x\ \timeunit};
\draw (label-\x.east) -- ++ (0.2,0);
}
\pgfmathsetmacro{\arrowend}{\yposition/(\maxtime-\mintime)*(\maxtime+1)}
\draw[very thick,-latex] (0,0) -- (0, \arrowend);
}
%TIMELINE END
\begin{document}
Timeline 1:
% ============================= modify these for altered appearance
\setboolean{displaytimeposition}{false}
\pgfmathsetmacro{\mintime}{1}
\pgfmathsetmacro{\maxtime}{6}
\providecommand{\timeunit}{Months}
\pgfmathtruncatemacro{\timeintervals}{6}
\pgfmathsetmacro{\scaleitemseparation}{2}
\pgfmathsetmacro{\timenodewidth}{12cm}
\providecommand{\timelineScaleY}{15} % lower numbers = larger height of timeline
\setcounter{itemnumber}{0}
% =============================
\begin{tikzpicture}
\node[inner sep=0] (n-0) at (\scaleitemseparation,0) {};
\timeentry{0}{Start: Kickoff Meeting}
\timeentry{0.5}{2 Weeks: Milestone 1}
\timeentry{3}{3 Month: Milestone 2}
\timeentry{3.5}{3.5 Month: Milestone 3}
\timeentry{6}{6 Month: Milestone 4}
\drawtimeline
\end{tikzpicture}
\end{document}
Timeline 2:
% ============================= modify these for altered appearance
\setboolean{displaytimeposition}{true}
\pgfmathsetmacro{\mintime}{1}
\pgfmathsetmacro{\maxtime}{12}
\providecommand{\timeunit}{Months}
\pgfmathtruncatemacro{\timeintervals}{12}
\pgfmathsetmacro{\scaleitemseparation}{2}
\pgfmathsetmacro{\timenodewidth}{2cm}
\providecommand{\timelineScaleY}{30} % lower numbers = larger height of timeline
\setcounter{itemnumber}{0}
% =============================
\begin{tikzpicture}
\node[inner sep=0] (n-0) at (\scaleitemseparation,0) {};
\timeentry{0}{Entry \theitemnumber}
\timeentry{2.5}{Entry \theitemnumber}
\timeentry{8}{Entry \theitemnumber}
\timeentry{10}{Entry \theitemnumber}
\timeentry{12}{Entry \theitemnumber}
\drawtimeline
\end{tikzpicture}
\end{document}