Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I try to draw an association type for an entity-relationship diagram. How can I draw a chamfered rectangle with split parts=2 or 3 ? I found this ref : Horizontally enlarged hexagon with TikZ but it doesn't answer completly to my problem. I tried some variations with "chamfered rectangle" and "rectangle split" without success.

How can I draw a figure like this:

enter image description here

share|improve this question
3  
Can you post a MWE? –  Count Zero Jun 3 '12 at 12:46
add comment

2 Answers

OK, this a little too lengthy but essentially it's a mixture of a copy/paste from rectangle split shape + some basic geometry.

I redefined the east and west anchors and the in-between anchors are now accessible via left/right upper/lower bump names. One can further define an encapsulating style to ease the typing of the node settings. Also inner sep needs a little adjusting. The angle is set to 75 via eye-balling but can be also changed.

However it's not perfect. The anchor border is still pointing to the original rectangle split shape and should not be used i.e.

\draw (o) -- (b);

gives wrong results but it gives the correct output if the point is above or below the node since the top and the bottom of this shape is the same with rectangle split.

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
 \usetikzlibrary{shapes.multipart}
\makeatletter
\pgfdeclareshape{chamfered rectangle}{
  \nodeparts{text,two,three,four}
  \inheritsavedanchors[from=rectangle split]
  \inheritanchorborder[from=rectangle split]
  \inheritanchor[from=rectangle split]{center}
  \inheritanchor[from=rectangle split]{north}
  \inheritanchor[from=rectangle split]{north west}
  \inheritanchor[from=rectangle split]{north east}
  \inheritanchor[from=rectangle split]{base}
  \inheritanchor[from=rectangle split]{south}
  \inheritanchor[from=rectangle split]{south west}
  \inheritanchor[from=rectangle split]{south east}
  \inheritanchor[from=rectangle split]{text}
  \inheritanchor[from=rectangle split]{two}
  \inheritanchor[from=rectangle split]{three}
  \inheritanchor[from=rectangle split]{four}
  \inheritanchor[from=rectangle split]{text split west}
  \inheritanchor[from=rectangle split]{two split west}
  \inheritanchor[from=rectangle split]{three split west}
  \inheritanchor[from=rectangle split]{four split west}
  \inheritanchor[from=rectangle split]{text split east}
  \inheritanchor[from=rectangle split]{two split east}
  \inheritanchor[from=rectangle split]{three split east}
  \inheritanchor[from=rectangle split]{four split east}
\savedanchor{\leftbump}{
  \northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
  \southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
  \pgfmathsetmacro{\vertih}{0.5*(\pgf@ya-\pgf@yb)}
  \pgfmathsetmacro{\horizw}{\vertih/tan(70)}
  \southwest
  \advance\pgf@x by -\horizw pt
  \advance\pgf@y by \vertih pt
}
\savedanchor{\rightbump}{
  \northeast \pgf@xa = \pgf@x \pgf@ya=\pgf@y
  \southwest \pgf@xb = \pgf@x \pgf@yb=\pgf@y
  \pgfmathsetmacro{\vertih}{0.5*(\pgf@ya-\pgf@yb)}
  \pgfmathsetmacro{\horizw}{\vertih/tan(70)}
  \northeast
  \advance\pgf@x by \horizw pt
  \advance\pgf@y by -\vertih pt
}
\savedanchor{\lubump}{
  \northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
  \southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
  \pgf@lib@sh@rs@anchor@one@split@west
  \pgfmathsetmacro{\vertih}{(\pgf@ya-\pgf@y)}
  \pgfmathsetmacro{\horizw}{\vertih/tan(70)}
  \pgfpoint{\pgf@xb}{\pgf@ya}
  \advance\pgf@x by -\horizw pt
  \advance\pgf@y by -\vertih pt
}
\savedanchor{\llbump}{
  \northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
  \southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
  \pgf@lib@sh@rs@anchor@three@split@west
  \pgfmathsetmacro{\vertih}{(\pgf@y-\pgf@yb)}
  \pgfmathsetmacro{\horizw}{\vertih/tan(70)}
  \southwest
  \advance\pgf@x by -\horizw pt
  \advance\pgf@y by \vertih pt
}
\savedanchor{\rubump}{
  \northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
  \southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
  \pgf@lib@sh@rs@anchor@one@split@west
  \pgfmathsetmacro{\vertih}{(\pgf@ya-\pgf@y)}
  \pgfmathsetmacro{\horizw}{\vertih/tan(70)}
  \northeast
  \advance\pgf@x by \horizw pt
  \advance\pgf@y by -\vertih pt
}
\savedanchor{\rlbump}{
  \northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
  \southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
  \pgf@lib@sh@rs@anchor@three@split@west
  \pgfmathsetmacro{\vertih}{(\pgf@y-\pgf@yb)}
  \pgfmathsetmacro{\horizw}{\vertih/tan(70)}
  \pgfpoint{\pgf@xa}{\pgf@yb}
  \advance\pgf@x by \horizw pt
  \advance\pgf@y by \vertih pt
}

\anchor{east}{\rightbump}
\anchor{west}{\leftbump}
\anchor{left upper bump}{\lubump}
\anchor{left lower bump}{\llbump}
\anchor{right upper bump}{\rubump}
\anchor{right lower bump}{\rlbump}
  \backgroundpath{
  \rectanglesplitparameters
  \northeast
  \pgf@xa = \pgf@x \pgf@ya=\pgf@y
  \centerpoint
  \pgf@xc = \pgf@x \pgf@yc=\pgf@y
  \southwest
  \pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgfmathsetmacro{\vertih}{0.5*(\pgf@ya-\pgf@yb)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
  \pgfpathmoveto{\northeast}
  \pgflineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
  \pgflineto{\leftbump}
  \pgflineto{\southwest}
\pgflineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgflineto{\rightbump}
\pgfclosepath
\pgfmoveto{\lubump}\pgflineto{\rubump}
\pgfmoveto{\llbump}\pgflineto{\rlbump}
  }
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node (o) at (0,0) {0};
\node[chamfered rectangle,rectangle split part align={center,left,left,center},draw,inner sep=2pt] (a) at (0,3) {
\verb|COMPTE|
\nodepart{two} \verb|NUM_COMPTE |
\nodepart{three} \verb|SOLDE|
\nodepart{four} \verb|id:NUM_COMPTE|
};
\node[chamfered rectangle,rectangle split part align={center,left,left,center},draw] (b) at (3,0) {
\verb|AA|
\nodepart{two} \verb|NUM_AA |
\nodepart{three} \verb|RAND|
\nodepart{four} \verb|id:NUM_AA|
};
\draw (a.right lower bump) -- (b.left upper bump);
\draw[-latex] (o) -- (b.left lower bump);
\end{tikzpicture}
\end{document}

enter image description here

Following Tom's cue, here are the anchors that are defined in the custom shape, one can add/remove more anchors simply following the copy/paste pattern. However <nodepartnumber> split east/west anchor would still be defined as in the original version but I don't think they would be needed in this particular case.

enter image description here

share|improve this answer
    
Dammit, you posted this faster than I even understood the very basic conceps of how to create a custom node shape. Very nice however. Would you mind making such an "anchor overview chart" as I did, depicting all the anchors with their name? –  Tom Bombadil Jun 12 '12 at 0:45
    
@TomBombadil Please feel free to take this as a base and improve on it. –  percusse Jun 12 '12 at 1:24
    
Oh no, I forgot to award the bounty manually! Sorry for that! –  Jake Jun 20 '12 at 16:44
    
@Jake No problem :) –  percusse Jun 20 '12 at 16:51
    
Tanks a lot ;-) –  madit Sep 27 '12 at 12:38
add comment

