使用 Pgf / TiKz 的和弦进程图

使用 Pgf / TiKz 的和弦进程图

需要使用 Pgf / TiKz 实现一个和弦进行图用于音乐讲座。基本代码如下:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning, fit, calc, shapes, arrows}
\renewcommand{\figurename}{Figure}

\usepackage{musixtex}

\begin{document}

\begin{figure}[!htb]
    \centering
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 4) {I};
        \node[raiz] (ch0) {C}
        child {node[right] (ch5) {maj6}}
        child {node[right] (ch4) {maj6/9}}
        child {node[right] (ch3) {maj9}}
        child {node[right] (ch2) {maj7}}
        child {node[right] (ch1) {maj}};
        \node[fit=(romanNumber)(ch0)(ch5)(ch1)(ch4), draw,rounded corners=0.5cm] {};
    \end{tikzpicture}    \qquad    
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 3) {iii};
        \node[raiz] (ch0) {E}
        child {node[right] (ch4) {maj6}}
        child {node[right] (ch3) {min9}}
        child {node[right] (ch2) {min7}}
        child {node[right] (ch1) {min}};
        \node[fit=(romanNumber)(ch0)(ch1)(ch4), draw,rounded corners=0.5cm] {};
    \end{tikzpicture}    \qquad    
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 2.5) {vi};
        \node[raiz] (ch01) {A}
        child {node[right] (ch11) {min9}}
        child {node[right] (ch12) {min7}}
        child {node[right] (ch13) {min}};
        \node[below = 2cm of ch01,raiz] (ch02) {C}
        child {node[right] (ch12) {maj6}};
        \node[fit=(romanNumber)(ch01)(ch11)(ch02)(ch12), draw,rounded corners=0.5cm] {};
    \end{tikzpicture}    \qquad    
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 3) {ii};
        \node[raiz] (ch01) {D}
        child {node[right] (ch11) {min9}}
        child {node[right] (ch12) {min7}}
        child {node[right] (ch13) {min}};
        \node[below = 2cm of ch01,raiz] (ch02) {F}
        child {node[right] (ch12) {maj6}};
        \node[fit=(romanNumber)(ch01)(ch11)(ch02)(ch12), draw,rounded corners=0.5cm] {};
    \end{tikzpicture}    \qquad    
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 4) {IV};
        \node[raiz] (ch01) {D}
        child {node[right] (ch11) {maj6}}
        child {node[right] (ch12) {maj6/9}}
        child {node[right] (ch12) {maj9}}
        child {node[right] (ch12) {maj7}}
        child {node[right] (ch13) {maj}};
        \node[below = 4.1cm of ch01,raiz] (ch02) {D}
        child {node[right] (ch12) {min7}};
        \node[fit=(romanNumber)(ch01)(ch13)(ch02)(ch12), draw,rounded corners=0.5cm] {};
    \end{tikzpicture}    \qquad    
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 4) {I};
        \node[raiz] (ch0) {C}
        child {node[right] (ch5) {maj6}}
        child {node[right] (ch4) {maj6/9}}
        child {node[right] (ch3) {maj9}}
        child {node[right] (ch2) {maj7}}
        child {node[right] (ch1) {maj}};
        \node[fit=(romanNumber)(ch0)(ch5)(ch1)(ch4), draw,rounded corners=0.5cm] {};
    \end{tikzpicture}    \qquad    
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 3) {V};
        \node[raiz] (ch01) {G}
        child {node[right] (ch11) {7\#5}}
        child {node[right] (ch12) {dom9}}
        child {node[right] (ch12) {dom7}}
        child {node[right] (ch13) {maj}};
        \node[below = 2.5cm of ch01,raiz] (ch02) {Db}
        child {node[right] (ch12) {dom7}};
        \node[fit=(romanNumber)(ch01)(ch11)(ch02)(ch12), draw,rounded corners=0.5cm] {};
    \end{tikzpicture} \qquad    
    \begin{tikzpicture}
        [parent anchor=east,child anchor=west,grow=east]
        \tikzstyle{title}=[font=\fontsize{18}{18}\color{green!65}\sffamily]
        \tikzstyle{raiz}=[ball color=white,circle,text=black,anchor=west]
        \tikzstyle{edge from parent}=[draw=none,dashed,thick,red]
        \node [title] (romanNumber) at (1.5, 2) {vii};
        \node[raiz] (ch01) {B}
        child {node[right] (ch11) {m7b5}}
        child {node[right] (ch12) {dim}};
        \node[below = 1.5cm of ch01,raiz] (ch02) {D}
        child {node[right] (ch21) {min6}};
        \node[fit=(romanNumber)(ch01)(ch11)(ch02)(ch21), draw,rounded corners=0.5cm] {};
    \end{tikzpicture}
    \caption{Chord Progression Map}
\end{figure}

\end{document}

当前输出如下: 当前的

期望的输出如下:

期望


编辑

现在,基本代码如下:

\documentclass{article}
%\documentclass[tikz]{standalone}
\usepackage{musixtex}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, graphs, chains, ext.paths.ortho, ext.positioning-plus}
\begin{document}
    \begin{tikzpicture}[
        chord list/.style args={#1/#2:#3}{
            matrix, rectangle, draw={#1}, fill={#1!10}, rounded corners, thick, name=#2,
            label={[anchor=north, node font=\Large\sffamily, text={#1}]north:{#2}},
            node contents={\tikzset{create chord list={#2}{#3}}\pgfmatrixendrow}},
        circ node/.style={
            thin, draw, fill=white, circle, inner sep=+.15em,
            text width=width("D$\flat$"), align=center},
        chord node/.style={inner xsep=+.15em, text depth=+0pt},
        create chord list/.code 2 args={
            \tikzset{node distance=+.2em and +.5em, start chain=chord#1 going west below, anchor=center}
            \path (up:2.3em);
            \foreach[remember=\first (initially 1), count=\i] \t/\N in {#2}{
                \foreach \n in \N \node[on chain, chord node] {\n};
                \node[circ node, left=of (chord#1-\first)(chord#1-\tikzchaincount)] (chord#1-label-\i) {\t};
                \unless\ifnum\first=\tikzchaincount\relax
                \path[black, thin] (chord#1-label-\i)
                edge (chord#1-\first.mid west) edge (chord#1-\tikzchaincount.mid west);
                \fi
                \edef\first{\pgfinteval{\tikzchaincount+1}}}}]
        %% Inicia dibujo
        \draw[thick,-LaTeX] (1.4,5.6) -- ++(-1:0.6);
        \draw[thick,-LaTeX] (1.4,4.5) -- ++(-20:0.6);
        \draw[thick,-LaTeX] (1.4,3.2) -- ++(-40:0.6);
        \draw[thick,-LaTeX] (0.5,2.7) -- ++(-70:0.6);
        \draw[thick,-LaTeX] (-0.3,2.7) -- ++(-95:0.6);
        \matrix[                      chord list=green/iii:E/{min, min7, min9, maj6}];
        \matrix[above=1.5cm of iii,  chord list=green/I:C/{maj, maj7, maj9, maj6/9, maj6}];
        \matrix[north right=  of iii, chord list=green/vi:{A/{min, min7, min9}, C/maj6}];
        \matrix[north right=  of vi,  chord list=blue/ii:{F/{min, min7, min9}, F/maj6}];
        \matrix[north right=  of ii,  chord list=blue/IV:{F/{maj, maj7, maj9, maj6/9, maj6}, D/min7}];
        \matrix[north right=2:of IV,  chord list=green/I:C/{maj, maj7, maj9, maj6/9, maj6}];
        \matrix[above=.5cm of (IV)(I),chord list=red/V:{G/{maj, dom7, dom9, 7$\sharp$5}, D$\flat$/dom7}];
        \matrix[below=.5cm of (IV)(I),chord list=red/vii:{B/{dim, m7$\flat$5}, D/min6}];
        \graph[
        edges={thick, >=Latex, only horizontal first},
        use existing nodes,
        oi/.style args={#1:#2}{out={#1}, in={#2}}]{
            iii -> vi -> ii -> IV <->[only horizontal second] I,
            iii ->[bend left, left anchor=north, right anchor=90] ii,
            vi <->[bend right, left anchor=south, right anchor=230] IV,
            iii <-[oi=-90:200] vii,
            V <->[oi=  0: 90] I,
            (V.200) <->[oi=180: 90] IV,
            V      <-[oi=180: 85] ii,
            (V.160) <->[oi=180: 90] vi,
            ii ->[oi=-90:180] vii,
            IV ->[oi=-90:160] vii
            ->[oi=  0:-90] I
        };
    \end{tikzpicture}
\end{document}

当前输出如下: 解决了

解决了 !!!

答案1

这里开始为每个盒子使用一个矩阵,并为最小/最大节点使用一个链。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta, graphs, chains, ext.paths.ortho, ext.positioning-plus}
\begin{document}
\begin{tikzpicture}[
  chord list/.style args={#1/#2:#3}{
    matrix, rectangle, draw={#1}, fill={#1!10}, rounded corners, thick, name=#2,
    label={[anchor=north, node font=\Large\sffamily, text={#1}]north:{#2}},
    node contents={\tikzset{create chord list={#2}{#3}}\pgfmatrixendrow}},
  circ node/.style={
    thin, draw, fill=white, circle, inner sep=+.15em,
    text width=width("D$\flat$"), align=center},
  chord node/.style={inner xsep=+.15em, text depth=+0pt},
  create chord list/.code 2 args={
    \tikzset{node distance=+.2em and +.5em, start chain=chord#1 going west below, anchor=center}
    \path (up:2.3em);
    \foreach[remember=\first (initially 1), count=\i] \t/\N in {#2}{
      \foreach \n in \N \node[on chain, chord node] {\n};
      \node[circ node, left=of (chord#1-\first)(chord#1-\tikzchaincount)] (chord#1-label-\i) {\t};
      \unless\ifnum\first=\tikzchaincount\relax
        \path[black, thin] (chord#1-label-\i)
          edge (chord#1-\first.mid west) edge (chord#1-\tikzchaincount.mid west);
      \fi
      \edef\first{\pgfinteval{\tikzchaincount+1}}}}]
\matrix[                      chord list=green/iii:E/{min, min7, min9, maj6}];
\matrix[north right=  of iii, chord list=green/vi:{A/{min, min7, min9}, C/maj6}];
\matrix[north right=  of vi,  chord list=blue/ii:{F/{min, min7, min9}, F/maj6}];
\matrix[north right=  of ii,  chord list=blue/IV:{F/{maj, maj7, maj9, maj6/9, maj6}, D/min7}];
\matrix[north right=2:of IV,  chord list=green/I:C/{maj, maj7, maj9, maj6/9}];
\matrix[above=.5cm of (IV)(I),chord list=red/V:{G/{maj, dom7, dom9, 7$\sharp$5}, D$\flat$/dom7}];
\matrix[below=.5cm of (IV)(I),chord list=red/vii:{B/{dim, m7$\flat$5}, D/min6}];
\graph[
  edges={thick, >=Latex, only horizontal first},
  use existing nodes,
  oi/.style args={#1:#2}{out={#1}, in={#2}}]{
  iii -> vi -> ii -> IV <->[only horizontal second] I,
  iii ->[bend left, left anchor=north, right anchor=95] ii,
  V <->[oi=  0: 90] I,
  (V.200) <->[oi=180: 90] IV,
   V       ->[oi=180: 90] ii,
  (V.160) <->[oi=180: 90] vi,
  IV ->[oi=-90:180] vii
     ->[oi=  0:-90] I
};
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容