[Tutorial] Grafica ad oggetti con TikZ

  • Creatore
    Topic
  • #82198
    Up
    0
    Down
    ::


    Il recente articolo di Roberto Giacomelli “Grafica ad oggetti” su ArsTeXnica mi ha incuriosito parecchio e mi sono ricordato di avere sfogliato qualcosa al riguardo nel pgfmanual. In effetti, nella versione del 25 Ottobre 2010 la sezione 67 Object-Oriented Programming è interamente dedicata a questo tipo di programmazione.

    Per alcuni tipi di applicazione (grafica) credo sia molto più facile ed immediata rispetto al paradigma tradizionale di TikZ, come possono essere diagrammi di flusso o diagrammi ER. Certo, per chi ha un po’ di esperienza con TikZ, il primo impatto è chiedersi: “Che fine hanno fatto nodi e path?”. La risposta è: “In background, nascosti all’utente, ma ci sono”. Anzi, la risposta vera sarebbe: “Da nessuna parte perché non esiste implementazione pratica ad oggi”. Infatti non ci sono, che io conosca, librerie create con questo paradigma di programmazione: occorre costruirsele.

    Un esempio semplice.

    Nel documento occorre dichiarare:`\usepgfmodule{oo}` per accedere alla programmazione ad oggetti. Andiamo ora a dichiarare una nostra classe rettangolo, che molto semplicemente creerà un rettangolo con testo. La dichiarazione di classe avviene con: `\pgfooclass{nome-classe}{
    codice-classe
    }` Nel nostro caso: `pgfooclass{rettangolo}{
    codice-classe
    }`Gli attributi privati di classe vanno definiti con: `\attribute attributo;` oppure: `\attribute attributo=valore;` nel caso l’attributo abbia un valore di default. I metodi, invece, con: `\method nome-metodo(parametri) {
    codice-metodo
    }` Esiste un metodo speciale, il costruttore, che deve avere il nome della classe e nessun parametro. Nel nostro caso quindi:`\method rettangolo() {
    }
    ` Supponiamo di creare un metodo per inserire il testo nel rettangolo. Per prima cosa è necessario creare un attributo di classe: `\attribute testo;` Successivamente, serve un metodo in modo tale che l’oggetto che si andrà a creare possa scrivere il testo nel rettangolo. In modo molto semplice: `\method add text(#1) {
    \pgfooset{testo}{#1}
    }` Per inserire il testo nel rettangolo sarà quindi sufficiente usare una sintassi tipo [tt]oggetto.add text(testo)[/tt]. Si noti che il nome del metodo può essere intervallato da spazi senza che il compilatore si lamenti. Attraverso il comando [tt]\pgfooset[/tt] il metodo [tt]add text[/tt] andrà a definire l’attributo [tt]testo[/tt] che non ha un valore di default suo.

    Definiamo ora un metodo per disegnare il rettangolo con il testo. Il codice: `\method draw(#1,#2) {
    \node [rectangle,draw]
    at (#1,#2) {\pgfoovalueof{testo}};
    }` Il nostro metodo riceve come parametri le coordinate x e y della posizione e disegna un rettangolo (opzioni [tt]rectangle,draw[/tt]) con il testo che abbiamo definito: il comando [tt]\pgfoovalueof{attributo}[/tt] semplicemente restituisce il valore di un attributo. A questo punto, con [tt]oggetto.draw(coordinate)[/tt] si potrà disegnare il rettangolo. Nel nostro caso: `\pgfoonew \rect=new rettangolo()`
    Resta solo da capire come definire nuovi oggetti. La sintassi è questa: `\pgfoonew \oggetto=new costruttore` La definizione non deve avvenire necessariamente in un ambiente [tt]tikzpicture[/tt] e si noti che i nomi degli oggetti sono preceduti da [tt]\[/tt] come la normali macro.

    Nel nostro esempio minimale, quindi, possiamo usare l’oggetto e i metodi descritti in questo modo:`\begin{document}
    \pgfoonew \rect=new rettangolo() % nuovo oggetto
    \begin{tikzpicture}
    \rect.add text(Testo)
    \rect.draw(0,0)
    \end{tikzpicture}
    \end{document}`

    Un esempio più complesso. `
    \documentclass{article}
    \usepackage{tikz}

    \usepgfmodule{oo}

    % dichiarazione di classe
    \pgfooclass{rettangolo}{

    \attribute larghezza=2cm;
    \attribute altezza=0.75cm;
    \attribute testo;
    \attribute bordo=black;
    \attribute sfondo=none;
    \attribute coltesto=black;

    % costruttore di classe
    \method rettangolo() {
    }

    \method add text(#1) {
    \pgfooset{testo}{#1}
    }

    \method set larghezza(#1) {
    \pgfooset{larghezza}{#1}
    }

    \method set altezza(#1) {
    \pgfooset{altezza}{#1}
    }

    \method set bordo(#1) {
    \pgfooset{bordo}{#1}
    }

    \method set sfondo(#1) {
    \pgfooset{sfondo}{#1}
    }

    \method set colore testo(#1) {
    \pgfooset{coltesto}{#1}
    }

    \method draw(#1,#2) {
    \node [rectangle,draw,
    minimum width=\pgfoovalueof{larghezza},
    minimum height=\pgfoovalueof{altezza},
    draw=\pgfoovalueof{bordo},
    fill=\pgfoovalueof{sfondo},
    text=\pgfoovalueof{coltesto},
    ]
    at (#1,#2) {\pgfoovalueof{testo}};
    }

    % Un metodo che richiama altri metodi:
    % si usa la macro \pgfoothis per
    % fare riferimento all'oggetto corrente
    \method set dimensioni(#1,#2){
    \pgfoothis.set larghezza(#1)
    \pgfoothis.set altezza(#2)
    }

    \method set stile(#1,#2,#3){
    \pgfoothis.set bordo(#1)
    \pgfoothis.set sfondo(#2)
    \pgfoothis.set colore testo(#3)
    }

    }
    \begin{document}
    \pgfoonew \rect=new rettangolo()
    \begin{tikzpicture}
    \rect.add text(Testo)
    \rect.set bordo(red)
    \rect.draw(0,0)

    % erediterà il testo e il bordo
    \rect.draw(2,2)

    % cambiamo dimensioni, stile e testo
    \rect.set stile(blue,blue!50!cyan!20,blue)
    \rect.set dimensioni(3cm,1cm)
    \rect.add text(Altro testo)
    \rect.draw(4,4)
    \end{tikzpicture}
    \end{document}
    ` Il risultato:

    [attachment=581]Senzanome.jpg[/attachment]

    Per chi ha avuto la pazienza di seguire fino a questo punto, vorrei segnalare che da poco ho creato una libreria per disegnare diagrammi ER (molto semplice) proprio con questo paradigma di programmazione: https://github.com/cfiandra/er-oo. È disponibile una breve guida e un primo esempio di utilizzo.

    Ciao
    Claudio

    Attachments:
    You must be logged in to view attached files.