Here you go: a chamfered rectangle which defines several coordinates that you can use:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes,calc,arrows}

\newcommand{\chamrec}[8]{% width, height, name, 1st, 2nd, 3rd, x, y
    \pgfmathsetmacro{\ind}{#2/4}
    \begin{scope}[xshift=#7,yshift=#8]
        \draw (\ind,0) coordinate (#3_bl) -- (#1-\ind,0) coordinate (#3_br) -- (#1,#2/2) coordinate (#3_r) -- (#1-\ind,#2) coordinate (#3_tr) -- (\ind,#2)  coordinate (#3_tl) -- (0,#2/2) coordinate (#3_l) -- cycle;
        \coordinate (#3_tlm) at ($0.5*(#3_tl)+0.5*(#3_l)$);
        \coordinate (#3_t) at ($0.5*(#3_tl)+0.5*(#3_tr)$);
        \coordinate (#3_trm) at ($0.5*(#3_tr)+0.5*(#3_r)$);
        \coordinate (#3_brm) at ($0.5*(#3_br)+0.5*(#3_r)$);
        \coordinate (#3_b) at ($0.5*(#3_br)+0.5*(#3_bl)$);
        \coordinate (#3_blm) at ($0.5*(#3_bl)+0.5*(#3_l)$);
        \coordinate (#3_sls) at ($0.5*(#3_bl)+0.5*(#3_tl)$);
        \pgfmathsetmacro{\txt}{(#1-2*\ind-0.1)*1cm}
        \draw (#3_tlm) -- (#3_trm);
        \draw (#3_blm) -- (#3_brm);
        \node[below] at (#3_t) {#4};
        \node[right,text width=\txt] at (#3_sls) {#5};
        \node[above right] at (#3_bl) {#6};
    \end{scope} 
}

\begin{document}

\begin{tikzpicture}
    \chamrec{6}{2}{first}{Red}{Blue Blue Blue Blue Blue Blue Blue Blue}{Yellow}{0}{0}
    \chamrec{6}{2}{second}{Ice}{Water}{Steam}{0}{3cm}
    \chamrec{6}{2}{third}{Crash}{\&}{Burn}{8cm}{1.5cm}
    \draw[-latex,red,very thick] (first_t) -- node[right] {asdf} (second_b);
    \draw[-latex,thick] (first_trm) -- node[below,sloped] {wasd} (third_blm);
    \draw[latex-latex,ultra thick,blue] (third_tlm) -- node[below,sloped] {\#ACDC} (second_brm);
\end{tikzpicture}

\begin{tikzpicture}
    \chamrec{6}{6}{show}{First}{Second}{Third}{0}{0}
    \foreach \x in {l,tlm,tl,t,tr,trm,r,brm,br,b,bl,blm,sls}
    {   \node[circle,draw,fill=white] at (show_\x) {\tiny\x};
    }
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
3  
Nice answer bad vote cap :) –  percusse Jun 11 '12 at 21:32
    
Very nice indeed! However, I think it would be great if you could turn this into a "proper" node shape, so you can just say \node[chamfered rectangle] {First \nodepart{two} Second}; and refer to it using the standard anchors (node.west etc.). Do you think you could do that? –  Jake Jun 11 '12 at 21:40
    
Thanks for answer –  madit Sep 27 '12 at 12:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.