Управляйте макетом пакета d3.js с помощью ввода диапазона HTML5

У меня есть этот http://jsfiddle.net/thechrisjordan/p4Fwm/11/, где я Я управляю макетом пакета d3 с помощью ползунка HTML5. Все работает так, как я хотел, за исключением того, как упорядочены узлы при вызове updateVis().

Этот код довольно прост: я создаю макет, а затем ползунок генерирует событие, которое вызывает обновление макета.

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

Похоже, моя проблема связана со строкой 69, где вызывается pack.nodes(data);. Я копался в источнике d3, но не могу понять, как предотвратить это переупорядочение (и это вполне может быть невозможно...).

Я полагаю, что альтернативой было бы попытаться втиснуть макет пакета в макет силы.

Я новичок в d3 и благодарен за любую информацию здесь.


person chrisjordanme    schedule 10.03.2014    source источник
comment
К сожалению, это не поддерживается компоновкой пакета — вам придется изменить исходный код (что вполне может быть нетривиальной модификацией).   -  person Lars Kotthoff    schedule 11.03.2014
comment
Спасибо, @LarsKotthoff. Судя по сайту, похоже, я упустил из виду метод сортировки, доступный для макетов пакетов. Это то, что я получаю за то, что копаюсь в исходниках и игнорирую документы :)   -  person chrisjordanme    schedule 11.03.2014


Ответы (1)


Если я понял, что вы просите сделать, я уверен, что это выполнимо. Вот скрипка; Я добавил немного веселья RGB, чтобы помочь отслеживать круги.

Это делается с помощью метода sort() макета пакета, который гарантирует, что они расположены в постоянном порядке. Чтобы добиться этого, мне пришлось присвоить значение index каждому из объявленных вами объектов (и необязательному цвету RGB):

data.children.forEach(function(d, i) {
    d.index = i;
    d.fill = ['#c33','#3c3','#33c'][i];
});

Тогда нужно использовать index для сортировки:

var pack = d3.layout.pack()
  .size([diameter - 4, diameter - 4])
  .sort(function(a,b) { return d3.ascending(a.index, b.index); }) // <--- this
  .value(function(d) { return d.size; });

Надеюсь, это помогло.

person meetamit    schedule 10.03.2014
comment
Мужик, огромное спасибо! Я думал, что, возможно, есть способ сделать это, и я думаю, что пропустил это в документах. Я все еще осваиваю d3, так что мне пришлось многое переварить. Спасибо еще раз; это была огромная помощь. - person chrisjordanme; 11.03.2014