Діаграми і графи в LaTeX з використанням PGF / TikZ 3.0

    
 
Кілька місяців тому вийшов графічний пакет для LaTeX PGF / TikZ 3.0, і в ньому з'явилося чимало цікавих штук. У цій статті ми спробуємо їх застосувати для малювання простий блок-схеми. Намалюємо, наприклад, шматочок відомої схеми визначення мови за писемності . Засоби, вже розглянуті в раніше опублікованої статті , чіпати не будемо, а поговоримо про спрощену нотації записи графів та управлінням позиціонуванням вузлів і розгалуженням графа.
 
 
 
 
Спрощена нотація графів
 
Стандартними командами малювання вузлів і ліній в TikZ є
\node
і
\path
, але код з ними виходить досить багатослівним і за парканом з команд
\node
можна втратити саму діаграму. У TikZ 3.0 з'явилася спрощена нотація для графів, запозичена з відомого пакету Graphviz і його мови DOT . У DOT-нотації найпростіший граф можна записати як послідовність текстових міток і псевдострелочек, начебто
a -> b -> c
.
 
 
 
Почнемо з преамбули:
 
\usepackage{tikz}  
\usetikzlibrary{graphs}

 
І зробимо простенький граф:
 
\begin{tikzpicture}
  \graph {
    Диакритика? -> Да! -> Французский
  };
  \end{tikzpicture}

 
Команда
\graph
у своєму аргументі приймає опис графа в DOT-нотації, і ми вважаємо, що отримаємо ланцюжок з трьох вершин. Насправді ж не все так просто: наші мітки збилися в кучамалу (пункт 1 на зображенні «Ланцюжок Вершин»)
 
Позиціонувати вузли графа можна вручну, і ми цим займемося в наступній частині, але поки спробуємо автоматичне позиціонування. Найпростіше, що можна зробити, це підказати TikZ'у в опціях команди
\graph
, куди повинен рости граф і куди галузитися. Давайте ростити граф вправо, так щоб центри вузлів розташовувалися на сітці з кроком три сантиметри (пункт 2):
 
 
\begin{tikzpicture}
    \graph[grow right=3cm] {
        Диакритика? -> Да! -> Французский
    };
    \end{tikzpicture}

 
Можна вказати відстань не між центрами, а між сусідніми краями вузлів (пункт 3):
 
 
\begin{tikzpicture}
    \graph[grow right sep=2em] {
        Диакритика? -> Да! -> Французский
    };
    \end{tikzpicture}

 
Граф можна ростити в будь-якому напрямку. Стандартні напрямки right, left, up, down ортогональні осях координат, але можна ростити і під кутом (пункт 4):
 
 
\begin{tikzpicture}
    \graph[chain shift=(-45:1)] {
        Диакритика? -> Да! -> Французский
    };
    \end{tikzpicture}

 
 
Довільний текст в мітках
 
 
Якщо в мітці є, наприклад, дефіс, або ще що-небудь більш-менш складне (математична формула?), То нас без додаткових підказок не зрозуміють, а от якщо його Залапковано, то все буде ок:
 
\begin{tikzpicture}
    \graph[grow right sep=1em] {
        Диакритика? -> Много над E:\\ \`{E}, \'{E}, \^{E}, \"{E} -> Французский
    };
    \end{tikzpicture}

    \begin{tikzpicture}
    \graph[grow right sep=1em] {
        Диакритика? -> "Много над E:\\ \`{E}, \'{E}, \^{E}, \"{E}" -> Французский
    };
    \end{tikzpicture}

 
 
Галуження графа
 
Давайте зробимо нашу схему поскладніше і додамо розгалуження. У DOT-нотації вузли можна об'єднати в групу за допомогою фігурних дужок і до кожного з вузлів групи провести дугу з вузла-предка:
 
 
\begin{tikzpicture}
    %% Опция nodes определяет параметры всех узлов графа. align=center центрирует текст в узле
    \graph[nodes={align=center}, grow down sep, branch right sep] {
        Диакритика? ->
        {
            "Много над E:\\ \`{E}, \'{E}, \^{E}, \"{E}" ->  Французский,
            Мало -> "Хоть что-то есть?" -> 
            {
                "\c{C} и \"{E}" -> Точно не французский? -> 
                { 
                   "Ой$\dots$он" -> Французский,
                   Вроде нет -> Албанский
                },
                "Только \"{A} и \"{O} \\ но мноогоо \\ сдвооенных" -> Финский
            }
        } 
    };
    \end{tikzpicture}

 
 
 
Як бачите, з вузлів-питань провелися дуги до відповідних вузлів-відповідям. За розташування вузлів при розгалуження відповідає параметр
branch
, в нашому випадку
right sep
каже що розгалуження має йти вправо, з однаковою відстанню між шарами. Він може приймати і інші значення, аналогічно параметру
grow
. До речі, нам знадобилося вказати вирівнювання тексту у вузлах, без якого не спрацювали б переноси рядків в мітках
 
Але у нас, схоже, проблема. Дуга з вузла «Ой… він» до висновку «Французький» провелась, але пішла кудись вгору. Чи не можна зробити так, щоб висновок «Французький» був нижче всіх попередніх йому запитань і відповідей? Якщо наївно помістити висновок «Французький» за всією групою після питання «діакрітікі?» Те дуги проведуть з усіх листя групи:
 
 
 
\begin{tikzpicture}
    %% Добавим стиль рисования всех узлов
    \graph[nodes={align=center,rectangle,draw=black}, grow down sep, branch right sep] {
        Диакритика? ->
        {
            "Много над E:\\ \`{E}, \'{E}, \^{E}, \"{E}",
            Мало -> "Хоть что-то есть?" -> 
            {
                "\c{C} и \"{E}" -> Точно не французский? -> 
                { 
                   "Ой$\dots$он",
                   Вроде нет -> Албанский
                },
                "Только \"{A} и \"{O} \\ но мноогоо \\ сдвооенных" -> Финский
            }
        } -> 
        Французский
    };
    \end{tikzpicture}

 
 
Але можна явно виключити листя зі списку решт проведених дуг, додавши опції
not source
і
not target
. Їх назви дещо суперечливі: так, щоб вказати, що з вузла «Албанська» не повинна йти дуга у вузол «Французький» треба приписати до вузла «Албанська» опцію
[not target]

 
 
\begin{tikzpicture}
    \graph[nodes={align=center,rectangle,draw=black}, grow down sep, branch right sep] {
        Диакритика? ->
        {
            "Много над E:\\ \`{E}, \'{E}, \^{E}, \"{E}",
            Мало -> "Хоть что-то есть?" -> 
            {
                "\c{C} и \"{E}" -> Точно не французский? -> 
                { 
                   "Ой$\dots$он",
                   Вроде нет -> Албанский[not target]
                },
                "Только \"{A} и \"{O} \\ но мноогоо \\ сдвооенных" -> Финский[not target]
            }
        } -> 
        Французский
    };
    \end{tikzpicture}

 
Мабуть, для першої частини вистачить, а в наступних частинах можна буде розглянути інші стратегії позиціонування вузлів і варіанти використання DOT-нотації.
 
Посилання:
[1] Оригінальний текст діаграм зі статті і скомпільований результат
[2] Пакет PGF / TikZ
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.