Controlling the placement of words in the D3 cloud - combining words closer to each other based on some attribute

I am working on an interactive implementation of the D3 tag cloud that relies on each term to have its own category or class. I was able to include the category attribute in the terms by modifying d3.layout.cloud.js as follows:

cloud.start = function() {
  var board = zeroArray((size[0] >> 5) * size[1]),
      bounds = null,
      n = words.length,
      i = -1,
      tags = [],
      data = words.map(function(d, i) {
    return {
      // Added by me
      epidem_category: d['epidem_category'],
      other_details: d['other_details'],
      id: d['id'],
      ///////
      text: text.call(this, d, i),
      size: ~~fontSize.call(this, d, i),
      font: font.call(this, d, i),
      rotate: rotate.call(this, d, i),
      padding: cloudPadding.call(this, d, i)
    };
  }).sort(function(a, b) { return b.size - a.size; });

      

Now I can access d.epidem_category

and also d.id

when drawing the cloud to give certain categories either a different fill color or a rotation value:

 canvas
 .selectAll("text")
 .data(words)
 .enter()
 .append("text")
 .style("font-size", function(d) { return d.size + "px"; })
 .style("font-family", 'Gentium Book Basic')
 .style("fill", function(d, i) { return entity_cloud.set_color(d.epidem_category);})
 .attr("text-anchor", "middle")
 .attr("transform", function(d) {
   return "translate(" + [d.x, d.y] + ")rotate(" + entity_cloud.set_rotation(d.epidem_category) ")";
   })
 .attr("class", function(d) { return d.epidem_category })
 .attr("id", function(d, i) { return d.id })
 .text(function(d) { return d.text; })

      

My problem is that now I would also like to control the placement of the word - I would like all terms of the same category to appear together in the cloud. I thought that maybe I could control this by reordering my input array into categories, assuming the algorithm described in the Jason Davies tag cloud demo page is :

Trying to place the word at some starting point: usually near the middle or somewhere on the center horizontal line.

.. Thus, according to this logic, if the first, for example, 10 words have the same category, they should appear in a bundle somewhere in the middle, the rest of the categories will follow a circular pattern. However, testing this result did not lead to the expected result. In fact, I have seen very little change in the layout.

Does anyone have any ideas on how to achieve a layout where terms are combined based on some attribute?

+3


source to share





All Articles