23

I already have

\tikzstyle{block} = [draw, fill=yellow!20, text centered, rectangle,
minimum height=0.8cm,minimum width=6em, align=right]

First, I can obtain a rectangle by

\node (rect) [block] at (0,0) {test};

Second, I can also obtain a rectangle by

\draw (0,0) rectangle (1,1);

Question: I want to use the first way to create a rectangle, whose properties have been predefined using \tikzstyle. If using the second way, I have to define the properties of the rectangle again. I know the coordinates of the corners of the rectangle can be obtained by

  • rect.north east
  • rect.north wast
  • rect.south east
  • rect.south west

Can I create a rectangle using the first way and specify the four corner coordinates of the rectangle?

5
  • You have conflicting objectives, you are providing a minimum width but then asking to be 1cm wide and high. Note that a node is not a ordinary path, it's a more complex object.
    – percusse
    Dec 23, 2012 at 1:31
  • 1
  • @percusse The rectangle path could not care less about the node specific styles (only the unknowing user might wonder). More interestingly, I find text centered and align=right, though my current PGF manual does not know about text centered anyway. Dec 23, 2012 at 2:07
  • @Qrrbrbirlbel Yes you have even more for example text badly ragged; check line 775 onwards in tikz.code.tex file. They are kind of the older (or maybe lower) versions of align=.... options. I know them from the auto-complete options of QTikZ.
    – percusse
    Dec 23, 2012 at 2:13
  • @percusse I have only said that my manual doesn’t know about them. ;) After all, there were no error messages, so TikZ at least knew them. And yes, they practically are align= without setting the node halign header. On that note, @Shiyu: align=right overwrites text centered. Dec 23, 2012 at 2:35

1 Answer 1

25

Yes, you can.

Though, I limited your question to two corner coordinates, because unless you account for rotation, two coordinates suffice to specify a rectangle.

So many possibilities.

But before I divulge the actual solution to you let me give you some other ideas on positioning.

  1. The anchor= key. It can be used as for example anchor=south west (see my example below) which set the south-west corner of the to-placed node at the at part.
  2. With the positioning library you can even be more specific and could specify above right=<distance> of <coordinate> where <coordinate> can be an actual coordinate like 0,0 (enbrace the whole argument in { } when you use , in it!), a node or a node’s anchor.

    Unless <distance> is specified, none is used. This topic is a bit complex, it is best to read subsection 17.5.3 “Advanced Placement Options” of the PGF manual.

  3. The fit library and its fit= key. The fit key takes a list of coordinates (or nodes, or anchors) and fits the to-be-fitted node so that those coordinates are enclosed by that node. But be aware of the inner sep key and the usual dimension-setting keys (height, width, etc.) as they can affect the placement; usually the corners do not lie at those coordinates.

  4. My solution: the from=<coordinate 1> to <coordinate2> key. See the last point on the next list.

So many styles.

I have created four distinctive styles:

  1. block filldraw contains
    • draw and
    • fill options. It is used in the other styles and on the rectangle path.
  2. block rect contains
    • block filldraw (and inherits its option) and
    • the node-specific rectangle option (which is the default). This style can be applied to an path but doesn’t change much for the path unless it contains a node which would than inherit those node-specific styles (but not the draw and fill styles).
  3. block contains
    • block rect,
    • minimum height and
    • minimum width. Again, it does not change much for paths but for nodes.
  4. from style (that should be used on a node) takes its argument in the form

    from=<coordinate 1> to <coordinate 2>
    

    Now, those coordinates can be just arbitrary 0,0 but than the whole argument must be enclosed in { } (as I did in my example below). But they also can be nodes and their anchors. <coordinate 1> will be used as the lower left corner in the above right=of key.

    Both coordinates will be used to calculate the horizontal and vertical dimensions for the node. Note that I have used the minimum width and minimum height keys to set the needed dimensions. In this case, the node will grow with its content.

