TeX - LaTeX Asked by Eric Sun on April 1, 2021
I want to draw a line between 2 nodes which may fly across existing shape and text content. In the example below, the line connecting a
and b
are intersecting with the label of init
node. I can manually do a "line fly" after I notice the fact from tikz result. But is there some facility which can judge such circumstances and do automatical handling on the run? Something like draw [flyline, ->] (a) to (b)
documentclass[convert]{standalone}
usepackage{tikz}
usetikzlibrary{shapes, positioning}
begin{document}
begin{tikzpicture}[auto]
node[rectangle, draw=black, label={right:this is a test}] (init) {hello};
node[rectangle, draw=black, above right=of init] (a) {a};
node[rectangle, draw=black, below right=of init] (b) {b};
draw [->] (a) to (b);
% I can change to use this after I find the intersect fact from the result
%draw (a) to (a|-init.north);
%draw [->] (b|-init.south) to (b);
end{tikzpicture}
end{document}
Update:
Response to @Rmano’s comment : Thansk for the reply. Yes, use layer can partly resolve my problem. I used `tikz-layers` package which provide 5 predefined layers. Code snippets is as the following:
documentclass[convert]{standalone}
usepackage{tikz}
usetikzlibrary{shapes, positioning, fit}
usepackage{tikz-layers}
begin{document}
begin{tikzpicture}[auto]
node[rectangle, draw=black, label={[fill=white, inner sep=2pt, name=lbl]right:this is a test}] (init) {hello};
node[rectangle, draw=black, above right=of init] (a) {a};
node[rectangle, draw=black, below right=of init] (b) {b};
begin{scope}[on behind layer]
draw [->] (a) to (b);
end{scope}
begin{scope}[on background layer]
node [fit=(init)(a)(b)(lbl), fill=cyan] () {};
end{scope}
end{tikzpicture}
end{document}
Which gives the following result
One thing which I feel not quite perfect is that this makes the label covering background fill. Originally label
is only text, now it get a shape which is not transparent to background fill. We can change the label fill the same as background fill cyan
, but that create another dependency.
Is it possible that label
can has a virtual boundary, which only masks underlining draw
but not underlining fill
?
Update : per @Rmano’s suggestion to use `contour`, update the MWE to the following
documentclass[convert]{standalone}
usepackage{tikz}
usetikzlibrary{shapes, positioning, fit}
usepackage{tikz-layers}
usepackage{bidicontour}
usepackage{bidi}
bidicontourlength{2pt}
begin{document}
begin{tikzpicture}[auto]
node[rectangle, draw=black, label={[inner sep=2pt, name=lbl]right:{bidicontour{cyan}{this is a test}}}] (init) {hello};
node[rectangle, draw=black, above right=of init] (a) {a};
node[rectangle, draw=black, below right=of init] (b) {b};
begin{scope}[on behind layer]
draw [->] (a) to (b);
end{scope}
begin{scope}[on background layer]
node [fit=(init)(a)(b)(lbl), fill=cyan] () {};
end{scope}
%draw (a) to (a|-init.north);
%draw [->] (b|-init.south) to (b);
end{tikzpicture}
end{document}
Which yields nearly perfect result
Thanks for the help!
Is it possible that
label
can has a virtual boundary, which only masks underliningdraw
but not underliningfill
?
I guess not.
Also in my opinion, there is not much difference between writing label={[fill=cyan]text}
and label={[...]bidicontour{cyan}{text}}
. One always need to explicitly write the background color in label={...}
.
The following example shows an attempt to write the background color only once. The definition of pgfonlayerreversed
environment is copied from my previous answer.
documentclass[tikz]{standalone}
usetikzlibrary{backgrounds, shapes, positioning, fit}
usepackage{xpatch}
makeatletter
% copied from my previous answer https://tex.stackexchange.com/a/562606
letpgfonlayerreversedpgfonlayer
letendpgfonlayerreversedendpgfonlayer
xpatchcmdpgfonlayerreversed
{expandafterboxcsname pgf@layerbox@#1endcsnamebegingroup}
{begingroup}
{}{fail}
xpatchcmdendpgfonlayerreversed
{endgroup}
{endgroupexpandafterboxcsname pgf@layerbox@pgfonlayer@nameendcsname}
{}{fail}
% similar to tikz@background@framed, but using "pgfonlayerreversed" envi
deftikz@background@framed@reversed{%
tikz@background@save%
pgfonlayerreversed{background}
path[style=background rectangle] (tikz@bg@minx,tikz@bg@miny) rectangle (tikz@bg@maxx,tikz@bg@maxy);
endpgfonlayerreversed
}%
% similar to option "show background rectangle"
tikzset{
show background rectangle reversed/.style={
execute at end picture=tikz@background@framed@reversed
}
}
makeatother
% user interface
tikzset{
background color/.style={
show background rectangle reversed,
inner frame sep=2pt,
background rectangle/.append style={draw=none, #1},
every node/.append style={#1},
every label/.append style={#1}
}
}
begin{document}
begin{tikzpicture}[background color={fill=cyan}]
node[draw, label={[inner sep=2pt, name=lbl]right:this is a test}] (init) {hello};
node[draw, above right=of init] (a) {a};
node[draw, below right=of init] (b) {b};
begin{scope}[on background layer]
draw [->] (a) to (b);
end{scope}
end{tikzpicture}
end{document}
Correct answer by muzimuzhi Z on April 1, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP