Я создаю некоторые листы потока теории управления, в TikZ
которых я указал размер узла. Поскольку я создаю много таких листов потока, я установил для них глобальные стили, например, тот box
стиль, который я сейчас использую:
box/.style={rectangle, draw, minimum width = 8ex,
minimum height = 4ex, inner sep = 1ex}
Количество текста в узлах варьируется. Проблема в том, что если текст узла требует больше места, чем minimum
, остальные узлы на этой картинке должны сохранять тот же размер, что и самый большой узел. Как это сделать? Решение вэтот вопросэтого я хотел бы избежать, так как, по моему мнению, это слишком «ручное» занятие, мне нужна автоматизация.
MWE:
\documentclass[12pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
box/.style={rectangle, draw, minimum width = 8ex,
minimum height = 4ex, inner sep = 0},
split/.style={circle, draw, minimum size = 2.5pt, fill=black,
inner sep = 0},
}
\begin{document}
\begin{tikzpicture}[
every path/.style={>={stealth}, ->, draw, node distance = 1pt, inner sep = 0pt},
]
\node[split] (split) {};
\node[box] (I) at ($(split) + (4,0)$) {Short};
\node[box] (P) at ($(I)+(0,1)$) {This node has long node text};
\node[box] (D) at ($(I)+(0,-1)$) {Short};
\draw (split.north) |-(P);
\draw (split.east) -- (I) ;
\draw (split.south) |-(D);
\end{tikzpicture}
\end{document}
решение1
Этот ответбыл преобразован в собственную библиотеку TikZ ext.node-families
как часть моегоtikz-ext
пакет расширений.
Я думаю, это почти так же автоматически, как и возможно. Он использует файл .aux
и не будет работать, когда изображение экспортируется с помощьюexternal
библиотека.
Вы указываете семейство узлов, которые должны иметь одинаковое измерение со следующими ключами, которые все находятся в пространстве имен /tikz/node family
:
Тип: Текстовое поле.
Перед построением узла измеряется и сравнивается размер текстового поля, содержащего текст узла (
\pgfnodeparttextbox
). Используется наибольшее значение.text height=<name>
: Узлы с одинаковыми значениями будут иметь одинаковую высоту текста.<name>
text depth=<name>
: Узлы с одинаковыми значениями будут иметь одинаковую глубину текста.<name>
text width=<name>
: Узлы с одинаковыми параметрами будут иметь одинаковую ширину текста.<name>
text width align = left|center|right
:Установка ширины текстового поля только расширяет поле вправо. Содержимое поля необходимо выровнять заново. Ключ
text width align
(по умолчаниюcenter
) гарантирует, что это будет сделано правильно.text=<name>
устанавливает всеtext height
иtext depth
кtext width
тому же .<name>
По умолчанию это установлено только для базовых фигур
rectangle
иcircle
. После того, как другая фигура объявлена (обычно путем загрузки одной изshapes.*
библиотек), ее можно настроить таким же образом, используя\tikzset{node family/setup shape=<shape name>}
Это следует делать только один раз для каждой формы.
Поскольку это изменяет только размеры текстового поля, для разных фигур в одном семействе это может привести к разной ширине или высоте фигуры, поскольку их размеры рассчитываются по-разному в зависимости от размера текстового поля. Рассмотрим этот пример:
\tikz[nodes=draw, node family/text width=test] \node {Foo} node[circle] {Barbarbar};
что приводит к следующему результату:
Тип: Минимальная высота и минимальная ширина.
В отличие от измерений текстового поля, здесь используются высота и ширина фигуры, которые вычисляются самой декларацией фигуры. Поскольку этот расчет выполняется где-то глубоко внутри декларации фигуры, необходимы новые декларации фигур:
Circle
иRectangle
.width=<name>
: Узлы с одинаковыми параметрами будут иметь одинаковую ширину.<name>
height=<name>
: Узлы с одинаковыми значениями будут иметь одинаковую высоту.<name>
Как и в случае с
/pgf/minimum width
и/pgf/minimum height
, здесь игнорируются любые значения/pgf/outer xsep
и/pgf/outer ysep
или сама ширина линии.
Установка пустого значения отключит действия этой библиотеки.<name>
Внутри файла запись .aux
происходит в конце изображения, которое обозначается \tikz@atend@picture
( execute at end picture
).
Ключ prefix
определяет prefix
для всех семейств узлов. По умолчанию это \pgfpictureid-
, это делает так, что семейства узлов применяются только к TikZpictures индивидуально.
В приведенном ниже примере все семьи названы, test
но все они разные.
Я также использовал positioning
библиотеку, которая делает эффект более заметным.
Код все еще может быть немного оптимизирован, так как для примера ниже семь дополнительных макросов определены файлом .aux
. Может быть, лучше сохранить все значения из одного семейства в одном макросе?
Код
\documentclass[12pt,tikz]{standalone}
\usetikzlibrary{
positioning, % better positioning (right=of …)
ext.node-families, % node families
arrows.meta % arrow tips
}
\begin{document}
\begin{tikzpicture}[
node distance=.3cm and 1cm,
box/.style={
rectangle, draw, minimum width=+8ex, minimum height=+4ex, inner sep=+0pt,
node family/text width=test},
split/.style={
circle, draw, minimum size=+2.5pt, fill=black, inner sep=+0pt}]
\node[split] (split) {};
\node[box, right=of split] (I) {Short};
\node[box, above=of I] (P) {This node has long node text};
\node[box, below=of I] (D) {Short};
\draw[-Stealth] (split.north) |-(P);
\draw[-Stealth] (split.east) -- (I) ;
\draw[-Stealth] (split.south) |-(D);
\end{tikzpicture}
\tikz % only the same height (text is still centered)
\foreach \cnt[count=\Cnt] in {a,...,h}
\node[draw, Circle, node family/height=test] at (right:\Cnt) {\cnt};
\tikz % height and text height (text depth set to zero)
\foreach \cnt[count=\Cnt] in {a,...,h}
\node[draw, Circle, text depth=+0pt,
node family={height=test, text height=test}]
at (right:\Cnt) {\cnt};
\begin{tikzpicture}[% http://tex.stackexchange.com/q/134983
nodes={circle, draw=black, node family/text=test}]
\node (A) {$n$};
\node[right=0pt of A] (B) {$n+1$};
\end{tikzpicture}
\end{document}
Выход
Первая компиляция
Вторая компиляция
Вывод (примеры)