使用迭代创建边命令

使用迭代创建边命令

我打算创建命令\graphEdge来简化绘制图形边缘的过程,它将采用由函数分隔的参数列表,,然后将参数划分并对其进行迭代,\draw为每个参数减去最后一个参数创建一个新的参数。

在 mwe 上有一些关于功能实现的非常粗略的想法,以及使用示例。

平均能量损失

\documentclass{standalone}
\usepackage{xparse}
\usepackage{tikz}
\NewDocumentCommand\graphEdge{
    s % #1 - dashed
    > {\SplitList{,}}
    o % #2 - position options
    > {\SplitList{,}}
    o % #3 - draw options
    >{\SplitList{,}}
    m % #4 - annotations
    >{\SplitList{,}}
    m % #5 - nodes
}{
    % i = interator
    \IfValueT{#5[i+1]}{
        \draw[->,\IfBooleanT{#1}{dashed,}\IfValueT{#3[i]}{#3[i]}]%
        (#5[i]-x) --node[sloped,\IfValueTF{#2[i]}{#2[i]}{above}] {\(#4[i]\)}%
        (#5[i+1]-x);
    }
}

\begin{document}

\begin{tikzpicture}

    % ======================= Nodes ====================== %

    % 1,2,3
    \node (1-x) at (0, 0) {1};
    \node (2-x) at (1, 1) {2};
    \node (3-x) at (2, 1) {3};
    \node (4-x) at (1,-1) {4};

    % ======================= Edges ====================== %

    % \graphEdge{A,B}{1,2,3}
    \draw[->] (1-x) --node[sloped,above]{\(A\)} (2-x);
    \draw[->] (2-x) --node[sloped,above]{\(B\)} (3-x);
    % \graphEdge*{C,D}{1,4,3}
    \draw[->,dashed] (1-x) --node[sloped,above]{\(C\)} (4-x);
    \draw[->,dashed] (4-x) --node[sloped,above]{\(D\)} (3-x);

\end{tikzpicture}

\end{document}

答案1

l3clist您可以使用\clist_item:nn直接访问列表中的元素,因为它将返回一个\unexpanded,我们可以安全地使用.expanded处理程序来允许每个项目有多个选项(否则,它会尝试blue, '在下面的示例中查找键)。

的元素#4直接用作一个\foreach循环的列表,其中\i从 1 开始计数,\j从 2 开始计数,但您也可以使用\i + 1并将l3clist为您评估它。

above我没有使用默认设置,而是auto = left使用可以通过密钥swap访问的设置。(不过,您可以仅为您的节点设置和定义。)auto = right'above'/.style = below

代码

\documentclass[tikz]{standalone}
\ExplSyntaxOn
\NewDocumentCommand\graphEdge{
    s % #1 - dashed
    o % #2 - position options
    o % #3 - draw options
    m % #4 - annotations
    m % #5 - nodes
}{
  \foreach[count=\i,count=\j from 2]\VALUE in {#4}
    \draw[
      ->,
      \IfBooleanT{#1}{dashed},
      style/.expanded=\IfValueT{#3}{\clist_item:nn{#3}{\i}}]
      (\clist_item:nn{#5}{\i}-x)
       to node[
         sloped,
         auto=left,
         style/.expanded=\IfValueT{#2}{\clist_item:nn{#2}{\i}}]{\(\VALUE\)}
      (\clist_item:nn{#5}{\i+1}-x);
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\node (1-x) at (0, 0) {1}; \node (2-x) at (1, 1) {2};
\node (3-x) at (2, 1) {3}; \node (4-x) at (1,-1) {4};

\graphEdge{A,B}{1,2,3}
\graphEdge*[', {blue, '}][, bend right]{C,D}{1,4,3}
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述


这是与图书馆相同的例子graphs,不幸的是我遇到了name suffix没有正确考虑目标节点的错误。建议的修复包含在下面的代码中。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs, quotes}
\tikzset{math node/.style={execute at begin node=$, execute at end node=$}}
\makeatletter % https://github.com/pgf-tikz/pgf/issues/1251#issuecomment-1486886842
\def\tikz@@to@or@edge@@coordinate(#1){\tikz@scan@one@point\tikz@to@use@last@coordinate@as@target(#1)\tikz@to@or@edge@function}
\def\tikz@to@use@last@coordinate@as@target#1{\iftikz@shapeborder\edef\tikztotarget{\tikz@shapeborder@name}\else\edef\tikztotarget{\the\tikz@lastx,\the\tikz@lasty}\fi}
\makeatother
\newcommand*\graphEdges[2][]{%
\path[name suffix=-x,#1]graph[
  use existing nodes,edge quotes={sloped,auto=left,math node}]{#2};}
\begin{document}
\begin{tikzpicture}
\node (1-x) at (0, 0) {1}; \node (2-x) at (1, 1) {2};
\node (3-x) at (2, 1) {3}; \node (4-x) at (1,-1) {4};

\graphEdges{
  1 ->["A"]     2 ->["B"]     3,
  {[edge = dashed]
    1 ->["C"' bend right] 4 ->["D"' blue] 3,
  }
}
\end{tikzpicture}
\end{document}

相关内容