Visualizzazione 7 filoni di risposte
  • Autore
    Risposte
    • #82199
      robitex
      Amministratore del forum
        Up
        0
        Down
        ::


        Bellissimo intervento molto interessante.
        La programmazione oop nell’articolo su Ars si basava su Lua. Nel tuo intervento invece si basa solo su pdftex appoggiandosi alle librerie TikZ.
        E la prima volta che vedo un esempio pratico delle capacità oop di TikZ.
        R.

      • #82200
        Up
        0
        Down
        ::

        robitex” post=81539Bellissimo intervento molto interessante.
        La programmazione oop nell’articolo su Ars si basava su Lua. Nel tuo intervento invece si basa solo su pdftex appoggiandosi alle librerie TikZ.
        E la prima volta che vedo un esempio pratico delle capacità oop di TikZ.
        R.

        Direi che al momento è una cosa ancora tutta da esplorare! 🙂

        Infatti, come dicevo, in alcuni ambiti ha una potenzialità notevole ed è di facile utilizzo, immediato direi, ma fatico ancora a trovare un metodo per alberi o matrici che hanno una sintassi particolare. Magari in futuro rivedrò la mia posizione 😉

        Ah.. un secondo esempio di utilizzo si può trovare in Make picture background transparent in beamer.

        Ciao
        Claudio

      • #82201
        claudio
        Partecipante
          Up
          0
          Down
          ::


          ho preso la palla al balzo e visto che devo fare dei diagrammi ho usato il tuo codice.
          Ho solo un piccolo problema
          come controllo la posizione di mod1 ?
          perché come se dice dalle mi parti nun se sposta 🙂

          ciao claudio
          il codice
          `
          \documentclass{article}

          \usepackage{lmodern}

          \usepackage{tikz}
          \usepgfmodule{oo}
          \usetikzlibrary{positioning}

          \pgfooclass{module}{

          % class attributes
          \attribute text;
          \attribute text width=2.5cm;
          \attribute border color=orange;
          \attribute top color=none;
          \attribute bottom color=none;
          \attribute text color=black;
          \attribute label;
          \attribute width=3cm;
          \attribute height=1cm;

          % constructor method
          \method module() {
          }

          \method text(#1) {
          \pgfooset{text}{#1}
          }

          \method set text width(#1) {
          \pgfooset{text width}{#1}
          }

          \method set border color(#1) {
          \pgfooset{border color}{#1}
          }

          \method set top color(#1) {
          \pgfooset{top color}{#1}
          }

          \method set bottom color(#1) {
          \pgfooset{bottom color}{#1}
          }

          \method set text color(#1) {
          \pgfooset{text color}{#1}
          }

          \method set label(#1) {
          \pgfooset{label}{#1}
          }

          \method set width(#1) {
          \pgfooset{width}{#1}
          }

          \method set height(#1) {
          \pgfooset{height}{#1}
          }

          \method draw(#1,#2) {
          \node [rectangle,
          rounded corners,
          draw=\pgfoovalueof{border color},
          top color=\pgfoovalueof{top color},
          bottom color=\pgfoovalueof{bottom color},
          text=\pgfoovalueof{text color},
          align=center,
          text width=\pgfoovalueof{text width},
          minimum width=\pgfoovalueof{width},
          minimum height=\pgfoovalueof{height},
          ] (\pgfoovalueof{label}) at (#1,#2) {\pgfoovalueof{text}};
          }

          \method place(#1) {
          \node [rectangle,
          rounded corners,
          draw=\pgfoovalueof{border color},
          top color=\pgfoovalueof{top color},
          bottom color=\pgfoovalueof{bottom color},
          text=\pgfoovalueof{text color},
          align=center,
          text width=\pgfoovalueof{text width},
          minimum width=\pgfoovalueof{width},
          minimum height=\pgfoovalueof{height},
          #1
          ] (\pgfoovalueof{label}) {\pgfoovalueof{text}};
          }

          % shortcut method to easily set labels, text and draw
          % use the \pgfoothis to refer to the current object
          \method set and draw(#1,#2,#3,#4) {
          \pgfoothis.set label(#1)
          \pgfoothis.text(#2)
          \pgfoothis.draw(#3,#4)
          }

          % shortcut method to easily set labels, text and place
          % objects
          \method set and place(#1,#2,#3) {
          \pgfoothis.set label(#1)
          \pgfoothis.text(#2)
          \pgfoothis.place(#3)
          }

          % shortcut method to easily set the style
          \method set style(#1,#2,#3) {
          \pgfoothis.set border color(#1)
          \pgfoothis.set top color(#2)
          \pgfoothis.set bottom color(#3)
          }

          % shortcut method to easily set the dimensions
          \method set dimensions(#1,#2,#3) {
          \pgfoothis.set width(#1)
          \pgfoothis.set height(#2)
          \pgfoothis.set text width(#3)
          }

          }

          \begin{document}

          \begin{tikzpicture}[node distance=4.5cm,scale=0.75, transform shape]
          % declaring the new object with the constructor method
          \pgfoonew \mod=new module()

          % method set style:
          % #1= border color
          % #2= top color
          % #3= bottom color
          \mod.set style(black,white,white)

          % method set and draw:
          % #1= label of the node
          % #2= text
          % #3,#4= coordinates
          \mod.set and draw(mod1,Bisogni educativi speciali,20,0)

          % \mod.set style(blue!50!cyan,blue!50!cyan!40,blue!50!cyan!5)

          % method set dimensions:
          % #1= module width
          % #2= module height
          % #3= text width
          %\mod.set dimensions(5cm,1cm,4.9cm)

          % method set and place:
          % #1= label of the node
          % #2= text
          % #3= position with respect to another node identified with a label
          \mod.set and place(mod2,{\mbox{Motivi fisici}} ,below left of=mod1)
          \mod.set and place(mod3,{\mbox{Motivi biologici}} ,right of=mod2)
          \mod.set and place(mod4,{\mbox{Motivi sociali}} ,right of=mod3)
          \mod.set and place(mod5,{\mbox{Motivi fisiologici}} ,right of=mod4)
          \mod.set and place(mod6,{\mbox{Motivi fisiologici}} ,right of=mod5)

          \draw[->] (mod1)– (mod2);
          \draw[->] (mod1)– (mod3);
          \draw[->] (mod1)– (mod4);
          \draw[->] (mod1)– (mod5);
          \draw[->] (mod1)– (mod6);
          \end{tikzpicture}

          `

        • #82202
          Up
          0
          Down
          ::


          Hai imposto che [tt]mod1[/tt] è alle coordinate [tt]x=20[/tt] e [tt]y=0[/tt] attraverso:`\mod.set and draw(mod1,Bisogni educativi speciali,20,0)` Esistono fondamentalmente due strade per operare: specificando sempre le coordinate dell’oggetto con [tt].set and draw[/tt] oppure usando riferimenti relativi (nello stesso modo di TikZ tradizionale) con [tt].set and place[/tt].

          Per le connessioni potresti anche usare un apposito metodo:`\documentclass{article}

          \usepackage{lmodern}

          \usepackage{tikz}
          \usepgfmodule{oo}
          \usetikzlibrary{positioning}

          \pgfooclass{module}{

          % class attributes
          \attribute text;
          \attribute text width=2.5cm;
          \attribute border color=orange;
          \attribute top color=none;
          \attribute bottom color=none;
          \attribute text color=black;
          \attribute label;
          \attribute width=3cm;
          \attribute height=1cm;

          % constructor method
          \method module() {
          }

          \method text(#1) {
          \pgfooset{text}{#1}
          }

          \method set text width(#1) {
          \pgfooset{text width}{#1}
          }

          \method set border color(#1) {
          \pgfooset{border color}{#1}
          }

          \method set top color(#1) {
          \pgfooset{top color}{#1}
          }

          \method set bottom color(#1) {
          \pgfooset{bottom color}{#1}
          }

          \method set text color(#1) {
          \pgfooset{text color}{#1}
          }

          \method set label(#1) {
          \pgfooset{label}{#1}
          }

          \method set width(#1) {
          \pgfooset{width}{#1}
          }

          \method set height(#1) {
          \pgfooset{height}{#1}
          }

          \method draw(#1,#2) {
          \node [rectangle,
          rounded corners,
          draw=\pgfoovalueof{border color},
          top color=\pgfoovalueof{top color},
          bottom color=\pgfoovalueof{bottom color},
          text=\pgfoovalueof{text color},
          align=center,
          text width=\pgfoovalueof{text width},
          minimum width=\pgfoovalueof{width},
          minimum height=\pgfoovalueof{height},
          ] (\pgfoovalueof{label}) at (#1,#2) {\pgfoovalueof{text}};
          }

          \method place(#1) {
          \node [rectangle,
          rounded corners,
          draw=\pgfoovalueof{border color},
          top color=\pgfoovalueof{top color},
          bottom color=\pgfoovalueof{bottom color},
          text=\pgfoovalueof{text color},
          align=center,
          text width=\pgfoovalueof{text width},
          minimum width=\pgfoovalueof{width},
          minimum height=\pgfoovalueof{height},
          #1
          ] (\pgfoovalueof{label}) {\pgfoovalueof{text}};
          }

          % shortcut method to easily set labels, text and draw
          % use the \pgfoothis to refer to the current object
          \method set and draw(#1,#2,#3,#4) {
          \pgfoothis.set label(#1)
          \pgfoothis.text(#2)
          \pgfoothis.draw(#3,#4)
          }

          % shortcut method to easily set labels, text and place
          % objects
          \method set and place(#1,#2,#3) {
          \pgfoothis.set label(#1)
          \pgfoothis.text(#2)
          \pgfoothis.place(#3)
          }

          % shortcut method to easily set the style
          \method set style(#1,#2,#3) {
          \pgfoothis.set border color(#1)
          \pgfoothis.set top color(#2)
          \pgfoothis.set bottom color(#3)
          }

          % shortcut method to easily set the dimensions
          \method set dimensions(#1,#2,#3) {
          \pgfoothis.set width(#1)
          \pgfoothis.set height(#2)
          \pgfoothis.set text width(#3)
          }

          % appositi metodi di connessione
          \method connect(#1,#2) {
          \draw[->] (#1)–(#2);
          }

          \method multi connect(#1) {
          \foreach \i in {#1}{
          \draw[->] (\pgfoovalueof{label})–(\i);
          }
          }

          }

          \begin{document}

          \begin{tikzpicture}[node distance=4.5cm,scale=0.75, transform shape]
          % declaring the new object with the constructor method
          \pgfoonew \mod=new module()

          % method set style:
          % #1= border color
          % #2= top color
          % #3= bottom color
          \mod.set style(black,white,white)

          % method set and draw:
          % #1= label of the node
          % #2= text
          % #3,#4= coordinates
          \mod.set and draw(mod1,Bisogni educativi speciali,20,0)

          % \mod.set style(blue!50!cyan,blue!50!cyan!40,blue!50!cyan!5)

          % method set dimensions:
          % #1= module width
          % #2= module height
          % #3= text width
          %\mod.set dimensions(5cm,1cm,4.9cm)

          % method set and place:
          % #1= label of the node
          % #2= text
          % #3= position with respect to another node identified with a label
          \mod.set and place(mod2,{\mbox{Motivi fisici}} ,below left of=mod1)
          \mod.set and place(mod3,{\mbox{Motivi biologici}} ,right of=mod2)
          \mod.set and place(mod4,{\mbox{Motivi sociali}} ,right of=mod3)
          \mod.set and place(mod5,{\mbox{Motivi fisiologici}} ,right of=mod4)
          \mod.set and place(mod6,{\mbox{Motivi fisiologici}} ,right of=mod5)

          % l'ultimo oggetto ha label mod6 quindi no posso usare multi connect
          % \mod.multi connect(mod1,mod2,mod3,mod4,mod5)
          % prova per capire cosa succede

          \mod.connect(mod1,mod2)
          \mod.connect(mod1,mod3)
          \mod.connect(mod1,mod4)
          \mod.connect(mod1,mod5)
          \mod.connect(mod1,mod6)

          \end{tikzpicture}
          \end{document}
          `
          Ciao
          Claudio

        • #82203
          claudio
          Partecipante
            Up
            0
            Down
            ::


            mi sono spiegato male
            se cambio le coordinate il punto non si muove 🙂
            ciao claudio

          • #82204
            Up
            0
            Down
            ::

            claudio” post=81559se cambio le coordinate il punto non si muove 🙂

            Si muove, si muove, ma di soppiatto 😉

            Il discorso è che tu hai definito un disegno principalmente con i riferimenti relativi, perciò cambiando le coordinate del riferimento iniziale sembra che non succeda nulla mentre in realtà viene tutto traslato di conseguenza. TikZ si calcola la bounding box partendo dalle coordinate iniziali ed aggiornadola ogni volta che aggiungi un elemento. Ambienti [tt]tikzpicture[/tt] diversi hanno bounding box diverse: ti saresti accorto di spostamenti se avessi inserito due volte la stessa figura (con nomi diversi ovviamente) e coordinate diverse al modulo iniziale.

            Dimostrazione pratica: `
            \documentclass{article}

            \usepackage{lmodern}

            \usepackage{tikz}
            \usepgfmodule{oo}
            \usetikzlibrary{positioning,shapes.misc}

            \pgfooclass{module}{

            % class attributes
            \attribute text;
            \attribute text width=2.5cm;
            \attribute border color=orange;
            \attribute top color=none;
            \attribute bottom color=none;
            \attribute text color=black;
            \attribute label;
            \attribute width=3cm;
            \attribute height=1cm;

            % constructor method
            \method module() {
            }

            \method text(#1) {
            \pgfooset{text}{#1}
            }

            \method set text width(#1) {
            \pgfooset{text width}{#1}
            }

            \method set border color(#1) {
            \pgfooset{border color}{#1}
            }

            \method set top color(#1) {
            \pgfooset{top color}{#1}
            }

            \method set bottom color(#1) {
            \pgfooset{bottom color}{#1}
            }

            \method set text color(#1) {
            \pgfooset{text color}{#1}
            }

            \method set label(#1) {
            \pgfooset{label}{#1}
            }

            \method set width(#1) {
            \pgfooset{width}{#1}
            }

            \method set height(#1) {
            \pgfooset{height}{#1}
            }

            \method draw(#1,#2) {
            \node [rectangle,
            rounded corners,
            draw=\pgfoovalueof{border color},
            top color=\pgfoovalueof{top color},
            bottom color=\pgfoovalueof{bottom color},
            text=\pgfoovalueof{text color},
            align=center,
            text width=\pgfoovalueof{text width},
            minimum width=\pgfoovalueof{width},
            minimum height=\pgfoovalueof{height},
            ] (\pgfoovalueof{label}) at (#1,#2) {\pgfoovalueof{text}};
            }

            \method place(#1) {
            \node [rectangle,
            rounded corners,
            draw=\pgfoovalueof{border color},
            top color=\pgfoovalueof{top color},
            bottom color=\pgfoovalueof{bottom color},
            text=\pgfoovalueof{text color},
            align=center,
            text width=\pgfoovalueof{text width},
            minimum width=\pgfoovalueof{width},
            minimum height=\pgfoovalueof{height},
            #1
            ] (\pgfoovalueof{label}) {\pgfoovalueof{text}};
            }

            % shortcut method to easily set labels, text and draw
            % use the \pgfoothis to refer to the current object
            \method set and draw(#1,#2,#3,#4) {
            \pgfoothis.set label(#1)
            \pgfoothis.text(#2)
            \pgfoothis.draw(#3,#4)
            }

            % shortcut method to easily set labels, text and place
            % objects
            \method set and place(#1,#2,#3) {
            \pgfoothis.set label(#1)
            \pgfoothis.text(#2)
            \pgfoothis.place(#3)
            }

            % shortcut method to easily set the style
            \method set style(#1,#2,#3) {
            \pgfoothis.set border color(#1)
            \pgfoothis.set top color(#2)
            \pgfoothis.set bottom color(#3)
            }

            % shortcut method to easily set the dimensions
            \method set dimensions(#1,#2,#3) {
            \pgfoothis.set width(#1)
            \pgfoothis.set height(#2)
            \pgfoothis.set text width(#3)
            }

            % appositi metodi di connessione
            \method connect(#1,#2) {
            \draw[->] (#1)–(#2);
            }

            \method multi connect(#1,#2) {
            \foreach \i in {#2}{
            \draw[->] (#1)–(\i);
            }
            }

            }

            \begin{document}

            \begin{tikzpicture}[node distance=4.5cm,scale=0.55, transform shape]

            \foreach \start in {-5,…,20}
            \draw[help lines](\start,-5) node[below,text=black]{\start}–(\start,5);

            \foreach \start in {-5,…,5}
            \draw[help lines](-5,\start) node[left,text=black]{\start}–(20,\start);

            \pgfoonew \mod=new module()

            \mod.set style(black,white,white)

            \mod.set and draw(mod1,Bisogni educativi speciali,0,0)

            % identificare l'ancora di base
            \node[cross out,draw=red,scale=2] at (0,0){};

            \draw[red,dashed] (-5,0)–(0,0) (0,-5)–(0,0);

            \mod.set and place(mod2,{\mbox{Motivi fisici}} ,below left of=mod1)
            \mod.set and place(mod3,{\mbox{Motivi biologici}} ,right of=mod2)
            \mod.set and place(mod4,{\mbox{Motivi sociali}} ,right of=mod3)
            \mod.set and place(mod5,{\mbox{Motivi fisiologici}} ,right of=mod4)
            \mod.set and place(mod6,{\mbox{Motivi fisiologici}} ,right of=mod5)

            \mod.multi connect(mod1,{mod3,mod4,mod5,mod6})
            \mod.connect(mod1,mod2) % non capisco come mai sparisca la freccia

            \end{tikzpicture}

            \begin{tikzpicture}[node distance=4.5cm,scale=0.55, transform shape]

            \foreach \start in {-5,…,20}
            \draw[help lines](\start,-5) node[below,text=black]{\start}–(\start,5);

            \foreach \start in {-5,…,5}
            \draw[help lines](-5,\start) node[left,text=black]{\start}–(20,\start);

            \pgfoonew \mod=new module()

            \mod.set style(black,white,white)

            \mod.set and draw(mod1,Bisogni educativi speciali,1,3)

            % identificare l'ancora di base

            \draw[red,dashed] (-5,3)–(1,3) (1,-5)–(1,3);
            \node[cross out,draw=red,scale=2] at (1,3){};

            \mod.set and place(mod2,{\mbox{Motivi fisici}} ,below left of=mod1)
            \mod.set and place(mod3,{\mbox{Motivi biologici}} ,right of=mod2)
            \mod.set and place(mod4,{\mbox{Motivi sociali}} ,right of=mod3)
            \mod.set and place(mod5,{\mbox{Motivi fisiologici}} ,right of=mod4)
            \mod.set and place(mod6,{\mbox{Motivi fisiologici}} ,right of=mod5)

            \mod.multi connect(mod1,{mod3,mod4,mod5,mod6})
            \mod.connect(mod1,mod2) % non capisco come mai sparisca la freccia

            \end{tikzpicture}

            \end{document}
            ` Risultato:

            [attachment=583]oo.jpg[/attachment]

            Ciao
            Claudio

            Attachments:
            You must be logged in to view attached files.
          • #82205
            claudio
            Partecipante
              Up
              0
              Down
              ::


              ho capito il problema
              bisogna costruire avendo in mente il risultato
              e un po di simmetria
              ecco il codice giusto
              `
              \documentclass{article}

              \usepackage{lmodern}

              \usepackage{tikz}
              \usepgfmodule{oo}
              \usetikzlibrary{positioning}

              \pgfooclass{module}{

              % class attributes
              \attribute text;
              \attribute text width=3.0cm;
              \attribute border color=orange;
              \attribute top color=none;
              \attribute bottom color=none;
              \attribute text color=black;
              \attribute label;
              \attribute width=3cm;
              \attribute height=1cm;

              % constructor method
              \method module() {
              }

              \method text(#1) {
              \pgfooset{text}{#1}
              }

              \method set text width(#1) {
              \pgfooset{text width}{#1}
              }

              \method set border color(#1) {
              \pgfooset{border color}{#1}
              }

              \method set top color(#1) {
              \pgfooset{top color}{#1}
              }

              \method set bottom color(#1) {
              \pgfooset{bottom color}{#1}
              }

              \method set text color(#1) {
              \pgfooset{text color}{#1}
              }

              \method set label(#1) {
              \pgfooset{label}{#1}
              }

              \method set width(#1) {
              \pgfooset{width}{#1}
              }

              \method set height(#1) {
              \pgfooset{height}{#1}
              }

              \method draw(#1,#2) {
              \node [rectangle,
              rounded corners,
              draw=\pgfoovalueof{border color},
              top color=\pgfoovalueof{top color},
              bottom color=\pgfoovalueof{bottom color},
              text=\pgfoovalueof{text color},
              align=center,
              text width=\pgfoovalueof{text width},
              minimum width=\pgfoovalueof{width},
              minimum height=\pgfoovalueof{height},
              ] (\pgfoovalueof{label}) at (#1,#2) {\pgfoovalueof{text}};
              }

              \method place(#1) {
              \node [rectangle,
              rounded corners,
              draw=\pgfoovalueof{border color},
              top color=\pgfoovalueof{top color},
              bottom color=\pgfoovalueof{bottom color},
              text=\pgfoovalueof{text color},
              align=center,
              text width=\pgfoovalueof{text width},
              minimum width=\pgfoovalueof{width},
              minimum height=\pgfoovalueof{height},
              #1
              ] (\pgfoovalueof{label}) {\pgfoovalueof{text}};
              }

              % shortcut method to easily set labels, text and draw
              % use the \pgfoothis to refer to the current object
              \method set and draw(#1,#2,#3,#4) {
              \pgfoothis.set label(#1)
              \pgfoothis.text(#2)
              \pgfoothis.draw(#3,#4)
              }

              % shortcut method to easily set labels, text and place
              % objects
              \method set and place(#1,#2,#3) {
              \pgfoothis.set label(#1)
              \pgfoothis.text(#2)
              \pgfoothis.place(#3)
              }

              % shortcut method to easily set the style
              \method set style(#1,#2,#3) {
              \pgfoothis.set border color(#1)
              \pgfoothis.set top color(#2)
              \pgfoothis.set bottom color(#3)
              }

              % shortcut method to easily set the dimensions
              \method set dimensions(#1,#2,#3) {
              \pgfoothis.set width(#1)
              \pgfoothis.set height(#2)
              \pgfoothis.set text width(#3)
              % appositi metodi di connessione
              }
              \method connect(#1,#2) {
              \draw[->] (#1)–(#2);
              }

              \method multi connect(#1) {
              \foreach \i in {#1}{
              \draw[->] (\pgfoovalueof{label})–(\i);
              }
              }

              }

              \begin{document}

              \begin{tikzpicture}[node distance=4.5cm,scale=0.75, transform shape]
              % declaring the new object with the constructor method
              \pgfoonew \mod=new module()

              % method set style:
              % #1= border color
              % #2= top color
              % #3= bottom color
              \mod.set style(black,white,white)

              % method set and draw:
              % #1= label of the node
              % #2= text
              % #3,#4= coordinates
              \mod.set and draw(mod1,Bisogni educativi speciali,100,200)

              % \mod.set style(blue!50!cyan,blue!50!cyan!40,blue!50!cyan!5)

              % method set dimensions:
              % #1= module width
              % #2= module height
              % #3= text width
              %\mod.set dimensions(5cm,1cm,4.9cm)

              % method set and place:
              % #1= label of the node
              % #2= text
              % #3= position with respect to another node identified with a label
              \mod.set and place(mod4,{\mbox{Motivi sociali}} ,below of=mod1)
              \mod.set and place(mod2,{\mbox{Motivi fisici}} ,right of=mod4)
              \mod.set and place(mod3,{\mbox{Motivi biologici}} ,right of=mod2)

              \mod.set and place(mod5,{\mbox{Motivi fisiologici}} ,left of=mod4)
              \mod.set and place(mod6,{\mbox{Motivi fisiologici}} ,left of=mod5)

              \mod.connect(mod1,mod2)
              \mod.connect(mod1,mod3)
              \mod.connect(mod1,mod4)
              \mod.connect(mod1,mod5)
              \mod.connect(mod1,mod6)
              \end{tikzpicture}

              \end{document}

              `

              ciao
              claudio

            • #82206
              Up
              0
              Down
              ::

              claudio” post=81564ho capito il problema
              bisogna costruire avendo in mente il risultato
              e un po di simmetria
              ecco il codice giusto

              Non proprio.. se usi i riferimenti relativi rispetto ad un unico punto iniziale dato con in coordinate, puoi inventare i valori che ti pare per quelle coordinate (nel range ammissibile ovviamente) e il disegno non si sposterà di un millimetro. Il motivo è che TikZ elabora la tua coordinata e poi aggiorna la bounding box in base a ciò che tu aggiungi con i riferimenti relativi. Dopo di che ti presenta solo la parte di disegno che ti interessa, quindi anche se dichiari la coordinata di partenza a [tt](218,301)[/tt] non ti mostra tutto il rettangolo vuoto da un’ipotetica origine[tt](0,0)[/tt]. Più o meno è quello che volevo dire con il disegno precedente. Poi, ovviamente, questo non vale se tu dai tutto in coordinate, ma poiché in questo esempio ricolleghi tutto al primo modulo… se sposti quello si sposta tutto di conseguenza.

              Per essere più chiaro, guarda questo esempio. Allego solo il documento, il preambolo è uguale a prima (serve però il pacchetto [tt]lipsum[/tt]): `
              \begin{document}
              \lipsum[2]

              \begin{tikzpicture}[node distance=4.5cm,scale=0.55, transform shape]

              \pgfoonew \mod=new module()

              \mod.set style(black,white,white)

              \mod.set and draw(mod1,Bisogni educativi speciali,0,0)

              \mod.set and place(mod2,{\mbox{Motivi fisici}} ,below left of=mod1)
              \mod.set and place(mod3,{\mbox{Motivi biologici}} ,right of=mod2)
              \mod.set and place(mod4,{\mbox{Motivi sociali}} ,right of=mod3)
              \mod.set and place(mod5,{\mbox{Motivi fisiologici}} ,right of=mod4)
              \mod.set and place(mod6,{\mbox{Motivi fisiologici}} ,right of=mod5)

              \mod.multi connect(mod1,{mod3,mod4,mod5,mod6})
              \mod.connect(mod1,mod2) % non capisco come mai sparisca la freccia

              \end{tikzpicture}

              \lipsum[2]

              \begin{tikzpicture}[node distance=4.5cm,scale=0.55, transform shape]

              \pgfoonew \mod=new module()

              \mod.set style(black,white,white)

              \mod.set and draw(mod1,Bisogni educativi speciali,218cm,301cm)

              % identificare l'ancora di base

              \mod.set and place(mod2,{\mbox{Motivi fisici}} ,below left of=mod1)
              \mod.set and place(mod3,{\mbox{Motivi biologici}} ,right of=mod2)
              \mod.set and place(mod4,{\mbox{Motivi sociali}} ,right of=mod3)
              \mod.set and place(mod5,{\mbox{Motivi fisiologici}} ,right of=mod4)
              \mod.set and place(mod6,{\mbox{Motivi fisiologici}} ,right of=mod5)

              \mod.multi connect(mod1,{mod3,mod4,mod5,mod6})
              \mod.connect(mod1,mod2) % non capisco come mai sparisca la freccia

              \end{tikzpicture}

              \lipsum[2]
              \end{document}
              ` Il risultato non subisce nessuna variazione in base alle coordinate iniziali:

              [attachment=589]Senzanome_2013-01-23-3.jpg[/attachment]

              Ciao
              Claudio

              Attachments:
              You must be logged in to view attached files.
          Visualizzazione 7 filoni di risposte
          • Devi essere connesso per rispondere a questo topic.

          Go to top