我想在 Tikz 中绘制一个内存布局图,如下所示: 请注意,原始文件是 SVG 文件,转换为 PNG 会导致奇怪的 [查看器不支持] 错误,不确定那是怎么回事。
无论如何,我怎样才能在 Tikz 中重新创建该图表,但没有编号阶段,并且各部分从最左边开始?
我尝试修改这个答案使其接近发布的图像,但是我对 Tikz 的了解不够多,无法使其完全达到那里。
答案1
像这样:
这是使用蒂克兹但为了隐藏技术细节,我定义了一个宏\MemoryLayout
,它接受以逗号分隔的 x 坐标/颜色/标签列表,以便上面的图像由以下方式生成:
\MemoryLayout{
12/blue!10/A,
21/orange!20/B,
30/red!30/C,
39/yellow!30/D,
48/green!30/E,
62/white/\relax
}
\relax
当您不想被贴标签时,请使用标签。
此宏所做的就是循环遍历输入数据,使用标准 tikz 命令绘制图片。以下是完整代码:
\documentclass[tikz, border=5mm]{standalone}
\usetikzlibrary{decorations.pathreplacing}
\newcommand\MemoryLayout[1]{
\begin{tikzpicture}[scale=0.3]
\draw[thick](0,0)--++(0,3)node[above]{$0$};
\foreach \pt/\col/\lab [remember=\pt as \tp (initially 0)] in {#1} {
\foreach \a in {\tp,...,\pt-1} {
\draw[fill=\col](-\a,0) rectangle ++(-1,2);
}
\draw[thick](-\pt,0)--++(0,3)node[above]{$\pt$};
\if\lab\relax\relax\else
\draw[thick,decorate, decoration={brace,amplitude=4mm}]
(-\tp,-0.2)--node[below=4mm]{\lab} (-\pt,-0.2);
\fi
}
\end{tikzpicture}
}
\begin{document}
\MemoryLayout{
12/blue!10/A,
21/orange!20/B,
30/red!30/C,
39/yellow!30/D,
48/green!30/E,
62/white/\relax
}
\end{document}
要删除数字,只需注释掉这两个\draw[thick]...;
命令。
答案2
xcolor
只是为了好玩,只使用(括号下方的标签中的amstext
for )实现。该命令采用以下参数:\text
\memory
\memory[<width>]{<num>}[<height>]{<color>}[<label>]
<width>
:是单个单元格的宽度
<height>
:是单元格的高度
<color>
:是单元格使用的颜色,它可以包含一个可选参数和一个强制参数,或者只包含转发给的强制参数\textcolor
,因此和{[gray]{.85}}
都是{white!85!black}
有效的。
<label>
:打印在括号下方的文本,如果省略,则不会绘制括号。
边框的粗细是 的当前值\fboxrule
,规则不会增加单元格的大小。要绘制多个内存块,只需将多个\memory
实例放在一起,确保中间没有空格。 的大小<label>
可能会产生空白,您必须注意这一点。
\documentclass[]{article}
\usepackage{amstext}
\usepackage{xcolor}
\makeatletter
\begingroup
\lccode`\A=`\-
\lccode`\N=`\N
\lccode`\V=`\V
\lowercase{\endgroup\def\memory@noval{ANoValue-}}
\long\def\memory@fiBgb\fi#1#2{\fi}
\long\def\memory@fiTBb\fi#1#2#3{\fi#2}
\newcommand\memory@ifnovalF[1]%>>=
{%
\ifx\memory@noval#1%
\memory@fiBgb
\fi
\@firstofone
}%=<<
\newcommand\memory@ifnovalTF[1]%>>=
{%
\ifx\memory@noval#1%
\memory@fiTBb
\fi
\@secondoftwo
}%=<<
\newcommand\memory@Oarg[2]%>>=
{%
\@ifnextchar[{\memory@Oarg@{#2}}{#2{#1}}%
}%=<<
\long\def\memory@Oarg@#1[#2]%>>=
{%
#1{#2}%
}%=<<
\newcommand*\memory@oarg%>>=
{%
\memory@Oarg\memory@noval
}%=<<
\newcommand*\memory@ifcoloropt%>>=
{%
\@ifnextchar[\memory@ifcoloropt@true\memory@ifcoloropt@false
}%=<<
\long\def\memory@ifcoloropt@true#1\memory@noval#2#3%>>=
{%
#2%
}%=<<
\long\def\memory@ifcoloropt@false#1\memory@noval#2#3%>>=
{%
#3%
}%=<<
\newlength\memory@width
\newlength\memory@height
\setlength\memory@width{7pt}
\setlength\memory@height{10pt}
\newcount\memory@num
\newcommand*\memory@blocks[2]%>>=
{%
\memory@num#1\relax
\fboxsep-\fboxrule
\memory@ifcoloropt#2\memory@noval
{\def\memory@color{\textcolor#2}}
{\def\memory@color{\textcolor{#2}}}%
\loop
\ifnum\memory@num>0
\fbox{\memory@color{\rule{\memory@width}{\memory@height}}}%
\kern-\fboxrule
\advance\memory@num\m@ne
\repeat
}%=<<
% memory:
% [#1]: width
% #2 : count
% [#3]: height
% #4 : colour
% [#5]: label
\newcommand*\memory%>>=
{%
\begingroup
\memory@oarg\memory@a
}%=<<
\newcommand*\memory@a[2]%>>=
{%
% #1 width
% #2 count
\memory@ifnovalF{#1}{\memory@width#1\relax}%
\memory@Oarg\memory@height{\memory@b{#2}}%
}%=<<
\newcommand*\memory@b[3]%>>=
{%
% #1 count
% #2 height
% #3 colour
\memory@ifnovalF{#2}{\memory@height#2\relax}%
\memory@oarg{\memory@c{#1}{#3}}%
}%=<<
\newcommand*\memory@c[3]%>>=
{%
% #1 count
% #2 colour
% #3 label
\memory@ifnovalTF{#3}
{\ensuremath{\memory@blocks{#1}{#2}}}
{\ensuremath{\underbrace{\memory@blocks{#1}{#2}}_{\text{#3}}}}%
\endgroup
}%=<<
\makeatother
\begin{document}
\memory{8}{orange}%
\memory{8}{green}[{\makebox[0pt]{[Not supported by viewer]}}]%
\memory{8}{yellow}%
\end{document}
% vim: fdm=marker fmr=>>=,=<<
答案3
这项任务的 tikz 替代方案是使用表格。提供此示例以防将来可能对某人有所帮助,因为我过去曾得到过帮助。我找不到创建下划线的简单方法,但通过着色或多列框可以实现相同的效果。额外的行只是为了显示定义它们是多么简单。
我发现使用表格通常可以帮助我说明我的意图和设计,而不必在每个步骤上都寻求帮助。下面的文档看起来很乏味,因为我没有使用任何循环,但我通常没有那么多元素,有时会使用一行 Python 或文本编辑器来创建 LaTex 内容。格式化命令看起来不言自明,易于修改,无需花时间寻找文档。
\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{geometry}
\geometry{letterpaper, portrait, margin=.5in}
\usepackage{graphicx}
\begin{document}
\newcommand{\shadeblue}{\cellcolor{blue!20}}
\newcommand{\shadeorange}{\cellcolor{orange!20}}
\newcommand{\shadered}{\cellcolor{red!30}}
\newcommand{\shadeyellow}{\cellcolor{yellow!30}}\newcommand{\shadegreen}{\cellcolor{green!30}}
% Column separation, default is 6pt
\setlength{\tabcolsep}{2pt}
\begin{table}
\resizebox{\textwidth}{!}{ % Resize to fit in the margins.
\begin{tabular}{|*{62}{c|}}
\hline
\multicolumn{14}{|c|}{61 ... 49} &
\multicolumn{9}{c|}{48 ... 39} &
\multicolumn{9}{c|}{38 ... 30} &
\multicolumn{9}{c|}{29 ... 21} &
\multicolumn{9}{c|}{20 ... 12} &
\multicolumn{12}{c|}{11 ... 0} \\
\hline
& & & & & & & & & & & & & &
& & & & & & & & &
& & & & & & & & &
& & & & & & & & &
& & & & & & & & &
& & & & & & & & & & & \\
\hline
61 & 60 & 59 & 58 & 57 & 56 & 55 & 54 & 53 & 52 & 51 & 50 & 49 &
48 & 47 & 46 & 45 & 44 & 43 & 42 & 41 & 40 & 39 &
38 & 37 & 36 & 35 & 34 & 33 & 32 & 31 & 30 &
29 & 28 & 27 & 26 & 25 & 24 & 23 & 22 & 21 &
20 & 19 & 18 & 17 & 16 & 15 & 14 & 13 & 12 &
11 & 10 & 9 & 8 & 7 & 6 & 5 & 4 & 3 & 2 & 1 & 0 \\
\hline
61 & 60 & 59 & 58 & 57 & 56 & 55 & 54 & 53 & 52 & 51 & 50 & 49 & 48 &
\shadegreen 47 & \shadegreen 46 & \shadegreen 45 &
\shadegreen 44 & \shadegreen 43 & \shadegreen 42 &
\shadegreen 41 & \shadegreen 40 & \shadegreen 39 &
\shadeyellow 38 & \shadeyellow 37 & \shadeyellow 36 &
\shadeyellow 35 & \shadeyellow 34 & \shadeyellow 3 &
\shadeyellow 32 & \shadeyellow 31 & \shadeyellow 30 &
\shadered 29 & \shadered 28 & \shadered 27 &
\shadered 26 & \shadered 25 & \shadered 24 &
\shadered 23 & \shadered 22 & \shadered 21 &
\shadeorange 20 & \shadeorange 19 & \shadeorange 18 &
\shadeorange 17 & \shadeorange 16 & \shadeorange 15 &
\shadeorange 14 & \shadeorange 13 & \shadeorange 12 &
\shadeblue 11 & \shadeblue 10 & \shadeblue 9 &
\shadeblue 8 & \shadeblue 7 & \shadeblue 6 &
\shadeblue 5 & \shadeblue 4 & \shadeblue 3 &
\shadeblue 2 & \shadeblue 1 & \shadeblue 0 \\
\hline
\multicolumn{14}{c}{ } &
\multicolumn{9}{c}{ \shadegreen } &
\multicolumn{9}{c}{ \shadeyellow } &
\multicolumn{9}{c}{ \shadered } &
\multicolumn{9}{c}{ \shadeorange } &
\multicolumn{12}{c}{ \shadeblue } \\
\multicolumn{14}{c}{ } &
\multicolumn{9}{c}{ \shadegreen E } &
\multicolumn{9}{c}{ \shadeyellow D } &
\multicolumn{9}{c}{ \shadered C } &
\multicolumn{9}{c}{ \shadeorange B } &
\multicolumn{12}{c}{ \shadeblue A } \\
\multicolumn{14}{c}{ } &
\multicolumn{9}{c}{ E } &
\multicolumn{9}{c}{ D } &
\multicolumn{9}{c}{ C } &
\multicolumn{9}{c}{ B } &
\multicolumn{12}{c}{ A } \\
\end{tabular}
}
\end{table}
\end{document}