
Я хочу нарисовать что-то вроде следующего (фотошопного) рендеринга:
Это изображение состоит из трех \node
s, каждое из которых использует свою границу. Все это закреплено на chain
, потому что в моей реальной ситуации я создаю что-то вродеСинтаксическая диаграмма в учебнике TikZ (стр. 60).
Сейчас у меня есть MWE, который \node
также отображает границы между буквами L, C и R, но я хочу, чтобы они исчезли, не изменяя «внешние» границы.
Мой реальный код:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{chains,scopes,shapes.misc}
\begin{document}
\begin{tikzpicture}[start chain,
node distance=5mm,
every node/.style={on chain},
connect/.style={join=by ->},
point/.style={coordinate},
l/.style={draw, fill=cyan!50, rounded rectangle, rounded rectangle right arc=0},
c/.style={draw, fill=green!50},
r/.style={draw, fill=orange!50, rounded rectangle, rounded rectangle left arc=0},
cozy/.style={node distance=-\pgflinewidth}]
\node[point] (p1) {};
\node [l, connect] (l) {L};
{[cozy]
\node [c] (c) {C};
\node [r] (r) {R};
}
\node[point, connect] (p2) {};
\end{tikzpicture}
\end{document}
Пользовательские границы (пересмотренные)
Я следовалэтот пример,@Хариш Кумар'sотвечать, иэтот ответ. Я пробовал рисовать границы вручную, используя немного разные подходы для каждой части моей фигуры. У всех из них есть свои недостатки:
- применяется в L:Если оставить
\node
'sline width
по умолчанию (\pgflinewidth
),draw=none
то будет\node
содержать окружающее пространство шириной0.5*\pgflinewidth
. Чтобы нарисовать границу в пределах\node
размеров ' , граница не должна выходить за пределы этого пространства. К сожалению, часть внутренней части границы рисуется за заполнителем, из-за чего она выглядит слишком тонкой. Кроме того, восточные опорные точки теперь выглядят так, как будто они немного смещены. - применяется в C:Установка
\node
'sline width=0
по крайней мере гарантирует, что все опорные точки (особенно восточная и западная) находятся в правильном месте. Однако, таким образом, вся граница рисуется позади заполнителя. - применяется в R:установка
\node
'sline width=0
и рисование границыснаружизаполнителя. Это приводит к тому, что граница выходит за пределы\node
размеров , что приводит к ее перекрытию с соединяющимися объектами.
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,chains,scopes,shapes.misc,backgrounds}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfdeclarelayer{foreforeground}
\pgfsetlayers{background,main,foreground,foreforeground}
\begin{document}
\begin{tikzpicture}[start chain,
node distance=5mm,
every node/.style={on chain},
connect/.style={join=by ->},
point/.style={coordinate},
l/.style={line width=\pgflinewidth, fill=cyan!50, rounded rectangle, rounded rectangle right arc=0, append after command={% <= for the border
\pgfextra{\begin{pgfinterruptpath}\begin{pgfonlayer}{foreground}
\draw[] let \p1=($(\tikzlastnode.north east)+(-0.5\pgflinewidth,-0.5\pgflinewidth)$),
\p2=($(\tikzlastnode.north west)+(0,-0.5\pgflinewidth)$),
\p3=($(\tikzlastnode.south west)+(0,0.5\pgflinewidth)$),
\p4=($(\tikzlastnode.south east)+(-0.5\pgflinewidth,0.5\pgflinewidth)$),
\n1={0.5*(\y2-\y3)} in
(\p1) -- (\p2) arc(90:270:\n1) -- (\p4);
\end{pgfonlayer}\end{pgfinterruptpath}}
}},
c/.style={line width=0, fill=green!50, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}\begin{pgfonlayer}{foreground}
\draw[] let \p1=($(\tikzlastnode.north east)+(0,-0.5\pgflinewidth)$),
\p2=($(\tikzlastnode.north west)+(0,-0.5\pgflinewidth)$),
\p3=($(\tikzlastnode.south west)+(0,0.5\pgflinewidth)$),
\p4=($(\tikzlastnode.south east)+(0,0.5\pgflinewidth)$) in
(\p1) -- (\p2) (\p3) -- (\p4);
\end{pgfonlayer}\end{pgfinterruptpath}
}
}},
r/.style={line width=0, fill=orange!50, rounded rectangle, rounded rectangle left arc=0, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}
\draw[] let \p1=($(\tikzlastnode.north east)+(0,0.5\pgflinewidth)$),
\p2=($(\tikzlastnode.north west)+(0,0.5\pgflinewidth)$),
\p3=($(\tikzlastnode.south west)+(0,-0.5\pgflinewidth)$),
\p4=($(\tikzlastnode.south east)+(0,-0.5\pgflinewidth)$),
\n1={0.5*(\y1-\y4)} in
(\p3) -- (\p4) arc(-90:90:\n1) -- (\p2);
\end{pgfinterruptpath}
}
}}
]
\node[point] (p1) {};
\node [l, connect] (l) {L};
{[node distance=-0.5\pgflinewidth]
\node [c] (c) {C};}
{[node distance=0]
\node [r] (r) {R};}
\node[point, connect] (p2) {};
\node[font=\tiny, cyan, below=of l] (lbl l-se) {l.se};
\draw[red,->] (lbl l-se) -- (l.south east);
\begin{pgfonlayer}{foreforeground}%apparently, using layer 'foreground' in 'append after command' brings the entire node to the front, which we don't want!
\node[font=\tiny, green, below=of c, yshift=2mm] (lbl c-ne) {c.ne};
\draw[red,->] (lbl c-ne) -- (c.north east);
\end{pgfonlayer}
\node[font=\tiny, orange, below=of r] (lbl r-sw) {r.sw};
\draw[red,->] (lbl r-sw) -- (r.south west);
\end{tikzpicture}
\end{document}
Как мне убедиться, что мои пользовательские границы находятся в пределах \node
границ и нарисованы?наверхуцвета \node
наполнителя?
Я пытался использовать его \begin{pgfonlayer}{foreground}
для вынесения границ на передний план, но, похоже, все, что он делает, append after command
это выносит на передний план все изображение целиком \node
, при этом граница остается позади заполнителя.
решение1
Вы можете уменьшить/увеличить их следующим образом 0.5\pgflinewidth
:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,chains,scopes,shapes.misc,calc}
\begin{document}
\begin{tikzpicture}[start chain,
node distance=5mm,
every node/.style={on chain},
connect/.style={join=by ->},
point/.style={coordinate},
l/.style={fill=cyan!50, rounded rectangle, rounded rectangle right arc=0, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}
\draw[] let \p1=(\tikzlastnode.north west), \p2=(\tikzlastnode.south east), \n1={0.5*(\y1-\y2)} in
($(\tikzlastnode.north east)+(-0.5\pgflinewidth,0)$) -- (\tikzlastnode.north west) arc(90:270:\n1) -- ($(\tikzlastnode.south east)+(-0.5\pgflinewidth,0)$);
\end{pgfinterruptpath}
}
}},
c/.style={fill=green!50, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}
\draw[] ($(\tikzlastnode.north east)+(-0.5\pgflinewidth,0)$) -- ($(\tikzlastnode.north west)+(0.5\pgflinewidth,0)$) ($(\tikzlastnode.south west)+(0.5\pgflinewidth,0)$) -- ($(\tikzlastnode.south east)+(-0.5\pgflinewidth,0)$);
\end{pgfinterruptpath}
}
}},
r/.style={fill=orange!50, rounded rectangle, rounded rectangle left arc=0, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}
\draw[] let \p1=(\tikzlastnode.north west), \p2=(\tikzlastnode.south east), \n1={0.5*(\y1-\y2)} in
($(\tikzlastnode.north west)+(0.5\pgflinewidth,0)$) -- (\tikzlastnode.north east) arc(90:-90:\n1) -- ($(\tikzlastnode.south west)+(0.5\pgflinewidth,0)$);
\end{pgfinterruptpath}
}
}},
cozy/.style={node distance=-\pgflinewidth}]
\node[point] (p1) {};
\node [l, connect] (l) {L};
% introduced space here on purpose, to demonstrate too long borders
\node [c] (c) {C};
{%[cozy]
\node [r] (r) {R};
}
\node[point, connect] (p2) {};
\end{tikzpicture}
\end{document}
Ответ на пересмотренный ОП:
Может быть, я не совсем понимаю ваши требования, но это ли то, что вы хотите?
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,chains,scopes,shapes.misc,backgrounds}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
%\pgfdeclarelayer{foreforeground}
\pgfsetlayers{background,main,foreground}%,foreforeground}
\begin{document}
\begin{tikzpicture}[start chain,
node distance=5mm,
every node/.style={on chain},
connect/.style={join=by ->},
point/.style={coordinate},
l/.style={line width=\pgflinewidth, fill=cyan!50, rounded rectangle, rounded rectangle right arc=0, append after command={% <= for the border
\pgfextra{\begin{pgfinterruptpath}\begin{pgfonlayer}{foreground}
\draw[] let \p1=($(\tikzlastnode.north east)+(-0.5\pgflinewidth,-\pgflinewidth)$),
\p2=($(\tikzlastnode.north west)+(0,-\pgflinewidth)$),
\p3=($(\tikzlastnode.south west)+(0,\pgflinewidth)$),
\p4=($(\tikzlastnode.south east)+(-0.5\pgflinewidth,\pgflinewidth)$),
\n1={0.5*(\y2-\y3)} in
(\p1) -- (\p2) arc(90:270:\n1) -- (\p4);
\end{pgfonlayer}\end{pgfinterruptpath}}
}},
c/.style={line width=0, fill=green!50, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}\begin{pgfonlayer}{foreground}
\draw[] let \p1=($(\tikzlastnode.north east)+(-0.5\pgflinewidth,-0.5\pgflinewidth)$),
\p2=($(\tikzlastnode.north west)+(0.5\pgflinewidth,-0.5\pgflinewidth)$),
\p3=($(\tikzlastnode.south west)+(0.5\pgflinewidth,0.5\pgflinewidth)$),
\p4=($(\tikzlastnode.south east)+(-0.5\pgflinewidth,0.5\pgflinewidth)$) in
(\p1) -- (\p2) (\p3) -- (\p4);
\end{pgfonlayer}\end{pgfinterruptpath}
}
}},
r/.style={line width=0, fill=orange!50, rounded rectangle, rounded rectangle left arc=0, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}
\begin{pgfonlayer}{foreground}
\draw[] let \p1=($(\tikzlastnode.north east)+(0,-0.5\pgflinewidth)$),
\p2=($(\tikzlastnode.north west)+(0,-0.5\pgflinewidth)$),
\p3=($(\tikzlastnode.south west)+(0,0.5\pgflinewidth)$),
\p4=($(\tikzlastnode.south east)+(0,0.5\pgflinewidth)$),
\n1={0.5*(\y1-\y4)} in
(\p3) -- (\p4) arc(-90:90:\n1) -- (\p2);
\end{pgfonlayer}
\end{pgfinterruptpath}
}
}}
]
\node[point] (p1) {};
\node [l, connect] (l) {L};
{[node distance=-0.5\pgflinewidth]
\node [c] (c) {C};}
{[node distance=0]
\node [r] (r) {R};}
\node[point, connect] (p2) {};
%\node[font=\tiny, cyan, below=of l] (lbl l-se) {l.se};
%\draw[red,->] (lbl l-se) -- (l.south east);
%
%\begin{pgfonlayer}{foreforeground}%apparently, using layer 'foreground' in 'append after command' brings the entire node to the front, which we don't want!
%\node[font=\tiny, green, below=of c, yshift=2mm] (lbl c-ne) {c.ne};
%\draw[red,->] (lbl c-ne) -- (c.north east);
%\end{pgfonlayer}
%\node[font=\tiny, orange, below=of r] (lbl r-sw) {r.sw};
%\draw[red,->] (lbl r-sw) -- (r.south west);
\end{tikzpicture}
\end{document}
Изменение c/.style
на
c/.style={line width=0, fill=green!50, append after command={% <= for the border
\pgfextra{%
\begin{pgfinterruptpath}\begin{pgfonlayer}{foreground}
\draw[] let \p1=($(\tikzlastnode.north east)+(-0\pgflinewidth,-0.5\pgflinewidth)$),
\p2=($(\tikzlastnode.north west)+(0\pgflinewidth,-0.5\pgflinewidth)$),
\p3=($(\tikzlastnode.south west)+(0\pgflinewidth,0.5\pgflinewidth)$),
\p4=($(\tikzlastnode.south east)+(-0\pgflinewidth,0.5\pgflinewidth)$) in
(\p1) -- (\p2) (\p3) -- (\p4);
\end{pgfonlayer}\end{pgfinterruptpath}
}
}},
дает
Но для этого вам понадобится TikZ 3. TikZ 2 нарисует границы за цветами заливки.
решение2
Одним из вариантов является использование составного прямоугольника из shapes.multipart
библиотеки:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
mynode/.style={
rectangle split,
rectangle split parts=3,
rectangle split horizontal,
draw,
rounded corners=6pt,
rectangle split part fill={cyan!50, green!50,orange!50},
rectangle split draw splits=false
}
}
\begin{document}
\begin{tikzpicture}
\node[mynode] at (2,3) {L\nodepart{two}C\nodepart{three}R};
\end{tikzpicture}
\end{document}