Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Create a Cloud Chart? [closed]

Tags:

javascript

I've seen these charts referred to as tag clouds, task clouds, and cloud charts, but can anyone recommend a pure JavaScript (no Flash please) library or utility with which one can generate cloud charts? Many thanks.

like image 667
Upperstage Avatar asked Dec 14 '09 16:12

Upperstage


People also ask

Can I create a word cloud in Powerpoint?

You can select a font, color scheme, layout, case, and importantly, the size of the world cloud that you want to generate. Select some text on your slide, and click on Create Word Cloud – and just like that, you'll get your word cloud.


1 Answers

Quoting "Showcase your skillset with an interactive colorful D3.js tag cloud", here's a working example of how to create such a cloud. It is based on Jason Davies' cloud layout calculation script (in turn inspired by Wordle) which is used to drive D3.js for drawing the cloud.

enter image description here

You can see working sample embedded below and also in jsfiddle.

The entire example can be found on GitHub at: https://github.com/bbottema/d3-tag-skills-cloud


First define your cloud data, using text and size properties:

var skillsToDraw = [
    { text: 'javascript', size: 80 },
    { text: 'D3.js', size: 30 },
    { text: 'coffeescript', size: 50 },
    { text: 'shaving sheep', size: 50 },
    { text: 'AngularJS', size: 60 },
    { text: 'Ruby', size: 60 },
    { text: 'ECMAScript', size: 30 },
    { text: 'Actionscript', size: 20 },
    { text: 'Linux', size: 40 },
    { text: 'C++', size: 40 },
    { text: 'C#', size: 50 },
    { text: 'JAVA', size: 76 }
];

Next you need to use the layout script to calculate the placement, rotation and size of each word:

d3.layout.cloud()
    .size([width, height])
    .words(skillsToDraw)
    .rotate(function() {
        return ~~(Math.random() * 2) * 90;
    })
    .font("Impact")
    .fontSize(function(d) {
        return d.size;
    })
    .on("end", drawSkillCloud)
    .start();

Finally implement drawSkillCloud, which performs the D3 drawing:

// apply D3.js drawing API
function drawSkillCloud(words) {
    d3.select("#cloud").append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + ~~(width / 2) + "," + ~~(height / 2) + ")")
        .selectAll("text")
        .data(words)
        .enter().append("text")
        .style("font-size", function(d) {
            return d.size + "px";
        })
        .style("-webkit-touch-callout", "none")
        .style("-webkit-user-select", "none")
        .style("-khtml-user-select", "none")
        .style("-moz-user-select", "none")
        .style("-ms-user-select", "none")
        .style("user-select", "none")
        .style("cursor", "default")
        .style("font-family", "Impact")
        .style("fill", function(d, i) {
            return fill(i);
        })
        .attr("text-anchor", "middle")
        .attr("transform", function(d) {
            return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
        })
        .text(function(d) {
            return d.text;
        });
}

That's the basic. You can influence the size and which angles are used for picking random rotations as well as some padding between words if you wish and color fill, but these are the basics!

See it at work in the snippet (or jsfiddle):

// First define your cloud data, using `text` and `size` properties:

var skillsToDraw = [
	{ text: 'javascript', size: 40 },
	{ text: 'D3.js', size: 15 },
	{ text: 'coffeescript', size: 25 },
	{ text: 'shaving sheep', size: 25 },
	{ text: 'AngularJS', size: 30 },
	{ text: 'Ruby', size: 30 },
	{ text: 'ECMAScript', size: 15 },
	{ text: 'Actionscript', size: 10 },
	{ text: 'Linux', size: 20 },
	{ text: 'C++', size: 20 },
	{ text: 'C#', size: 25 },
	{ text: 'JAVA', size: 38 },
  // just copy data and reduce size, else the cloud is a little boring
	{ text: 'javascript', size: 40 },
	{ text: 'D3.js', size: 15 },
	{ text: 'coffeescript', size: 25 },
	{ text: 'shaving sheep', size: 25 },
	{ text: 'AngularJS', size: 30 },
	{ text: 'Ruby', size: 30 },
	{ text: 'ECMAScript', size: 15 },
	{ text: 'Actionscript', size: 10 },
	{ text: 'Linux', size: 20 },
	{ text: 'C++', size: 20 },
	{ text: 'C#', size: 25 },
	{ text: 'JAVA', size: 38 },
	{ text: 'javascript', size: 40 },
	{ text: 'D3.js', size: 15 },
	{ text: 'coffeescript', size: 25 },
	{ text: 'shaving sheep', size: 25 },
	{ text: 'AngularJS', size: 30 },
	{ text: 'Ruby', size: 30 },
	{ text: 'ECMAScript', size: 15 },
	{ text: 'Actionscript', size: 10 },
	{ text: 'Linux', size: 20 },
	{ text: 'C++', size: 20 },
	{ text: 'C#', size: 25 },
	{ text: 'JAVA', size: 38 }
];

// Next you need to use the layout script to calculate the placement, rotation and size of each word:

    var width = 500;
    var height = 500;
    var fill = d3.scale.category20();

    d3.layout.cloud()
    	.size([width, height])
    	.words(skillsToDraw)
    	.rotate(function() {
    		return ~~(Math.random() * 2) * 90;
    	})
    	.font("Impact")
    	.fontSize(function(d) {
    		return d.size;
    	})
    	.on("end", drawSkillCloud)
    	.start();

// Finally implement `drawSkillCloud`, which performs the D3 drawing:

    // apply D3.js drawing API
    function drawSkillCloud(words) {
    	d3.select("#cloud").append("svg")
    		.attr("width", width)
    		.attr("height", height)
    		.append("g")
    		.attr("transform", "translate(" + ~~(width / 2) + "," + ~~(height / 2) + ")")
    		.selectAll("text")
    		.data(words)
    		.enter().append("text")
    		.style("font-size", function(d) {
    			return d.size + "px";
    		})
    		.style("-webkit-touch-callout", "none")
    		.style("-webkit-user-select", "none")
    		.style("-khtml-user-select", "none")
    		.style("-moz-user-select", "none")
    		.style("-ms-user-select", "none")
    		.style("user-select", "none")
    		.style("cursor", "default")
    		.style("font-family", "Impact")
    		.style("fill", function(d, i) {
    			return fill(i);
    		})
    		.attr("text-anchor", "middle")
    		.attr("transform", function(d) {
    			return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
    		})
    		.text(function(d) {
    			return d.text;
    		});
    }

// optional: set the viewbox to content bounding box (zooming in on the content, effectively trimming whitespace)

    var svg = document.getElementsByTagName("svg")[0];
    var bbox = svg.getBBox();
    var viewBox = [bbox.x, bbox.y, bbox.width, bbox.height].join(" ");
    svg.setAttribute("viewBox", viewBox);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdn.rawgit.com/jasondavies/d3-cloud/v1.2.1/build/d3.layout.cloud.js"></script>

<div id="cloud"></div>

You can read a more in-depth introduction followed by a more advanced approach over at "Showcase your skillset with an interactive colorful D3.js tag cloud". Checkout a sample project over at https://github.com/bbottema/d3-tag-skills-cloud.

like image 171
Benny Bottema Avatar answered Nov 05 '22 01:11

Benny Bottema