
Quiero crear un gráfico como el siguiente:
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
\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 Rasterizer
ubicació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 edge
correo 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 Direct2D
nodo directamente encima del centro del Software Rasterizer
nodo. La misma idea para (I.south-|{$(H.north)!.5!(H.north east)$})
, pero un poco complicada. Ahora es el punto del Direct2D
nodo directamente encima del punto medio entre el norte y el noreste del Direct3D
nodo.
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 G
y J
y 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 fit
se 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 fit
cá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}
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: