Алгоритмы для рисования графиков с высоким отношением детей к родителям
Я работаю над инструментом визуализации для документа Excel, содержащего относительно большой объем бизнес-требований (70 элементов данных).
Цель состоит в том, чтобы показать некоторые внутренние структуры данных, которые не сразу очевидны при взгляде на файл Excel. Структура выглядит примерно так:
корень -> (
(компонент 1)--->(подкомпонент a)--->(элемент данных 1, элемент данных 2, ..., элемент данных 30),
(компонент 2)--->(подкомпонент a)--->(элемент данных 1, элемент данных 2, ..., элемент данных 30),
(компонент 3)--->(подкомпонент a)--->(элемент данных 2, элемент данных 2, ..., элемент данных 30)
)
Что я заметил, так это:
Графики хороши для отображения структуры, но отстой в отображении данных. Таблицы хороши для отображения данных, но отстой в отображении структуры.
На данный момент я больше не могу использовать автоматическое расположение GraphStream по умолчанию. Из-за большого количества элементов данных, прикрепленных к одному субкомпоненту, автоматическая разметка не может позиционировать эти элементы таким образом, чтобы они не перекрывались и становились невозможными для чтения. То, что происходит, является своего рода цветочным эффектом, когда элементы данных похожи на перекрывающиеся лепестки вокруг их родителя.
Если я отключаю автопоставку, я должен сам размещать узлы. Graphstream говорит следующее:
Вы фиксируете координаты, как хотите. Единицы, которые вы используете, будут называться "Графические единицы". Однако, как вы увидите позже, программа просмотра поддерживает две другие единицы: пиксели и проценты.
http://graphstream-project.org/doc/Tutorials/Graph-Visualisation/1.0/
Хорошо, как оказалось, или это сложная проблема, или я медленный. Я не смог позиционировать узлы читабельным способом.
Вещи, которые я пробовал:
- Позиционирование дочерних элементов относительно их родительских элементов : перебирайте узлы с циклами for (в ретроспективе, возможно, стоит реализовать это рекурсивно для поддержки n уровней), начиная с root. Определите число потомков корня, деленное на 2 (3/2 = 1 с целочисленным делением), назовите эту середину. Установите для компонента 1 X положение i - middle. Установите позицию y в положение корня y - 1. Таким образом, я могу создать структуру "дерево", где родительский элемент расположен по центру над его дочерними элементами.
Дети других людей, что не так с этим миром...
К сожалению, это не очень хорошо работает на практике. С любым отдельным компонентом все в порядке, но если на том же уровне есть другие родители, их дети пересекаются с детьми всех остальных родителей. Это происходит потому, что дети позиционируются относительно своих родителей и не подозревают, что фактически занимаемая ими позиция уже занята чужими детьми.
Так что теперь я не знаю, что делать. Я не могу позиционировать узлы с учетом узлов, которые еще не существуют. У меня есть несколько фрагментов идеи, но все они кажутся запутанными.
Поэтому, прежде чем я углублюсь в адский код, я задал этот вопрос, потому что мне кажется, что я не могу быть первым человеком, который должен нарисовать читабельный график, и, вероятно, существуют установленные способы сделать это.
Для справки это фрагменты идеи:
Сделайте так, чтобы отдельные элементы графа отвечали за свою собственную позицию, и пусть они позиционируют себя относительно своих дочерних элементов или их отсутствия.
Посмотрите на манипулирование камерой в сочетании с некоторым решением для позиционирования. Ограничьте количество узлов, которые могут быть видны в данный момент (убивайте детей других людей, если их слишком много). Используйте масштабирование и панорамирование в зависимости от того, какой компонент нажат.
Рекурсия. Это слово, которое я знаю. Шучу в сторону, я раньше использовал рекурсию, и я чувствую, что графы, особенно такие, как мой, без циклических структур в них, практически просят рекурсивное решение. Я действительно, в другом проекте использовал рекурсивный подход для рисования графиков, но я оказался в той же ситуации. Как я могу знать о рекурсивных путях, рисующих детей других родителей? Возможно, мне все еще стоит подумать о некоторых рекурсивных подходах.
Создайте новую структуру данных, которая представляет относительную недвижимость в области просмотра. Разбейте на области, узлы занимают относительные области, 2 узла не могут занимать одну и ту же относительную область. Выясните, что делать, когда кто-то пытается сесть на чужого ребенка. Я придумал это, когда писал этот пост на самом деле.
Это все, что у меня есть, что вы, ребята, думаете? Есть какой-нибудь хорошо известный алгоритм позиционирования узла, который уже решает мою проблему? Какие из моих фрагментов идеи кажутся наиболее перспективными?