
Первое, с чего стоит начать – описать основную мысль.
В приложении графы будут надстройкой над виджетами (примерно так же, как и графики Highcharts, если кто-то уже знаком с ними).
Для простоты будем подразумевать табличный виджет.
Данные у табличного виджета – это записи той или иной БК.
В нашем концепте каждая запись должна описывать ребро графа.
Таким образом, каждая запись должна содержать информацию по «начальному» и «конечному» узлах графа, и ребру между ними.
Ключи полей, хранящих информацию о начальном узле, должны начинаться с префикса from__, ключи полей, хранящих информацию о конечном узле должны начинаться с префикса to__.
Ключи полей для ребра (например, для указания веса) могут иметь совершенно произвольное имя.
Важно, чтобы набор полей для начальных и конечных узлов совпадали.
Идея в том, чтобы, отбросив префиксы, виджет мог собрать информацию по всем узлам графа, и эта информация была бы однородной.
Т.е. если в виджете заявлено поле to__legalResidentName, то также должно существовать поле from__legalResidentName, и так далее.
<br/><br/>
Подразумевается, что каждый узел графа – экземпляр некой сущности, а ребро описывает произвольные связи между ними.
Таким образом, в обязательном порядке на БК и на виджете должны присутствовать поля to__id и from__id.
Также, не лишним будет напомнить о необходимости, чтобы каждая запись БК имела уникальное поле id.
В данном случае это поле будет использоваться для внутренней идентификации узла (каждая запись в БК описывает ребро графа).
Неизбежным является обстоятельство дублирования данных по узлам в разных строках таблицы, т.к.
каждый узел может принимать участие во множестве связей.
Дублирование данных не должно смущать, т.к. выше уже упоминалось, что приложение соберет уникальную выборку данных по узлам исходя из предоставленной выдачи данных.
Далее обсудим метаданные виджета и настройки графа.
С точки зрения основных полей метаданных виджета ничего не изменилось.
Заводя виджет, по-прежнему требуется указание id, имени БК, имени виджета, заголовка виджета.
В поле fields требуется указывать те, поля, которые требуются для построения графа.
Т.е. если поле технически есть в выдаче БК, но в блоке fields виджета эти поля не указаны, то для построения и отображения в графе эти поля недоступны.
Граф «видит» только те поля, что отобразятся в табличном виде виджета.
Кстати, табличный виджет, с учетом разработки Графа поддерживает по-прежнему режим отображения в виде таблицы, в виде графиков, и в виде графа.
Переключаться между режимами можно свободно.
Префиксы полей to__ и from__ на отображение графиков не повлияют.
Достаточно у fields указывать человекочитаемые title\label у полей.
<br/><br/>
В БД таблице Widget появилось поле Graph, куда в виде JSON требуется вписывать настройки для графа виджета.
Почти все эти настройки являются необязательными.
Во-первых, содержимое поля Graph – это объект.
Не массив. Этот объект имеет следующую структуру:
<br/>
<pre><b>
"edgeLabel": "Ребро с весом %weight%&amp;#37;",
"nodeLabel": "Узел с названием %name%",
"style": [массив],
"layout": {объект},
"cytoscapeOptions": {объект},
"styleContainer": {объект}
</pre></b>
<br/>

Поле <b>edgeLabel</b> описывает шаблон подписи к ребру. (Вес ребра).
В %% заключаются ключи полей, значения которых для данного ребра отобразятся.
Если подпись к ребру совсем не требуется, поле edgeLabel можно оставить пустой строкой “”, null или не указывать вовсе.
Если в подписи к ребру требуются спец.символы, в том числе и %, то для адекватного отображения подписи (чтобы не сломать макросы полей), спец.символы, и в обязательном порядке % нужно представлять в виде html-сущностей.
Т.е. символ процента представляется в виде &amp;#37; и т.д.
<br/><br/>

Поле <b>nodeLabel</b> описывает шаблон подписи узла. Принципы и правила точно такие же, как и для подписи к ребру.
<br/><br/>

Поле <b>nodeTooltip</b> описывает шаблон всплывающей подсказки узла. Принципы и правила точно такие же, как и для подписи к узлу.
<br/><br/>

Поле <b>nodeDrillDownTarget</b> указывает ключ поля в данных узла, в котором хранится ссылка для дриллдауна.
<br/><br/>

Поле <b>nodeDrillDownType</b> указывает ключ поля в данных узла, в котором хранится тип дриллдауна.
<br/><br/>

