给树的边缘上色并弯曲

给树的边缘上色并弯曲

我希望树的边缘呈 S 形弯曲,并且节点的顶部边缘用一种颜色着色,底部边缘用另一种颜色着色。我能想到两种可能的解决方案:第一种(灵感来自德米特里·沃洛斯尼赫解决方案)按预期弯曲箭头,但不支持多色。这可以在 中找到customEdge。第二个是使用edge from parent path。我不知道如何继续。在这种情况下,标签很重要。我希望使用 Ti 的解决方案Z 的tree库而不是foresttikz-qtree包。

电流输出

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{trees, arrows.meta}

\begin{document}
\begin{tikzpicture}[
    level 1/.style={sibling distance=8em, level distance=6em},
    level 2/.style={sibling distance=4em, level distance=6em},
    topLabelStyle/.style={
        draw=red,
        every node/.style={
            fill=white, inner sep=4pt, text=red, draw=none
          },
      },
    bottomLabelStyle/.style={
        draw=blue,
        every node/.style={
            fill=white, inner sep=4pt, text=blue
          },
      },
    % Either allow customEdge to alternate between the two colours or fix 
    % edge from parent path so that the paths matches the grays ones.
    edge from parent/.style={customEdge,  -Latex},
    customEdge/.code={
        \draw [thick, gray, -Latex] (\tikzparentnode.east) to[looseness = 0.5, out=0,in=-180,]
        (\tikzchildnode.west);
      },
    edge from parent path={
        (\tikzparentnode.east) .. controls +(90:1) and +(180:1) .. (\tikzchildnode.west)
      },
  ]
  \node {root}[grow'=right]
  child {
      node {1}
      child {
          node {3} edge from parent[topLabelStyle] node[] {c}
        }
      child {
          node {4} edge from parent[bottomLabelStyle] node[] {d}
        }
      edge from parent[topLabelStyle] node[] {a}
    }
  child {
      node {2}
      child {
          node {5} edge from parent[topLabelStyle] node[] {e}
        }
      child {
          node {6} edge from parent[bottomLabelStyle] node[] {f}
        }
      edge from parent[bottomLabelStyle] node[] {b}
    };
\end{tikzpicture}
\end{document}

答案1

这是几乎可以做到的一种方法。与您发布的代码的基本区别:

  • 由于某种原因,该code部分阻止传递样式参数
  • 我删除了这些部分,然后重建了你的代码
  • edge from parent/.style={draw,red,->},现在是默认样式,并且,无论何时需要,向下的路径都会被覆盖,请参阅下面的代码
  • 在路径中使用(\tikzparentnode.east) -- (\tikzchildnode.west)直线,而替换--to [out=0,in=180]似乎忽略了pos-参数,该参数将节点/标签沿所述路径放置
  • 修改你的controls声明即可达到以下效果:
  • .. controls +(0:.5) and +(180:.5) ..现在将一个参考点放在父节点的右侧和子节点的左侧,从而形成 S 形
  • 然而,这种方法似乎与在根和其子级之间放置标签相冲突
  • 我建议插入一个child名为 root 的,它应该可以很好地与所示的方法配合使用,并且使其\node本身不可见,即使用空文本\node {} ...
  • 一些子项必须再次变为黑色以避免彩色节点文本,您当然可以every在样式部分中处理这个问题
  • 最后,我改变了缩进,以便更好地看到哪些单元属于一起(防御性或预防性编程

结果

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{trees, arrows.meta}

\begin{document}
\begin{tikzpicture}[
    level 1/.style={sibling distance=8em, level distance=6em},
    level 2/.style={sibling distance=4em, level distance=6em},
    edge from parent/.style={draw,red,->},% default style
    edge from parent path={(\tikzparentnode.east) 
                            .. controls +(0:.5) and +(180:.5) ..
                           (\tikzchildnode.west)
%           (\tikzparentnode.east) -- (\tikzchildnode.west)
    },
    >={Stealth},
    lbl/.style={pos=0.5,fill=white},
    dwn/.style={blue},
  ]
  \node {root}[grow'=right]
      child{
          node {1}
          child{
               node {3} edge from parent node[lbl] {c}
          }
          child{
              node {4}  edge from parent[dwn] node[lbl] {d}
          } 
      }
      child{
          node {2} edge from parent[blue]% to be replaced by dwn
          child[black]{
              node {5}edge from parent node[lbl] {e}
          }
          child[black]{
              node {6} edge from parent[dwn] node[lbl] {f}
          }
      }
  ;
\end{tikzpicture}
\end{document}

相关内容