Como criar este gráfico com TikZ?

Como criar este gráfico com TikZ?

Quero criar um gráfico como o seguinte:

insira a descrição da imagem aqui

Abaixo está meu código:

    \documentclass[11pt]{article}
    \usepackage{tikz}
    \usetikzlibrary{arrows}

    \newcommand{\psign}{+}
    \newcommand{\ppsign}{++}

    \begin{document}

    \noindent
    \begin{tikzpicture}
    \tikzstyle{my node} = [draw,rectangle,minimum width=2.2cm,minimum height=0.8cm, node distance=2cm]
    %\draw[black!20] (-0.5cm,-0.5cm) grid (14cm,7cm);
    \node [my node] (A) {GDI DDI};
    \node [my node] (B) [above of=A] {GDI};

    \begin{scope}[xshift=3cm]
    \node                       (C)     {Graphics Driver};
    \node [my node] (D) [above of=C]    {GDI\psign Flat API};
    \node [my node] (E) [above of=D]    {GDI\psign\ C\ppsign API};
    \end{scope}

    \begin{scope}[xshift=6cm]
    \node [my node] (F) {DX DDI};
    \node [my node] (G) [above of=F] {DXGI};
    \node [my node] (H) [above of=G] {Direct3D};
    \node [my node] (I) [above of=H,minimum width=4cm,right=0pt] {Direct2D};
    \node [my node] (J) [right of=I,right=0pt,node distance=3cm] {DirectWrite};
    \node [my node] (K) [right of=F, node distance=4cm] {Software Rasterizer};
    \end{scope}

    \begin{scope}[->,>=triangle 45,semithick]
    \path (B) edge (A);
    \path (E) edge (D);
    \path (H) edge (G);
    \path (G) edge (F);
    \path (J) edge (I);
    \end{scope}

    \draw [dashed] (-1.25,1cm) -- (14,1cm);
    \end{tikzpicture}

    \end{document}

Responder1

insira a descrição da imagem aqui

\documentclass[11pt]{article}
\usepackage{tikz,xcolor}
\usetikzlibrary{arrows,calc,fit,backgrounds}

\definecolor{fcolor}{HTML}{F1F1F1}

\newcommand{\psign}{+}
\newcommand{\ppsign}{++}

\begin{document}

\noindent
\begin{tikzpicture}
\tikzstyle{my node} = [draw,rectangle,minimum width=2.2cm,minimum height=0.8cm, node distance=2cm]
%\draw[black!20] (-0.5cm,-0.5cm) grid (14cm,7cm);
\node [my node] (A) {GDI DDI};
\node [my node] (B) [above of=A] {GDI};

\begin{scope}[xshift=3cm]
\node                       (C)     {Graphics Driver};
\node [my node] (D) [above of=C]    {GDI\psign Flat API};
\node [my node] (E) [above of=D]    {GDI\psign\ C\ppsign API};
\end{scope}

\begin{scope}[xshift=6cm]
\node [my node] (F) {DX DDI};
\node [my node] (G) [fill=white,above of=F] {DXGI};
\node [my node] (H) [fill=white,above of=G] {Direct3D};
\node [my node] (I) [fill=white,above of=H,minimum width=4.5cm,right=0pt] {Direct2D};
\node [my node] (J) [fill=white,right of=I,right=0pt,node distance=3.5cm] {DirectWrite};
\node [my node] (K) [fill=white,right of=G, node distance=4cm] {Software Rasterizer};
\end{scope}

\begin{scope}[->,>=triangle 45,semithick]
\path (B) edge (A);
\path (E) edge (D);
\path (H) edge (G);
\path (G) edge (F);
\path (J) edge (I);
\path (I.south-|K) edge (K);
\path (I.south-|{$(H.north)!.5!(H.north east)$}) edge ($(H.north)!.5!(H.north east)$);
\end{scope}

\begin{scope}[on background layer]
\node[rectangle,fill=fcolor,fit=(G.south west) (J.north east)] {};
\end{scope}

\draw [dashed] (-1.25,1cm) -- (14,1cm);
\end{tikzpicture}

\end{document}

Primeiro, corrigi o Software Rasterizerposicionamento do nó right of=G:

\node [my node] (K) [right of=G, node distance=4cm] {Software Rasterizer};

Então, para as duas conexões de seta restantes, adicionei ao seu edges estas duas linhas:

\path (I.south-|K) edge (K);
\path (I.south-|{$(H.north)!.5!(H.north east)$}) edge ($(H.north)!.5!(H.north east)$);

Aqui (I.south-|K)está o ponto no Direct2Dnó diretamente acima do centro do Software Rasterizernó. A mesma ideia para (I.south-|{$(H.north)!.5!(H.north east)$}), mas um pouco complicada. Agora é o ponto no Direct2Dnó diretamente acima do ponto médio entre o norte e o nordeste do Direct3Dnó.

Os cinco blocos destacados podem ser obtidos pela fitbiblioteca, mas desta vez dentro de um escopo ( on background layer) para evitar desenhar os nós duas vezes. Selecionamos quaisquer dois nós mais externos, como Ge, Je especificamos seus cantos mais externos (G.south west)e (J.north east), respectivamente.

