Зависимый размер узла в TikZ

Зависимый размер узла в TikZ

Я создаю некоторые листы потока теории управления, в 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:

  1. Тип: Текстовое поле.

    Перед построением узла измеряется и сравнивается размер текстового поля, содержащего текст узла ( \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};
    

    что приводит к следующему результату:

    введите описание изображения здесь

  2. Тип: Минимальная высота и минимальная ширина.

    В отличие от измерений текстового поля, здесь используются высота и ширина фигуры, которые вычисляются самой декларацией фигуры. Поскольку этот расчет выполняется где-то глубоко внутри декларации фигуры, необходимы новые декларации фигур: 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}

Выход

Первая компиляция

введите описание изображения здесь

Вторая компиляция

введите описание изображения здесь

Вывод (примеры)

введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь

Связанный контент