改进 TikZ 用户界面

改进 TikZ 用户界面

我希望改进概念以及用于生成代码的用户界面视觉进度图。该图表示高层建筑建设的活动和进度。白色方块表示活动尚未开始,绿色方块表示活动已完成,红色方块表示由于某种原因受到限制而无法完成的活动。

活动地图

用户界面如下:

\floor{Level 47}{0}{0}{0}{0}{2}
\floor{Level 46}{0}{0}{0}{2}{2}
...
\floor{Level 08}{0}{0}{1}{1}{1}

这是高度重复的,但由于进展必须按楼层报告,我想不出任何更简单的方法,并欢迎替代解决方案(0 =白色,1 =完成,2 =受限)。

MWE 如下所示:

\documentclass[a4paper, oneside, justified=true, sfsidenotes]{tufte-book} % for a 
\usepackage[utf8]{inputenc} % set input encoding to utf8
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{pgfplots}

%% Define some colors
\definecolor{activity1}{rgb}{0,1.0,0}
\definecolor{activity2}{rgb}{0,0.9,0}
\definecolor{activity3}{rgb}{0,0.85,0}
\definecolor{activity4}{rgb}{0,0.75,0}
\definecolor{activity5}{rgb}{0,0.65,0}

%% Color helper routine
\def\getcolor#1#2{%
\def\zero{0}\def\one{1}\def\two{2}
  \if\zero#1 \gdef\statuscolor{white} \else \gdef\statuscolor{#2}\fi
  \if\two#1  \gdef\statuscolor{red} \fi
}

\gdef\ascale{0.8}