Responder2

Isso faz o que você está procurando. Observe que fitdesenha na parte superior, se precisar de uma cor completa por baixo, pode ser necessário desenhar esses nós duas vezes (uma vez para obter os nós para o fitcálculo e uma vez para desenhá-los novamente na área de ajuste, você pode simplesmente armazenar o desenhar código em uma macro e executar essa macro duas vezes).

\documentclass[11pt]{article}
  \usepackage{tikz}
  \usetikzlibrary{arrows,calc}
  \usetikzlibrary{positioning,fit}
    \newcommand{\psign}{+}
    \newcommand{\ppsign}{++}

    \begin{document}

    \noindent
    \begin{tikzpicture}
    \tikzstyle{my node} = [draw,rectangle,minimum width=2.2cm,minimum height=0.8cm, node distance=2cm]
    %\draw[black!20] (-0.5cm,-0.5cm) grid (14cm,7cm);
    \node [my node] (A) {GDI DDI};
    \node [my node] (B) [above of=A] {GDI};

    \begin{scope}[xshift=3cm]
    \node                       (C)     {Graphics Driver};
    \node [my node] (D) [above of=C]    {GDI\psign Flat API};
    \node [my node] (E) [above of=D]    {GDI\psign\ C\ppsign API};
    \end{scope}

    \begin{scope}[xshift=6cm]
    \node [my node] (F) {DX DDI};
    \node [my node] (G) [above of=F] {DXGI};
    \node [my node] (H) [above of=G] {Direct3D};
    \node [my node] (I) [above of=H,minimum width=4cm,right=0pt] {Direct2D};
    \node [my node] (J) [right of=I,right=0pt,node distance=3cm] {DirectWrite};
    \node [my node] (K) [right of=G, node distance=4cm] {Software Rasterizer};
    \end{scope}


  \begin{scope}[ transform canvas={xshift=1cm},
    ->,>=triangle 45,semithick]
    \draw (I)  --  (I |- K.north);
  \end{scope}
  \begin{scope}[ transform canvas={xshift=-4em},
    ->,>=triangle 45,semithick]
    \draw (I)  --  (I |- H.north);
  \end{scope}

    \begin{scope}[->,>=triangle 45,semithick]
    \path (B) edge (A);
    \path (E) edge (D);
    \path (H) edge (G);
    \path (G) edge (F);
    \path (J) edge (I);
    \end{scope}

    \draw [dashed] (-1.25,1cm) -- (14,1cm);


    \node [fill=gray,opacity=0.2,dotted,fit = (H) (I) (J) (K) ] {};



    \end{tikzpicture}

    \end{document}

insira a descrição da imagem aqui

Presumo que você consiga descobrir como adicionar a legenda acima da área cinza.

Responder3

Soluções @daleif e @ AboAmmar ligeiramente modificadas e simplificadas (me parecem quase iguais :-)):

\documentclass[11pt, border=1mm,
               tikz,
               preview]{standalone}
\usetikzlibrary{arrows,calc,fit,backgrounds}
    \newcommand{\psign}{+}
    \newcommand{\ppsign}{++}

    \begin{document}
\begin{tikzpicture}[
    node distance = 2cm,
every node/.style = {draw, rectangle,
                    fill=white, % if you liked, otherwise should be omitted
                     minimum width=2.2cm, minimum height=0.8cm}
                    ]
\node  (A) {GDI DDI};
\node  (B) [above of=A] {GDI};

\begin{scope}[xshift=3cm]
\node  (C) [draw=none]     {Graphics Driver};
\node  (D) [above of=C]    {GDI\psign Flat API};
\node  (E) [above of=D]    {GDI\psign\ C\ppsign API};
\end{scope}

\begin{scope}[xshift=6cm]
\node  (F) {DX DDI};
\node  (G) [above of=F] {DXGI};
\node  (H) [above of=G] {Direct3D};
\node  (I) [above of=H,minimum width=4.5cm,right=0pt] {Direct2D};
\node  (J) [right of=I,right=0pt,node distance=3.5cm] {DirectWrite};
\node  (K) [right of=G, node distance=4cm] {Software Rasterizer};
\end{scope}

\coordinate (L) at ([xshift=7mm] H.north);
\path[-triangle 45,semithick]
    (B) edge (A)    (E) edge (D)    (H) edge (G)
    (G) edge (F)    (J) edge (I)    (I.south-|K) edge (K)
    (I.south -| L) edge (L)
    (I.south-|{$(H.north)!.5!(H.north east)$}) -- ($(H.north)!.5!(H.north east)$);

\scoped[on background layer]
    \node (M) [rectangle,fill=gray!30,fit=(G.south west) (J.north east)] {};

\coordinate (N) at ($(A.west)!0.5!(B.west)$);
\draw [dashed]  (N) -- (N -| M.east);
\end{tikzpicture}
        \end{document}

Este código fornece:

insira a descrição da imagem aqui

informação relacionada