SVG & WordPress experiment with Raphaël JS

In Molokoloco | 14:07 - 18 Jul 2010

My first step with SVG… and http://raphaeljs.com



See the demo : http://www.b2bweb.fr/graphs/


I want to show tags connexions between some random articles, here the code !


The PHP WordPress code is added in a declared new page,
named ./wp-content/themes/mytheme/graphs.php :

/*
Template Name: Graphs
*/
 
get_header(); 
 
query_posts('cat=16,92&posts_per_page=60&orderby=rand');
 
$articles = array();
$max = 15;
$count = 1;
if (have_posts()) :
	while (have_posts()) : the_post();
		$posttags = get_the_tags();
		$taggs = array();
		foreach((array)$posttags as $tag) {
			$taggs[] = addslashes($tag->name);
		}
		if (count($taggs) > 2) {
			$title = the_title('', '', false);
			if (strpos($title, '&#') === FALSE) { // for the moment, i cannot un_html_entities() that, some titles in the blog came from strange rss feed...
				$title = str_replace('’', '\'', $title);
				$title = stripTags(un_html_entities(utf8_decode($title)));
				if (strlen($title) > 40) $title = substr($title, 0, 40).' (...)';
				$articles[] = "{href:'".get_permalink()."', title:'".utf8_encode(addslashes($title))."', tags:'".implode(',', $taggs)."'}";
 
				if ($count >= $max) break;
				else $count++;
			}
		}
	endwhile;
	$articles = implode(',', $articles);
endif;
 
wp_reset_query();

The JavaScript in ./wp-content/themes/mytheme/graphs.php :
View source

 
$(window).load(function () {
 
	var shapes = [], connections = [];
	var W = 600, H = 800;
 
	var r = Raphael('holder', W, H);
 
	var dragger = function () {
		this.ox = this.attr('x');
		this.oy = this.attr('y');
		//this.animate({fill:'#666'}, 500);
		this.attr({fill:'#666'});
	};
 
	var move = function (dx, dy) {
		var att = {x: this.ox + dx, y: this.oy + dy};
		this.attr(att);
		$(this).data(att);
		for (var i = 0, ii = connections.length; i < ii; i++) {
			r.connection(connections[i]);
		}
		r.safari();
	};
 
	var up = function () {
		//this.animate({fill:'#BBB'}, 1000);
		this.attr({fill:'#1E91D4'});
	};
 
	var titlesY = [];
	for (var i = 0, ii = articles.length; i < ii; i++) {
		var tags = articles[i]['tags'].split(',');
 
		// Built title
		shapes[i] = r.text(0, 0, articles[i]['title']).attr({font:(Math.floor(tags.length*2.5) + 10)+'px Helvetica, Verdana', fill:'#1E91D4', cursor:'move'});
 
		// Adjust with text width
		var b = shapes[i].getBBox();
		var bx = 30 + Math.floor(Math.random() * (W- 60 - (b.width / 2)));
		var by = 0;
		while(true) { // Check if not so close from an other title
			by = 30 + Math.floor(Math.random() * (H - 60 - (b.height / 2)));
			for (var y = 0, yy = titlesY.length; y < yy; y++) {
				if (Math.abs(by - titlesY[y]) < (b.height + 20)) continue;
			};
			break; 
		}
		titlesY[i] = by;
		shapes[i].attr({x:bx, y:by});
 
		// Raphael drag & drop
		shapes[i].drag(move, dragger, up);
 
		// Article link...
		$(shapes[i]).data({'href':articles[i]['href'], x:bx, y:by}); // jQuery to stock original position before motor() start
		shapes[i].dblclick(function() { window.open($(this).data('href'), '_win'+i); });
	}
 
	// On recommence maintenant que l'on a toutes les shapes.. let's build connections..
	var connected = []; // To build only one connection between 2 articles with same tag
	for (var i = 0, ii = articles.length; i < ii; i++) {
		var tags = articles[i]['tags'].split(',');
		for (var j = 0, jj = tags.length; j < jj; j++) { // Pour chaque tag de l'article
			for (var k = 0, kk = articles.length; k < kk; k++) { // On regarde tous les autres articles
				if (k == i) continue; // not himself
				if (articles[k]['tags'].indexOf(tags[j]) >= 0) {
					var exist = false;
					for (var c = 0, cc = connected.length; c < cc; c++) {
						if (!connected[c]) continue;
						for (var d = 0, dd = connected[c].length; d < dd; d++) {
							if ((c == i && d == k) || (c == k && d == i)) {
								exist = true;
								c = cc; d = dd; // break;
							}
						}
					}
					if (!exist) {
						connections.push(r.connection(shapes[i], shapes[k], '#CACED1', '', tags[j]));
						if (!connected[i]) connected[i] = [];
						connected[i].push(k); // Stock connection that exist
						break;
					}
				}
			} 	 
		}
	}
 
	// Animate
	var frameRate = 1000 / 25; // 25f/s
	var motor = setInterval(function(coef, inc, connections_, r_) {
		for (var i = 0, ii = shapes.length; i < ii; i++) { // 
			if (!inc[i]) inc[i] = (Math.random() / 10);
			if (!coef[i] && coef[i] !== 0) coef[i] = Math.floor(Math.random() * 10);
			else coef[i] += inc[i];
			shapes[i].attr({
				x: Math.floor($(shapes[i]).data('x') + (Math.sin(coef[i]) * 15)),
				y: Math.floor($(shapes[i]).data('y') + (Math.cos(coef[i]) * 15))//,
				//'fill-opacity': 0.5 + ((shapes[i].attr('y') - $(shapes[i]).data('y')) / 100)
			});
		}
		for (var j = 0, jj = connections_.length; j < jj; j++) r_.connection(connections_[j]);
 
	}, frameRate, [], [], connections, r);
 
	r.safari();
});

See the demo : http://www.b2bweb.fr/graphs/

Download : http://www.b2bweb.fr/wp-content/graphs.php

 

Home made artworks

MyBookReadR | The RSS Wall | Carousel slider | Fast web start | Try it :)
My latest sources and sheets :
Github sources | Personnal wiki | jsFiddle example | WebDev bookmark

RSS Molokoloco's JS fiddles

Recent Comments