D3 круговая компоновка пакета с горизонтальным расположением


Я пытаюсь создать wordcloud с компоновкой пакета D3 с горизонтальным расположением.

Вместо того чтобы ограничивать ширину, я ограничиваю высоту.

Компоновка пакета автоматически распределяет круги с большим в центре и другими вокруг него. Если высота ограничена, то вместо того, чтобы расширять расположение кругов по горизонтали, он уменьшает размер каждого круга.

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

Я хочу что-то вроде этого: http://imgur.com/7MDnKHF

Но я только достигаю этого: http://jsfiddle.net/v9xjra6c/

Это мой текущий код:

var width,
    height,
    diameter,
    padding,
    format,
    pack,
    svg,
    node;

var initSizes = function() {
    var dimensions = { width: 900, height: 288 };
    width = dimensions.width;
    height = dimensions.height;
    diameter = Math.min(width, height);
    padding = 12;
    format = d3.format(',d');
};

var initLayout = function() {
    pack = d3.layout.pack()
        .sort(null)
        .size([width, height])
        .padding(padding);
};

var createSVG = function() {
    svg = d3.select('.chart-container').append('svg')
        .attr('width', width)
        .attr('height', height)
        .attr('class', 'bubble');
};

var createBubbles = function() {
    var dataset = pack.nodes(DATA);

    node = svg.selectAll('.node')
        .data(dataset.filter(function(d) { return !d.children; }))
        .enter().append('g')
        .attr('class', 'node')
        .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; });

    node.append('title')
        .text(function(d) { return d.name + ': ' + format(d.value); });

    node.append('circle')
        .attr('r', function(d) { return d.r; });

    node.append('text')
        .attr('dy', '.3em')
        .style('text-anchor', 'middle')
        .text(function(d) { return d.name.substring(0, d.r / 3); });
};

initSizes();

initLayout();

createSVG();

createBubbles();

Спасибо!

1 5

1 ответ:

Ваше решение будет похоже на слияние этого примера 1 + Пример 2

Итак, из примера 1 я взял механизм ограничения окружностей в границах, чтобы он не выходил за пределы высоты и ширины svg:

function tick(e) {
      node
          .each(cluster(10 * e.alpha * e.alpha))
          .each(collide(.5))
          //max radius is 50 restricting on the width
          .attr("cx", function(d) {  return d.x = Math.max(50, Math.min(width - 50, d.x)); })
          //max radius is 50 restricting on the height
          .attr("cy", function(d) { return d.y = Math.max(50, Math.min(height - 50, d.y)); });        }

Создание шкалы для создания радиуса

//so now for your data value which ranges from 0 to 100 you will have radius range from 5 to 500
var scale = d3.scale.linear().domain([0,100]).range([5, 50]);

Сделайте данные в соответствии с Example2

var nodes = data.map(function(d){
  var i = 0,
      r = scale(d.value),
      d = {cluster: i, radius: r, name: d.name};  
  if (!clusters[i] || (r > clusters[i].radius)) {clusters[i] = d;}
  return d
});

В итоге результат будет выглядеть так: это

Примечание: Вы можете уменьшить высоту в коде и круги будут переставляться в соответствии с имеющимся пространством.

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

Надеюсь, это поможет!