2014-01-03 3 views
6

У меня есть набор данных, где каждый образец имеет размер (0-1000) и значение (класс 1-5). Я хочу, чтобы визуализировать данные с кругами разных размеров вдоль линии (оси области), так же, как:упаковка d3.js вокруг линии

http://www.nytimes.com/interactive/2013/05/25/sunday-review/corporate-taxes.html?_r=1&

(заметим, что круги, даже с той же эффективной TaxRate не перекрываются)

Пример данные:

  • образец 1: 300 размер значение 3,2
  • образец 2: размер 45 значение 3.8
  • образец 3: Размер 4400 значение 4,0
  • Образец 5: размер 233 значения 0,2
  • Образец 6: Размер 4000 значения 4,2

Как можно выше данные можно визуализировать с помощью кругов на линии (размера решает диаметр, значение определяет приблизительную позицию на линии), чтобы круги не перекрывались?

Я смотрел макет упаковки D3, но из того, что я могу сказать, не поддерживает это из коробки. У кого-нибудь есть идеи о том, как подойти к этому?

+0

Если это прямая все, что вам нужно будет сделать, это суммируют диаметры предыдущих кругов, чтобы получить позицию для нового круга. –

+0

@LarsKotthoff: Не могли бы вы немного рассказать (я обновил вопрос)? – jrydberg

ответ

17

Оооо, это одна была головоломка ...

Если вы посмотрите на код графического NYTimes, он использует предварительно вычисленные координаты в файле данных, так что это не много пользы.

Однако в начале скрипта есть неиспользованное объявление переменной, в котором намекает, что исходная версия использовала d3.geom.quadtree для выкладки кругов. Квадратура на самом деле не является способом компоновки; он используется для создания дерева поиска соседних узлов, так что, когда вам нужно найти узел в данной области, вам не нужно искать весь набор. Example here.

Таким образом, квадрант может использоваться для определения того, какие из ваших точек данных могут перекрываться друг с другом по оси x. Затем вы должны выяснить, сколько вам нужно, чтобы компенсировать их, чтобы избежать дублирования. Переменные радиусы осложнят обе функции ...

У меня есть тестовый пример реализован здесь: http://fiddle.jshell.net/6cW9u/5/

Алгоритм упаковка не является совершенным: Я всегда добавлять новые круги наружу существующих кругов, без проверяя, могут ли они подойти ближе, поэтому иногда вы получаете значительные лишние пробелы, когда это только крайние края окружностей натыкаются друг на друга. (Запустите его несколько раз, чтобы получить представление о возможностях - обратите внимание, что у меня есть x-переменные, распределенные как случайные нормальные и r-переменные, распределенные как случайные униформы.) Я также получил переполнение стека по рекурсивным методам во время одного итерации с N = 100 - случайное распределение явно недостаточно распределялось для оптимизации квадранта.

Но у него есть базовая функциональность. Оставьте комментарий здесь, если вы не можете следовать логике комментариев к коду.

--ABR

Update

Новой скрипка здесь: http://fiddle.jshell.net/6cW9u/8/

После долгой перестановки, я получил алгоритм упаковки для поиска пробелов между существующими пузырями. У меня упорядоченный порядок сортировки (так что первые круги добавляются в первую очередь), чтобы показать, как маленькие круги могут быть добавлены в пробелы - хотя, как я упоминаю в комментариях к коду, это снижает эффективность поиска quadtree.

Также добавлено различное украшение и переход, чтобы вы могли четко видеть, как расположены круги, и установите r-масштаб в квадратный корень, поэтому площадь (не радиус) пропорциональна значению в данных (что более реалистично, и то, о чем попросил ОП).

+0

Блестящий! Я хочу также добавить, что первоначальная визуализация на самом деле не точно отражает данные по горизонтальной оси - если вы внимательно изучите данные, которые отображаются во всплывающих подсказках, вы увидите это. Таким образом, позиции корректируются вручную или нет, и мы видим только жесткий код. – VividD

+0

Я бегу скрипку с N = 125, а макеты вполне удовлетворительные, даже красивые, однако, похоже, что есть ошибка (может быть, то же, что вы упомянули), которая время от времени врывается, и помещает почти все круги вправо на оси ... – VividD

+0

Да, это то, что происходит, когда стек переполняется - вы не получаете действительного смещения y. Кажется, что это связано с значениями x вне области I, установленной в степени квадранта. Поэтому логичным было бы убедиться, что вы устанавливаете размер квадранта на основе фактического диапазона данных. * (Я обманул в своей обновленной скрипке и просто использовал значение, достаточно большое, чтобы вероятность того, что моя случайная нормальная внешность была вне его, была очень маленькой.) * – AmeliaBR

1

Расположение упаковки D3 не является ответом здесь. Он размещает круги по спирали по существующей группе. Вот мне обратный инжиниринг алгоритма за макетом упаковки:

enter image description here

Я хотел бы предложить force layout-подход. Таким образом, вы можете привести свои узлы к гравитационному центру, а затем позволить гравитации сделать свое дело.

Силовые макеты (например, Clustered Force Layout I) обычно являются анимациями, поэтому вы хотите применить static force layout.

Я завернутый этот подход in an example block, который выглядит следующим образом:

circles on a line in a static force layout

Смежные вопросы