In the example I have set the opacity key to see the overlaying nodes and how they get positioned.

Code

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning}
\makeatletter
\tikzset{
    block filldraw/.style={% only the fill and draw styles
        draw, fill=yellow!20},
    block rect/.style={% fill, draw + rectangle (without measurements)
        block filldraw, rectangle},
    block/.style={% fill, draw, rectangle + minimum measurements
        block rect, minimum height=0.8cm, minimum width=6em},
    from/.style args={#1 to #2}{% without transformations
        above right={0cm of #1},% needs positioning library
        /utils/exec=\pgfpointdiff
            {\tikz@scan@one@point\pgfutil@firstofone(#1)\relax}
            {\tikz@scan@one@point\pgfutil@firstofone(#2)\relax},
        minimum width/.expanded=\the\pgf@x,
        minimum height/.expanded=\the\pgf@y}}
\makeatother
\begin{document}
\begin{tikzpicture}[opacity=.4]
\draw[block filldraw]              (0,0) rectangle (1,1)       ;
\node[block] (rect)             at (0,0)                 {test};
\node[block, anchor=south west] at (0,0)                 {test};
\node[block rect, from={0,0 to 2,.5}]                 {from-to};

\foreach \x/\y/\pos in {0/0/below,1/1/above,2/.5/right}
  \fill[opacity=1] (\x,\y) circle (1pt) node [\pos] {$\x,\y$};
\end{tikzpicture}
\end{document}

Output

enter image description here

Code with fit and animation

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning,fit}
\makeatletter
\tikzset{
    block filldraw/.style={% only the fill and draw styles
        draw, fill=yellow!20},
    block rect/.style={% fill, draw + rectangle (without measurements)
        block filldraw, rectangle},
    block/.style={% fill, draw, rectangle + minimum measurements
        block rect, minimum height=0.8cm, minimum width=6em},
    from/.style args={#1 to #2}{% without transformations
        above right={0cm of #1},% needs positioning library
        /utils/exec=\pgfpointdiff
            {\tikz@scan@one@point\pgfutil@firstofone(#1)\relax}
            {\tikz@scan@one@point\pgfutil@firstofone(#2)\relax},
        minimum width/.expanded=\the\pgf@x,
        minimum height/.expanded=\the\pgf@y}}
\makeatother
\newcommand*\hideme[1]{\ifnum\iCount<#1\relax\tikzset{every node/.style={opacity=0}}\fi}
\begin{document}
\foreach \iCount in {0,...,4}{
\begin{tikzpicture}[opacity=.6]
\draw[block filldraw]              (0,0) rectangle (1,1)       ; \hideme1
\node[block] (rect)             at (0,0)                 {test}; \hideme2
\node[block, anchor=south west] at (0,0)                 {test}; \hideme3
\node[block rect, from={0,0 to 2,.5}]                 {from-to}; \hideme4
\node[block rect, fit={(0,0)(1,1)}]                       {fit};  
\foreach \x/\y/\pos in {0/0/below,1/1/above,2/.5/right}
  \fill[opacity=1] (\x,\y) circle (1pt) node [opacity=1, \pos] {$\x,\y$};
\end{tikzpicture}}
\end{document}

Output with fit and animation

enter image description here

3
  • Nice. You can also get the same effect by \node[block,fit={(0,0)(1,1)}] {test}; with inner and outer sep dimensions reset to zero and minimum size removed (via fit library).
    – percusse
    Dec 23, 2012 at 3:08
  • @percusse Well, now that you have mentioned it, I’ll add fit to my answer. Though I find the need to set the seps to zero as a disadvantage. Nonetheless, it is a valid option and, in other cases, a good alternative. Dec 23, 2012 at 3:31
  • Dear Lord! So many solutions. Tikz is always much more complicated than I think. Thanks a lot! Excellent answer!
    – Shiyu
    Dec 23, 2012 at 4:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .