D3 Circular bag with horizontal layout

I am trying to create a wordcloud with a D3 layout with horizontal layout.

Instead of limiting the width, I limit the height.

The package layout automatically distributes circles with a large one in the center and surrounding. If height is limited, instead of horizontally spacing the circles, it reduces the size of each circle.

How can I stop the layout from resizing circles and start adding them to the sides if there is no more space around the larger one.

I want something like this: http://imgur.com/7MDnKHF

But I just achieved this: http://jsfiddle.net/v9xjra6c/

This is my current code:

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(' + dx + ',' + dy + ')'; }); node.append('title') .text(function(d) { return d.name + ': ' + format(d.value); }); node.append('circle') .attr('r', function(d) { return dr; }); node.append('text') .attr('dy', '.3em') .style('text-anchor', 'middle') .text(function(d) { return d.name.substring(0, dr / 3); }); }; initSizes(); initLayout(); createSVG(); createBubbles(); 

Thanks!

+5
source share
1 answer

Your solution will be like combining this Example1 + Example2

So, from example 1, I took the mechanism to limit the circles in the borders so that it does not exceed the height and width of 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 dx = Math.max(50, Math.min(width - 50, dx)); }) //max radius is 50 restricting on the height .attr("cy", function(d) { return dy = Math.max(50, Math.min(height - 50, dy)); }); } 

Creating a Radius Scale

 //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]); 

Make the data according to example 2

 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 }); 

Finally, the result will look like this

Note. You can reduce the height of the code and the circles will switch according to the available space.

Note. . You can also play around the cluster to group similar nodes, as in the example in my case I have made one group cluster.

Hope this helps!

+3
source

Source: https://habr.com/ru/post/1235708/


All Articles