LaTeX forum ⇒ Graphics, Figures & TablesTikZ: Custom shape with input and output ports Topic is solved

Information and discussion about graphics, figures & tables in LaTeX documents.
johnahay
Posts: 3
Joined: Mon Jan 04, 2016 5:29 pm

TikZ: Custom shape with input and output ports

Postby johnahay » Mon Jan 04, 2016 5:56 pm

Dear all!

I'm trying to create some blocks in tikz and create some edges between them. It should look like the attached image. (With more blocks obviously)
goal.png
goal.png (4.5 KiB) Viewed 7730 times


Each block may have an arbitrary number of inputs on its left hand side, and an arbitrary number of outputs on its right hand side. (-> tikz-anchors?)
The block names, inputs and outputs are generated via a python3 script. (among other things)

I tried to create the block on the right first: "just" 2 inputs, 2 outputs. In the tikz manual I read about "anchors", "declareshape" and "circle split", so I tried to create a rectangle with a second label (somewhere).

It looks like I'm to dumb do that... :cry:

Edit:
Another question that I have:
Will I be able to use that with automatic layout?

Minimal code included below:

  1. ! Package PGF Math Error: Unknown function `port' (in ' port').
  2. ...
  3. ! Missing number, treated as zero.
  4. ...
  5. ! A <box> was supposed to be here.
  6. ...


  1. \documentclass{standalone}
  2. \usepackage{tikz}
  3. \usetikzlibrary{shapes}
  4. \makeatletter
  5.  
  6. \begin{document}
  7.  
  8. \newbox\pgfnodepartportbox
  9.  
  10. \pgfdeclareshape{document}{
  11. \nodeparts{text, port}
  12.  
  13. \savedanchor\centerpoint{%
  14. \pgf@x=.5\wd\pgfnodeparttextbox%
  15. \pgfmathsetlength{\pgf@y}{10mm}%
  16. \pgf@y=-\pgf@y%
  17. \advance\pgf@y by-\dp\pgfnodeparttextbox%
  18. \advance\pgf@y by-.5\pgflinewidth%
  19. }%
  20. \savedanchor\portanchor{%
  21. \pgf@x=-.5\wd\pgfnodepartportbox%
  22. \advance\pgf@x by.5\wd\pgfnodeparttextbox%
  23. \pgfmathsetlength{\pgf@y}{10mm}%
  24. \pgf@y=-2\pgf@y%
  25. \advance\pgf@y by-\ht\pgfnodepartportbox%
  26. \advance\pgf@y by-.5\pgflinewidth%
  27. \advance\pgf@y by-\dp\pgfnodeparttextbox%
  28. \advance\pgf@y by-.5\pgflinewidth%
  29. }
  30.  
  31. \inheritsavedanchors[from=rectangle]
  32. \inheritanchorborder[from=rectangle]
  33. \inheritanchor[from=rectangle]{center}
  34. \inheritanchor[from=rectangle]{north}
  35. \inheritanchor[from=rectangle]{south}
  36. \inheritanchor[from=rectangle]{west}
  37. \inheritanchor[from=rectangle]{east}
  38. \inheritbackgroundpath[from=rectangle]
  39.  
  40. \anchor{port}{\portanchor}
  41.  
  42. }
  43.  
  44. \begin{tikzpicture}
  45. \node[draw,shape=circle split] (x) {Remark \nodepart{lower} test};
  46. \node[draw,shape=document] at ([shift=(0:3cm)]x) (x) {test1 \nodepart{port} test2};
  47. \end{tikzpicture}
  48. \end{document}

Tags:

User avatar
Stefan Kottwitz
Site Admin
Posts: 9597
Joined: Mon Mar 10, 2008 9:44 pm

Postby Stefan Kottwitz » Wed Jan 06, 2016 12:55 am

Hi,

welcome to the forum!

I think programming shapes would be very challenging. That's because you require different anchors and node parts, so it's not just a single shape.

Perhaps it's manageable to create the shapes by macros. Each macro could draw a rectangular shape with text and small input and output nodes. Connection arrows could be pointed at those nodes.

I use macros myself to handle complex drawings with repeated parts. They can take arguments for node texts.

Stefan
LaTeX.org admin

johnahay
Posts: 3
Joined: Mon Jan 04, 2016 5:29 pm

Postby johnahay » Thu Jan 07, 2016 4:05 pm

Hi, thanks for your reply!

As the data is generated by a python3 script, I think I may just create 1 shape definition for each different block. So port counts and sizes will not have to be generated by latex/tikz, alleviating the need for macros? :lol:

Problem is: I can't get a custom shape correctly defined in latex/tikz. I don't know latex/tikz enough to create any custom shape (or complex macros). So in my code, I tried to modify the circle split example but ran into the errors posted above.

I found the code for split circle *quite* difficult to understand, but I did not find an easier example. What I think the circle split code does:

  1. \newbox\pgfnodepartlowerbox

Creates a box for the lower text label. Is this empty until the \nodepart command in instantiation via \createnode?

  1. \nodeparts{text,lower}

Tells tikz that my shape consists of two labels I can specify using \nodepart.

  1. \savedanchor\centerpoint{%
  2. \pgf@x=.5\wd\pgfnodeparttextbox%
  3. \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/inner ysep}}%
  4. \pgf@y=-\pgf@y%
  5. \advance\pgf@y by-\dp\pgfnodeparttextbox%
  6. \advance\pgf@y by-.5\pgflinewidth%
  7. }%

I think I don't understand this part for example: What variables are set by this? Does this influence shape sizes too? Is the position of the labels set here?

  1. \inheritbackgroundpath[from=circle]
  2. \beforebackgroundpath{
  3. \pgfutil@tempdima=\radius%
  4. \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
  5. \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
  6. \ifdim\pgf@xb<\pgf@yb%
  7. \advance\pgfutil@tempdima by-\pgf@yb%
  8. \else%
  9. \advance\pgfutil@tempdima by-\pgf@xb%
  10. \fi%
  11. \advance\pgfutil@tempdima by-.5\pgflinewidth%
  12. \pgfsetshortenstart{0pt}%
  13. \pgfsetshortenend{0pt}%
  14. \pgfsetarrows{-}%
  15. \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpoint{-1\pgfutil@tempdima}{0pt}}}%
  16. \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpoint{\pgfutil@tempdima}{0pt}}}%
  17. \pgfusepath{stroke}%
  18. }

This part uses the radius variable to create the visible shapes horizontal line, the circle is inherited. How do the \advance correlate to the \advance in the anchor part?

I'm looking for some dead-simple example code for custom tikz shapes. (e.g. a block with 2 inputs and 2 outputs :mrgreen: )

User avatar
Stefan Kottwitz
Site Admin
Posts: 9597
Joined: Mon Mar 10, 2008 9:44 pm

Postby Stefan Kottwitz » Thu Jan 07, 2016 10:54 pm

Here is a suggestion using TikZ pic instead of pgf code. This can be adjusted.

  1. \documentclass[border=10pt]{standalone}
  2. \usepackage{tikz}
  3. \usetikzlibrary{arrows.meta}
  4. \tikzset{>={Latex[width=3mm,length=5mm]}}
  5. \renewcommand*{\familydefault}{\sfdefault}
  6. \def\Width{1}
  7. \def\Heigth{0.5}
  8. \tikzset{
  9. block/.style={
  10. thick, draw,
  11. minimum width=2.8cm, minimum height=2cm,
  12. text width = 3cm, inner sep=0pt,
  13. text = black, align=center, font=\LARGE,
  14. },
  15. pics/blockFourInputs/.style args = {#1/#2/#3/#4}{
  16. code = {
  17. \node [block] {\tikzpictext};
  18. \node (-1) at (-\Width,-\Heigth) {#1};
  19. \node (-2) at (-\Width,\Heigth) {#2};
  20. \node (-3) at (\Width,\Heigth) {#3};
  21. \node (-4) at (\Width,-\Heigth) {#4};
  22. }
  23. }
  24. }
  25. \begin{document}
  26. \begin{tikzpicture}
  27. \pic (block1) [pic text = plup] at (6,3) {blockFourInputs = p1/p2/o1/o2};
  28. \pic (block2) [pic text = gen] at (0,0) {blockFourInputs = //out/};
  29. \pic (block3) [pic text = more] at (6,-3,0) {blockFourInputs = //in/};
  30. \draw [->] (block2-3) to [in=-180, out=0] ++ (1,0)
  31. to [in=180, out=0] (block1-1);
  32. \draw [->] (block1-4) to [in=90, out=0] ++ (2,-2)
  33. to [in=0, out=270] (block3-3);
  34. \end{tikzpicture}
  35. \end{document}


tikz-pic.png
tikz-pic.png (9.46 KiB) Viewed 7688 times


Stefan
LaTeX.org admin

johnahay
Posts: 3
Joined: Mon Jan 04, 2016 5:29 pm

Postby johnahay » Thu Jan 07, 2016 11:44 pm

Looks very good, I will try that. Thank you!

User avatar
Stefan Kottwitz
Site Admin
Posts: 9597
Joined: Mon Mar 10, 2008 9:44 pm

Postby Stefan Kottwitz » Fri Jan 08, 2016 12:45 am

It was a quick shot - pic codes (TikZ 3.0 or above required) are easier than pgf shapes and you can do more in a similar way. Let me know if you would like to know more or if there's trouble in applying it.

And I'm very interested in your final drawings - can you tell us more, post results, perhaps also Python code? I use TikZ for comprehensive network drawings. Just to show, I attach a sample PDF, and embed a downsized preview bitmap. (Not that I post I noticed that my foreground/background bundling ellipses don't work well in the lower part - I accidentally made the lines in the lower parts background lines, to be corrected.)

bandwidth.png
bandwidth.png (120.21 KiB) Viewed 7686 times


Stefan
Attachments
bandwidth.pdf
(32.7 KiB) Downloaded 231 times
LaTeX.org admin


Return to “Graphics, Figures & Tables”

Who is online

Users browsing this forum: No registered users and 5 guests