Как стать автором
Обновить

Java — Знакомство с JUNG Framework

0. Введение


Недавно получил заказ на написание системы, визуализирующей процессы взаимодействия различных генов и молекул. Работу было предложено выполнить, используя JUNG Framework. О знакомстве с ним хотелось бы рассказать.

1. Что такое JUNG


JUNG — the Java Universal Network/Graph FrameworkFramework — библиотека на языке Java, предоставляющая расширяемый язык для моделирования, анализа и визуализации данных, которые могут быть представлены в виде графа или сети.
Собственно, в данной работе элементы (гены, молекулы) являются вершинами графа, а реакции между ними – ребрами.

2. Начало работы


Для начала были разработаны классы Junction и Reaction. Junction — элемент (вершина). Reaction – реакция между элементами.
Теперь нужно создать граф, использующий их в качестве вершин и ребер.
Graph<Junction, Reaction> graph = new SparseMultigraph<Junction, Reaction>();

* This source code was highlighted with Source Code Highlighter.
Таким образом создается граф с вершинами типа Junction и ребрами типа Reaction.
Теперь необходимо заполнить новый граф. Делается это двумя методами:
Graph.addVertex(Junction vertex); //добавляем вершину типа Junction
Graph.addEdge(Reaction edge, Junction vertex1, Junction vertex2, EdgeType.DIRECTED); //добавляем ребро между вершинами vertex1 и vertex2


* This source code was highlighted with Source Code Highlighter.
EdgeType.DIRECTED показывает, что при отображении должна рисоваться стрелка, указывающая направление ребра (в данном случае, направление реакции, т. е. какой элемент на какой воздействует).
Все исходные данные читались из файла и заносились в массив Junction[], который передавался методу заполнения графа.
Теперь необходимо было построить красивые деревья для отображения, показывающие, как элементы воздействуют друг с другом.
Forest<Junction, Reaction> tree;
MinimumSpanningForest2<Junction, Reaction> prim = new MinimumSpanningForest2<Junction, Reaction>(graph, new DelegateForest<Junction, Reaction>(), DelegateTree.<Junction, Reaction> getFactory(), new ConstantTransformer(1.0));
tree = prim.getForest();


* This source code was highlighted with Source Code Highlighter.
Здесь используется алгоритм MinimumSpanningForest2 из библиотеки JUNG, который строит из исходного графа деревья.

3. Отображение


Для отображения полученного графа или дерева можно использовать множество вариантов. Я выбрал TreeLayout.
Layout<Junction, Reaction> layout = new TreeLayout<Junction, Reaction>(tree); //создаем новый layout для полученного дерева
Layout<Junction, Reaction> mainLayout = new StaticLayout<Junction, Reaction>(graph, layout); //… и Layout для графа


* This source code was highlighted with Source Code Highlighter.
Теперь нам нужно создать панель, где граф будет отрисовываться.
VisualizationViewer<Junction, Reaction> vv = new VisualizationViewer<Junction, Reaction>(mainLayout, new Dimension(800, 400));

* This source code was highlighted with Source Code Highlighter.
VisualizationViewer расширяет JPanel, и ему доступны все его методы.
Теперь немного о фичах самого VisualizationViewer’а. Можно задать различные виды отображений для вершин и ребер, в зависимости от их типов. Для этого необходимо воспользоваться интерфейсом Transformer из библиотеки org.apache.commons.collections. Напишем три трансформера: для вывода названия элемента, для цвета различных реакций (активирующая или блокирующая, поле type в классе Reaction) и для цвета элементов в различном состоянии (активный или неактивный, так же поля в классе Junction).
Transformer<Junction, String> stringer = new Transformer<Junction, String>() {
  public String transform(Junction e) {
    if ("gene".equals(e.biologicalProperty)) {
      return e.name + " (gene)";
    }
    return e.name;
  }
}; //выводим имя элемента (если это ген, то добавляем соответствующую пометку)

Transformer<Reaction, Paint> edgePaint = new Transformer<Reaction, Paint>() {
  public Paint transform(Reaction r) {
    if (r.type == 1) {
      return Color.red;
    } else {
      return Color.blue;
    }
  }
}; //если реакция активации (type==1), то ребро должно быть красным, иначе – синим

Transformer<Junction, Paint> vertexPaint = new Transformer<Junction, Paint>() {
  public Paint transform(Junction e) {
    if (e.upregulated == true) {
      return Color.orange;
    } else {
      return Color.gray;
    }
  }
}; //активные вершины оранжевые, неактивные – серые


* This source code was highlighted with Source Code Highlighter.
Далее, необходимо добавить эти трансформеры в RenderContext нашего VisualizationViewer’а:
vv.getRenderContext().setVertexLabelTransformer(stringer);
vv.getRenderContext().setEdgeDrawPaintTransformer(edgePaint);
vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);


* This source code was highlighted with Source Code Highlighter.
Ну и в конце создается pane GraphZoomScrollPane, где и будет располагаться VisualizationViewer:
GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);

* This source code was highlighted with Source Code Highlighter.
GraphZoomScrollPane реагирует на скролл мыши. Таким образом можно масштабировать полученное изображение.

4. Завершение


Теперь оставалось лишь создать апплет с необходимыми элементами управления и добавить туда panel. Описывать это я не буду, т. к. оно больше относится уже непосредсвенно к работе с JAVA SWING.
Стоит также добавить, что к VisualizationViewer’у можно добавить элемент GraphMouse. Есть DefaultModalGraphMouse, который позволяет работать в двух режимах: transforming и picking. Первый позволяет перетаскивать весь граф целиком по экрану, крутить вокруг своей оси или растягивать относительно какой-то точки. Второй, picking, дает возможность перетаскивать мышью отдельные вершины. Ну и в обоих режимах доступно масштабирование изображения.
Кроме этого, существует EditingModalGraphMouse, который предоставляет широкие возможности для редактирования элементов графа.

5. Ссылки


Здесь я рассмотрел лишь основы работы с JUNG Framework. Больше вы можете узнать здесь:
http://jung.sourceforge.net/ — официальный сайт проекта;
http://jung.sourceforge.net/applet/index.html — куча примеров;
http://jung.sourceforge.net/doc/api/index.html — собственно, JavaDoc.

Ну и собственно моя работа:
http://systems.drugdiscoveryathome.com/?q=node/36 (апплет протестирован в Opera (9.64, 10), IE (6, 7), Firefox (3.5.2), должен работать; необходим JRE 1.5 и выше).
Можете там на кнопочки потыкать, помоделировать что-нибудь ;)
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.