
Пытаюсь рисовать диаграммы изПроблемные рамкибумага.
Как мне создать эти границы слева и добавить дополнительные поля в правом углу с меткой. Можно ли также добавить дополнительную линию с обеих сторон?
Вот как это должно выглядеть:
Вот где я застрял:
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,arrows,shapes.geometric,positioning}
\tikzset{element/.style={
draw,
thick,
node distance=1.5cm,
minimum width=1.5cm,
minimum height=1cm
},
desinedDomain/.style={element},
machine/.style={element},
requirement/.style={element,circle,dotted}
}
\begin{document}
\begin{figure}[htbp]
\centering
\begin{tikzpicture}
\node (m) [machine] {machine};
\node (d1) [desinedDomain, above right=of m] {domain1};
\node (d2) [element, below right=of m] {domain2};
\node (r1) [requirement, below right=of d1] {domain3};
\draw (m) -- (d1) node[midway,left] {a};
\draw (m) -- (d2) node[midway,above] {b};
\draw[dashed,->] (r1) -- (d1) node[midway,below] {c};
\draw[dashed,->] (r1) -- (d2) node[midway,above] {d};
\end{tikzpicture}
\caption{Problem Frames}
\label{fig:pf}
\end{figure}
\end{document}
решение1
Другое, более сложное и отличающееся (по сравнению с моим первым ответом, именно поэтому я решил дать новый ответ) решение.
В этом решении "подэлементы" определяются как внутренние метки в узле "элемент". Они могут быть произвольно расположены внутри узла, аналогично тому, как стандартные метки могут быть расположены снаружи узла, с той разницей, что они прикреплены к внутренней стороне якорей узла. Для проектирования узла "машина" я использую multipart
узел и возможность включения содержимого узла между другими параметрами узла.
Следовательно, код изображения заметно более лаконичен по сравнению с первым решением. Полная версия MWE теперь выглядит так:
\documentclass[border=3mm,tikz]{standalone}
\usetikzlibrary{positioning,shapes.multipart}
\makeatletter
\def\tikzsavelastnodename#1{\let#1=\tikz@last@fig@name}
\makeatother
\tikzset{%
node distance=0mm and 15mm,
element/.style={%
draw, thick,
minimum size=11mm, inner xsep=5mm,
append after command={\pgfextra{\tikzsavelastnodename\tikzsavednodename}},#1
},
subelement/.style args={#1:#2}{%
append after command =
{node[draw,thick,minimum size=3mm,
inner sep=2pt] at (\tikzsavednodename.#1) [anchor=#1] {#2}}
},
machine/.style={%
shape=rectangle split, rectangle split horizontal,
rectangle split parts=3,
rectangle split empty part width=-3mm,
draw, thick,
minimum height=11mm, inner sep=2mm, outer sep=0mm,
node contents={\nodepart{three}\ #1\ }
},
requirement/.style={%
element, inner sep=2mm, circle, dotted}
}% end of tikzset
\begin{document}
\begin{tikzpicture}
\node (m) [machine=machine];
\node (d1) [element,
subelement=south east:C,
above right=of m] {domain1};
\node (d2) [element,
subelement=south east:B,
below right=of m] {domain2};
\node (r1) [requirement,
below right=of d1] {domain3};
%
\draw (m) -- node[above] {a} (d1)
(m) -- node[above] {b} (d2);
\draw[dashed,->] (r1) -- node[above] {c} (d1);
\draw[dashed,->] (r1) -- node[above] {d} (d2);
\end{tikzpicture}
\end{document}
Полученная картина аналогична той, что в моем первом ответе:
Редактировать:Сегодня я заметил, что дважды загрузил свой MWE. Поэтому я удаляю излишки MWE и немного (надеюсь) улучшаю его описание.
решение2
Простое решение — добавить два небольших узла, размещенных внутри узлов «domain1» и «domain2»:
Для рисунка выше я определяю subelement
стиль для маленьких узлов. Кроме того, я перехожу node distance
к общему параметру в tikzset
, немного изменяю его (чтобы результат был больше похож на вставленное изображение в вопросе), для всех узлов с прямоугольной формой использую стиль element
. И это:
Редактировать:ups, я забыл об одном из подвопросов. Теперь он добавлен. Для линий на левой стороне узла "машина" я определяю новый стиль machine
и добавляю два этих узла на узел "машина" левого размера.
\documentclass[border=3mm,tikz]{standalone}
\usetikzlibrary{calc,arrows,shapes.geometric,positioning}
\tikzset{%
node distance=3mm and 15mm,
element/.style={
draw,
thick,
minimum width=1.7cm,
minimum height=1cm
},
machine/.style={
element,
minimum width=0cm, outer sep=0pt,
subelement/.style={
draw,
thick,
inner sep= 1pt,
minimum size=3mm,
},
requirement/.style={element,circle,dotted}
}% end of tikzset
\begin{document}
\begin{tikzpicture}
\node (m) [element] {machine};
\node (d1) [element,above right=of m] {domain1};
\node[subelement,above left] at (d1.south east) {C};
\node (d2) [element,below right=of m] {domain2};
\node[subelement,above left] at (d2.south east) {B};
\node (r1) [requirement, below right=of d1] {domain3};
%
\draw (m) -- node[above] {a} (d1)
(m) -- node[above] {b} (d2);
\draw[dashed,->] (r1) -- node[above] {c} (d1);
\draw[dashed,->] (r1) -- node[above] {d} (d2);
\end{tikzpicture}
\end{document}
решение3
Для линий можно использовать \pgfextra
и рисовать линии с помощью якорей узла. Для метки можно использовать метку как аргумент для стиля.
Выход
Код
\documentclass[tikz]{standalone}
\usetikzlibrary{calc,arrows,shapes.geometric,positioning}
\tikzset{
element/.style={
draw,
thick,
node distance=1.5cm,
minimum width=1.5cm,
minimum height=1cm
},
desinedDomain/.style={element,
label={[draw, anchor=south east, thick, inner sep=0, minimum size=3mm, shift={(\tikzlastnode.south east)}]#1}
},
machine/.style={element,append after command={\pgfextra{
\draw[thick] (\tikzlastnode.south west)++(0,.5\pgflinewidth) --++ (-1mm,0) |- ($(\tikzlastnode.north west)+(0,-.5\pgflinewidth)$);
\draw[thick] (\tikzlastnode.south west)++(0,.5\pgflinewidth) --++ (-2mm,0) |- ($(\tikzlastnode.north west)+(0,-.5\pgflinewidth)$);
}}},
requirement/.style={element,circle,dotted}
}
\begin{document}
\begin{tikzpicture}
\node (m) [machine] {machine};
\node (d1) [desinedDomain=c, above right=of m] {domain1};
\node (d2) [element, below right=of m] {domain2};
\node (r1) [requirement, below right=of d1] {domain3};
\draw (m) -- (d1) node[midway,left] {a};
\draw (m) -- (d2) node[midway,above] {b};
\draw[dashed,->] (r1) -- (d1) node[midway,below] {c};
\draw[dashed,->] (r1) -- (d2) node[midway,above] {d};
\end{tikzpicture}
\end{document}