¿Cómo crear este gráfico con TikZ?

¿Cómo crear este gráfico con TikZ?

Quiero crear un gráfico como el siguiente:

ingrese la descripción de la imagen aquí

A continuación se muestra mi 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}

Respuesta1

ingrese la descripción de la imagen aquí

\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}

Primero arreglé la Software Rasterizerubicación del nodo right of=G:

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

Luego, para las dos conexiones de flecha restantes, agregué a su edgecorreo electrónico estas dos líneas:

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

Aquí (I.south-|K)está el punto del Direct2Dnodo directamente encima del centro del Software Rasterizernodo. La misma idea para (I.south-|{$(H.north)!.5!(H.north east)$}), pero un poco complicada. Ahora es el punto del Direct2Dnodo directamente encima del punto medio entre el norte y el noreste del Direct3Dnodo.

La biblioteca puede obtener los cinco bloques resaltados fit, pero esta vez dentro de un alcance ( on background layer) para evitar dibujar los nodos dos veces. Seleccionamos dos nodos más externos cualesquiera como Gy Jy especificamos sus esquinas más externas (G.south west)y (J.north east), respectivamente.

Respuesta2

Este tipo de hace lo que estás buscando. Tenga en cuenta que fitse dibuja en la parte superior; si necesita un color completo debajo, es posible que necesite dibujar esos nodos dos veces (una vez para obtener los nodos para el fitcálculo y otra para dibujarlos nuevamente en el área de ajuste, puede simplemente almacenar el dibujar código en una macro y ejecutar esa macro dos veces).

\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}

ingrese la descripción de la imagen aquí

Supongo que puedes descubrir cómo agregar la leyenda sobre el área gris.

Respuesta3

Soluciones @daleif y @AboAmmar ligeramente modificadas y simplificadas (me parecen casi iguales :-)):

\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 da:

ingrese la descripción de la imagen aquí

información relacionada