\gdef\floor#1#2#3#4#5#6{%
  \centering
  \parindent0pt
  \tikzpicture[scale=\ascale]
    \def\posx{0.6}
    \getcolor{#2}{activity1}
    \draw node [anchor=south east ]{#1};
    \draw[fill=\statuscolor] (0,0) rectangle (0.5,0.5); 
    \getcolor{#3}{activity2}
    \draw[fill=\statuscolor] (\posx,0.0) rectangle (1.1,0.5);
    \getcolor{#4}{activity3}  
    \draw[fill=\statuscolor] (2*\posx,0.0) rectangle (1.7,0.5);
    \getcolor{#5}{activity4}
    \draw[fill=\statuscolor] (3*\posx,0.0) rectangle (2.3,0.5);
    \getcolor{#6}{activity5}
    \draw[fill=\statuscolor] (4*\posx,0.0) rectangle (2.9,0.5);
  \endtikzpicture
}


\begin{document}
\input{planning}
\end{document}

输入文档为:

\chapter{Planning}
\begin{marginfigure}
The Tower can be represented by a series of squares, which denote an activity. Green
is done and white is not done. There is no need to use intermediate colors as they 
would add to the visual clutter.

\vspace{1cm}
\floor{Level 47}{0}{0}{0}{0}{2}
\floor{Level 46}{0}{0}{0}{2}{2}
\floor{Level 45}{0}{0}{1}{1}{1}
\floor{Level 44}{0}{0}{1}{1}{1}
\floor{Level 43}{1}{1}{1}{1}{1}
\floor{Level 42}{1}{1}{1}{1}{1}
\floor{Level 41}{0}{1}{1}{0}{1}
\floor{Level 40}{0}{1}{1}{1}{1}
\floor{Level 39}{0}{1}{1}{1}{1}
\floor{Level 38}{0}{1}{1}{1}{1}
\floor{Level 37}{0}{0}{1}{1}{1}
\floor{Level 36}{0}{0}{0}{1}{1}
\floor{Level 35}{0}{0}{0}{1}{1}
\floor{Level 34}{0}{0}{0}{1}{1}
\floor{Level 33}{0}{0}{0}{1}{1}
\floor{Level 32}{0}{0}{0}{1}{1}
\floor{Level 31}{0}{0}{0}{1}{1}
\floor{Level 30}{0}{0}{0}{1}{1}
\floor{Level 29}{1}{1}{1}{1}{1}
\floor{Level 28}{1}{1}{1}{1}{1}
\floor{Level 27}{0}{1}{1}{1}{1}
\floor{Level 26}{0}{1}{1}{1}{1}
\floor{Level 25}{0}{0}{1}{1}{1}
\floor{Level 24}{0}{0}{1}{1}{1}
\floor{Level 23}{0}{0}{1}{1}{1}
\floor{Level 22}{0}{0}{1}{1}{1}
\floor{Level 21}{0}{0}{1}{1}{1}
\floor{Level 20}{0}{0}{1}{1}{1}
\floor{Level 19}{0}{0}{1}{1}{1}
\floor{Level 18}{0}{0}{1}{1}{1}
\floor{Level 17}{0}{0}{1}{1}{1}
\floor{Level 16}{0}{0}{1}{1}{1}
\floor{Level 15}{0}{1}{1}{1}{1}
\floor{Level 14}{0}{1}{1}{1}{1}
\floor{Level 12}{0}{1}{1}{1}{1}
\floor{Level 11}{0}{1}{1}{1}{1}
\floor{Level 10}{1}{1}{1}{1}{1}
\floor{Level 09}{1}{1}{1}{1}{1}
\floor{Level 08}{1}{1}{1}{1}{1}
\caption{Shangri-la Tower Progress, each square represents one separate activity.}
\end{marginfigure}
\lipsum[1-3]

总而言之,用户界面有没有更好的替代方案?您会建议对地面路线进行哪些更改?您建议将图例放置在何处以及如何放置?

答案1

这是我的建议。在 floor 位的开头,将 TeX 变成一个解析器。然后每行都是一个空格分隔的 0、1、2 列表,这些列表会变成 floor 语法。在每行的开头,我们看看是否应该停止解析,否则我们假设下一行是一个新的楼层。由于楼层是从上到下指定的,所以我们必须在一开始就知道楼层数(尽管我们可以将其保存在辅助文件中并在下次运行时恢复它)。否则,语法似乎更干净一些,因此不容易出错。但是,这不会进行任何错误检查。一种方法是使换行符处于活动状态并将其用作楼层之间的分隔符。

这是代码(我将输入文件包含到主文档中)。

\documentclass[a4paper, oneside, justified=true, sfsidenotes]{tufte-book} % for a 
\usepackage[utf8]{inputenc} % set input encoding to utf8
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{pgfplots}

%% Define some colors
\definecolor{activity1}{rgb}{0,1.0,0}
\definecolor{activity2}{rgb}{0,0.9,0}
\definecolor{activity3}{rgb}{0,0.85,0}
\definecolor{activity4}{rgb}{0,0.75,0}
\definecolor{activity5}{rgb}{0,0.65,0}

%% Color helper routine
\def\getcolor#1#2{%
\def\zero{0}\def\one{1}\def\two{2}
  \if\zero#1 \gdef\statuscolor{white} \else \gdef\statuscolor{#2}\fi
  \if\two#1  \gdef\statuscolor{red} \fi
}

\gdef\ascale{0.8}
\def\posx{0.6}
\def\posy{0.5}

\newcounter{floor}
\newcommand{\NumberOfFloors}[1]{\def\MaxFloors{#1}\setcounter{floor}{#1}}

\makeatletter
\def\isfloor{%
  \@ifnextchar\stopfloors{}{\floor}}
\makeatother

\gdef\floor#1 #2 #3 #4 #5 {%
\pgfmathsetmacro{\yshift}{-\posy * (\MaxFloors - \value{floor})}
    \getcolor{#1}{activity1}
    \node[anchor=south east] at (0,\yshift) {Level \thefloor};
    \draw[fill=\statuscolor] (0,\yshift) rectangle +(0.5,0.5); 
    \getcolor{#2}{activity2}
    \draw[fill=\statuscolor] (\posx,\yshift) rectangle +(0.5,0.5);
    \getcolor{#3}{activity3}  
    \draw[fill=\statuscolor] (2*\posx,\yshift) rectangle +(0.5,0.5);
    \getcolor{#4}{activity4}
    \draw[fill=\statuscolor] (3*\posx,\yshift) rectangle +(0.5,0.5);
    \getcolor{#5}{activity5}
    \draw[fill=\statuscolor] (4*\posx,\yshift) rectangle +(0.5,0.5);
\addtocounter{floor}{-1}
\isfloor}

\let\startfloors=\floor
\let\stopfloors=\relax


\begin{document}
\chapter{Planning}
\begin{marginfigure}
The Tower can be represented by a series of squares, which denote an activity. Green
is done and white is not done. There is no need to use intermediate colors as they 
would add to the visual clutter.

\NumberOfFloors{47}
\begin{tikzpicture}
\startfloors
0  0  0  0  2
0  0  0  2  2
0  0  1  1  1
0  0  1  1  1
1  1  1  1  1
1  1  1  1  1
0  1  1  0  1
0  1  1  1  1
0  1  1  1  1
0  1  1  1  1
0  0  1  1  1
0  0  0  1  1
0  0  0  1  1
0  0  0  1  1
0  0  0  1  1
0  0  0  1  1
0  0  0  1  1
0  0  0  1  1
1  1  1  1  1
1  1  1  1  1
0  1  1  1  1
0  1  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  0  1  1  1
0  1  1  1  1
0  1  1  1  1
0  1  1  1  1
0  1  1  1  1
1  1  1  1  1
1  1  1  1  1
1  1  1  1  1
\stopfloors
\end{tikzpicture}
\caption{Shangri-la Tower Progress, each square represents one separate activity.}
\end{marginfigure}
\lipsum[1-3]
\end{document}

输出与您发布的内容非常相似,但稍微不那么紧凑。这可能是由于我在某处引入了一些间距问题。这显然可以进行调整。

塔

答案2

我有一个不同的建议。您可以定义三个宏,例如\undone\finished\constrained,每个宏都接受两个参数:楼层数和任务数,并将该楼层和该任务的标志设置为 0、1 或 2。您只需将所有内容初始化为“未完成”,然后当第 15 层的 sat 任务 3 完成后,将其放在\finished{15}{3}列表的末尾。然后 TeX 会负责按楼层组织信息。

如果您在输入信息时添加了日期(也许作为注释),那么您还将获得完整的进度日志。

可以按照以下方式进行:

\documentclass[a4paper, oneside, justified=true, sfsidenotes]{tufte-book}
\usepackage[utf8]{inputenc} % set input encoding to utf8
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{pgfplots}

%% The commands to enter information:
\newcommand\undone[2]{\expandafter\def\csname Floor#1Task#2\endcsname{0}}
\newcommand\finished[2]{\expandafter\def\csname Floor#1Task#2\endcsname{1}}
\newcommand\constrained[2]{\expandafter\def\csname Floor#1Task#2\endcsname{2}}

\newcommand\initfloor[1]{%
\undone{#1}{1}%
\undone{#1}{2}%
\undone{#1}{3}%
\undone{#1}{4}%
\undone{#1}{5}%
}

%% Define some colors
\definecolor{activity1}{rgb}{0,1.0,0}
\definecolor{activity2}{rgb}{0,0.9,0}
\definecolor{activity3}{rgb}{0,0.85,0}
\definecolor{activity4}{rgb}{0,0.75,0}
\definecolor{activity5}{rgb}{0,0.65,0}

%% Color helper routine
\def\getcolor#1#2{%
\def\zero{0}\def\one{1}\def\two{2}
  \if\zero#1 \gdef\statuscolor{white} \else \gdef\statuscolor{#2}\fi
  \if\two#1  \gdef\statuscolor{red} \fi
}

\gdef\ascale{0.8}

\gdef\floor#1{%
  \centering
  \parindent0pt
  \tikzpicture[scale=\ascale]
    \def\posx{0.6}
    \getcolor{\csname Floor#1Task1\endcsname}{activity1}
    \draw node [anchor=south east ]{\hbox to 5em{\hfil #1}};
    \draw[fill=\statuscolor] (0,0) rectangle (0.5,0.5); 
    \getcolor{\csname Floor#1Task2\endcsname}{activity2}
    \draw[fill=\statuscolor] (\posx,0.0) rectangle (1.1,0.5);
    \getcolor{\csname Floor#1Task3\endcsname}{activity3}  
    \draw[fill=\statuscolor] (2*\posx,0.0) rectangle (1.7,0.5);
    \getcolor{\csname Floor#1Task4\endcsname}{activity4}
    \draw[fill=\statuscolor] (3*\posx,0.0) rectangle (2.3,0.5);
    \getcolor{\csname Floor#1Task5\endcsname}{activity5}
    \draw[fill=\statuscolor] (4*\posx,0.0) rectangle (2.9,0.5);
  \endtikzpicture
}

\initfloor{1}
\initfloor{2}
\initfloor{third}

%% This could be in a separate file:
\finished{2}{3}
\finished{third}{5}
\constrained{1}{1}
%%

\begin{document}
\chapter{Planning}

\begin{marginfigure}
The Tower can be represented by a series of squares, which denote an activity. Green
is done and white is not done. There is no need to use intermediate colors as they 
would add to the visual clutter.

\vspace{1cm}
\floor{third}
\floor{2}
\floor{1}
\end{marginfigure}
\lipsum[1-3]

\end{document}

相关内容