Сравнение графических схем рисования java-графики с открытым исходным кодом (JUNG и Prefuse) для построения топологии сети
какую из графических схем рисования Java с открытым исходным кодом использовать для сетевой диаграммы со следующими требованиями? График будет содержать менее 1000 узлов.
1) имеет параллельные ребра
2) направленные и неориентированные ребра внутри одного графа
3) узлы, представленные изображениями
4) взаимодействие пользователя с узлами и ребрами
5) динамическое добавление/удаление узлов и ребер
6) множественная маркировка на узлах и ребрах, различные уровни маркировки могут быть отключены/включены пользователями. (например, рисование слоев и выключение/на слой)
7) различные алгоритмы компоновки для отображения звездных, кольцевых, топографических топологий
Я оценил JUNG и Prefuse. Это то, что я нашел для каждого из моих требований.
1) Prefuse не может отображать параллельные края, в то время как JUNG поддерживает его. Можно ли обработать код предварительной обработки для отображения параллельных ребер? Так как это связано с основными изменениями уровня данных, я считаю, что это будет сложнее, если изменится обычный настраиваемый рендеринг.
2) Я не нашел ссылки на комбинированный график (как направленный, так и неориентированный) как в prefuse, так и в JUNG. Кто-нибудь знает иначе?
3) Это кажется легким как с Prefuse, так и с JUNG
4) Опять же, как prefuse, так и JUNG обеспечивают поддержку взаимодействия с пользователем.
5) Оба prefuse и JUNG поддерживают его. Как выполняется каждая структура при перерисовке графика? Я видел в другом сообщении, что префикс не работает хорошо для динамических обновлений ( Prefuse Toolkit: динамическое добавление узлов и ребер)
6) Это сводится к изменению графика и его перерисовке. Таким образом, вопрос становится таким же, как 5)
7) И JUNG, и prefuse имеют несколько алгоритмов компоновки. Но когда я попытался отобразить один и тот же набор данных, используя FruchtermanReingoldLayout в JUNG и Prefuse, я получаю разные дисплеи. Любые идеи почему? Как бы то ни было, алгоритмы компоновки в Prefuse выглядят лучше, чем в JUNG (рендеринг также лучше, я думаю), хотя большинство алгоритмов компоновки в Prefuse основаны на реализации JUNG.
Планы предварительной обработки, такие как ForceDirectedLayout/FruchtermanReingoldLayout и CircleLayout, непосредственно отображаются в топологии звезд, кругов, сеток.
Помимо этих требований, prefuse имеет хорошую поддержку выражений и языка запросов, но похоже, что он не активно развивается в отличие от JUNG. какой из них лучше визуализировать? Любые предложения, по которым будет целесообразным, и как преодолеть недостатки?
Какие-нибудь другие рамки, которые я могу использовать?
Ответы
Ответ 1
Несколько лет назад (2007?) Я использую prefuse для визуализации записей данных звонков. Я считал prefuse, jung, jgraph и некоторые другие и выбрал prefuse. Сначала немного сложно обернуть голову вокруг префайла, но как только я познакомился с ней, это очень просто (продлить) и весело использовать. Я думаю, что то же самое можно сказать о JUNG, но я никогда не пробовал.
1) В prefuse очень легко добавить свой собственный рендерер для рисования параллельных ребер - вы можете подклассифицировать EdgeRenderer по умолчанию и переопределить метод render(). Там нет "базовых изменений уровня данных". Это все в части представления, если вы хотите думать об этом как о роли MVC.
2) Это совсем не проблема. Существует несколько способов сделать это: 1) У вас могут быть два средства рендеринга: один для рисования направленных ребер и один для рисования неориентированных ребер, и они будут работать очень хорошо, и соответствующим образом группировать ребра. 2) Поместите флаг (добавьте булевский столбец в корневой таблице поддержки в prefuse speak), чтобы указать, направлено ли ребро, и пропустить часть чертежа стрелки соответственно в EdgeRender в соответствии с этим флагом.
3) Это очень просто
4) ditto
5) Последний выпуск prefuse - "prefuse beta release 2007.10.21". Я использовал тот, который был до этого, у которого есть возможное состояние гонки при добавлении или удалении узлов динамически - на нем не хватало нескольких синхронизированных ключевых слов, которые я предполагаю. Я решил, что, останавливая все анимацию и действия (цвет, размер, макет) при добавлении или удалении узлов, также не забывайте обновлять свои индексы lucene (если вы используете встроенную поисковую систему lucene). Последний должен решить этот вопрос гонки, но у меня не было возможности попробовать его.
6) Поскольку вы упомянули "множественную маркировку", я думаю, что это не вопрос "изменения графика и его перерисовки" - это всего лишь вопрос настройки рендеринга метки/края для рисования только соответствующих ярлыков, чтобы на самом деле это не было большой вопрос. Также я не думаю, что это связано с 5 вообще.
7) Я не удивлен, что префьюза и JUNG-рендеринг FruchtermanReingoldLayout отличаются друг от друга - есть несколько факторов, которые могут повлиять на это один из них, начиная с node, где каждая реализация запускает расчет, поэтому я не буду волноваться много об этой проблеме. Очень легко попробовать различные алгоритмы построения встроенных графов в prefuse, чтобы вы могли пойти дальше и проверить, какой из них ближе всего к тому, что вы хотели бы иметь. Посмотрите RadialLayout и BalloonTreeLayout для макета звезды. ForceEirectedLayout требует довольно много итераций для размещения узлов как "стабильных". Обратите внимание, что эти итерации необязательно отображаться, поэтому вы можете запустить его в фоновом режиме и сделать окончательный результат.
Я не использую JUNG, поэтому я не могу много комментировать.
Основываясь на моем опыте использования prefuse, я очень рекомендую его благодаря продуманному дизайну (IMHO) и разделимости между компонентами. Джеффри Хеер (автор prefuse) действительно хорошо поработал там.
Вещи, которые следует учитывать, если вы используете prefuse (это два "боль-большие пальцы", которые я живо помню при работе с prefuse):
1) Там, где при масштабировании метки node не масштабируются соответствующим образом, так что она переполняет ограничивающий прямоугольник node, который оставит артефакты рисования шрифта, когда движется node, потому что средство визуализации только очищает и перерисовывает материал в ограничительной рамке node. IIRC это вызвано ошибкой в метрике AWT. Обходной путь заключается в том, чтобы оставить достаточный запас между меткой и ограничивающим прямоугольником node.
2) При расширении встроенных макетов вы можете столкнуться с одной или двумя проблемами с областью определения, где члену суперкласса, к которому вы хотите получить доступ, присваивается частный атрибут вместо защищенного, поэтому решение либо самостоятельно изменить библиотеку, либо создать новый класс без наследования (это может быть немного больно!). Я думаю, вы можете сказать то же самое для некоторых других java-библиотек. Не все имеют преимущество задним числом нет?:)
Поскольку вы задали этот вопрос около месяца назад (во время моего написания этого), я хотел бы знать, каково ваше решение и как это получилось для вас, если вы продолжите реализацию.
Ответ 2
Я один из создателей и разработчиков JUNG, поэтому не забывайте об ответах ниже.
Во-первых, я должен сказать, что автор Prefuse - друг друга (и да, мы встретились), и он отлично поработал. У меня нет опыта с Prefuse, но я видел некоторые красивые визуализации, созданные с ним.
Вот ответы на эти вопросы для JUNG. Некоторые из них ((1), (2), (4) показаны в PluggableRendererDemo
:
- Поддерживается (вам нужна правильная модель данных, не все поддерживают параллельные грани по соображениям производительности).
- Поддерживается (опять же, вам нужна правильная модель данных)
- Поддерживается (см.
ImageShaperDemo
)
- Поддерживается (большинство демо)
- Поддерживается (см.
GraphEditorDemo
)
- Не поддерживается напрямую, хотя вы можете динамически изменять ярлыки и использовать HTML для отображения сложных меток.
- Алгоритмы компоновки JUNG больше подходят для общих сетей (за несколькими исключениями для деревьев и т.д.). Однако вы можете, конечно, создать свои собственные алгоритмы компоновки, и многие это сделали.
Надеюсь, что это поможет.
Ответ 3
Я знаю, что вы указали jung и prefuse, но...
У меня был хороший опыт работы с TomSawyer и yFiles. Список требований, который вы предложили, очень важен для этих двух - и они поддерживают гораздо больше.
Ран.
Ответ 4
Я бы предложил оценить JGraph.
Ответ 5
Мне нравится @holygeek ответ. Вот моя реализация для решения для 2 (как направленных, так и неориентированных ребер), для Prefuse:
public class MyRenderFactory implements RendererFactory
{
private NodeRenderer nodeRenderer = new NodeRenderer();
private EdgeRenderer defaultEdgeRenderer = new EdgeRenderer();
private EdgeRenderer undirectedEdgeRenderer = new EdgeRenderer(EdgeRenderer.EdgeType.LINE, EdgeRenderer.EdgeArrowType.NONE);
public static String directedness = "myEdgeDirectedness";
public enum EdgeDirected
{
directed, undirected;
public static EdgeDirected fromIsDirected(boolean isDirected)
{
if (isDirected)
{
return directed;
}
return undirected;
}
}
@Override
public Renderer getRenderer(VisualItem<?> visualItem)
{
if (visualItem instanceof EdgeItem)
{
if (visualItem.get(directedness).equals(PrefuseGraphConverter.EdgeDirected.undirected))
{
return undirectedEdgeRenderer;
}
return defaultEdgeRenderer;
}
return nodeRenderer;
}
}
... в другом месте, где создается граф...
MyRenderFactory.EdgeDirected directedness =
MyRenderFactory.EdgeDirected.fromIsDirected(myEdge.isDirected());
prefuseEdge.set(MyRenderFactory.directedness, directedness);