Поле <b>layout</b> (необязательное) содержит конфигурационный объект, описывающий свойство layout библиотеки cytoscape.js, на базе которой строится граф.
Свойство layout, если кратко, отражает характеристики слоя, на котором будет строиться граф.
Т.е. координаты, единицы измерения и прочие внутренности.
По сути это влияет на то, как будут располагаться на «холсте» узлы и ребра, как будут перемещаться и как они будут изначально проинициализированы.
Свойство не является для нас обязательным и если его не указывать в мете виджета, граф будет строиться на холсте: layout: {name: “random”}.
Также доступны холсты типа: grid, circle, concentric и т.д.
Подробности здесь (<a href="http://js.cytoscape.org/#layouts">http://js.cytoscape.org/#layouts</a>) P.S.
В самом простейшем случае описывая layout достаточно указать его name и применятся дефолтные настройки библиотеки для этого холста.
Если требуется более тонкая настройка холста, это можно также вписать в layout помимо свойства name.
<br/><br/>

Поле cytoscapeOptions (необязательное) - это конфигурационный объект, который описывает поведение самой библиотеки с позиции пользовательских воздействий (например максимальный и минимальный зум, чувствительность мыши и т.д.).
Пример:
<br/>
<pre><b>
"wheelSensitivity": 0.01,
"boxSelectionEnabled": false,
"autounselectify": true,
"maxZoom": 2,
"minZoom": 0.5
</b></pre>
<br/>
Найти эти настройки можно по адресу (<a href="http://js.cytoscape.org/">http://js.cytoscape.org/</a>) в самой документации, а также в демо-примерах.
<br/><br/>
Поле <b>styleContainer</b> (необязательное) – это конфигурационный объект, содержащий описание css стилей, требуемых для кастомизации той области на странице, в которую будет отрендерен граф.
Например размеры, отступы, фон и т.д.
К примеру, дефолтная высота контейнера, куда будет отрендерен граф – 400px.
Если требуется иной размер – это можно указать в поле styleContainer:
<br/>
<pre><b>
"height": "200px",
"width": "50%",
"border": "1px solid #ff0000"
</b></pre>
<br/>
<br/>
Поле <b>style</b> – самое важное, но необязательное, т.к. мы зашили значение по-умолчанию.
Поле style описывает стиль отображения самого графа.
Это не css стили в чистом виде, но имеют с ними много общего.
О стилизации графа можно почитать здесь: <a href="http://js.cytoscape.org/#style">http://js.cytoscape.org/#style</a> , а также в демопримерах библиотеки (исходные коды примеров открыты и просты для восприятия)
<br/>
<br/>
В style описываются стили узлов и ребер (толщина линий, цвета шрифтов, тип линий ребер (безье, прямая, кривая и т.д.) местоположение и выравнивание подписей, геометрические свойства и т.д., описание того, что должно быть на концах ребер и пр.)
<br/>
Ниже приведен пример дефолтного стиля графа, который нами используется.
<pre><b>
[
  {
    "selector": "node",
    "style": {
      "content": "data(label)",
      "background-color": "#363c49",
      "text-outline-color": "#363c49",
      "text-outline-width": 3,
      "color": "#ffffff",
      "text-valign": "center",
      "text-wrap": "wrap",
      "text-max-width": 110
    }
  },
  {
    "selector": "edge",
    "style": {
      "curve-style": "unbundled-bezier",
      "width": 5,
      "target-arrow-shape": "triangle",
      "source-arrow-shape": "circle",
      "line-color": "#d7d7d7",
      "target-arrow-color": "#d7d7d7",
      "label": "data(label)",
      "edge-text-rotation": "autorotate"
    }
  }
]
</b></pre>
<br/>
Т.е в простейшем случае это два селектора (узел и ребро) и стилевые свойства, применяемые к ним.
В данном случае у узлов указан цвет заливки, цвет и толщина обводки текста, цвет самого текста, вертикальное выравнивание текста узла, а также указана инструкция о переноса слов в названии узла, если длина превышает 110.
У ребер же указан тип линии – безье, ширина линии, форма в виде стрелки со стороны узла-приемника, форма в виде круга, со стороны узла-источника, цвет линии, а также автовращение подписи.
<br/><br/>
Если требуется кастомизация вида графа (например другая толщина, другие цвета формы и т.д.) то требуется полностью описать стили графа, т.к.
указываемые стили в мете виджета не мержатся с дефолтными стилями, приведенными выше.