|Most Shared

Experiments with D3 tech coding tutorial javascript d3
22 Jul 2013at Atlanta

Sharing d3 code for a simple blog-post-tag relationship diagram to exhibit svg generation and transitions. Posts are shown as circles with radius based on number of tags; tags as displayed as rectangles with height based on number of posts; lines represent the many-to-many links between them. Code needs refactoring but left to explicitly convey the idea.

Domain APIs:

Both 'Post' and 'Tag' objects maintain referential links between them

Post = function(name){
    this.name = name;
    this.tags = {};
    this.tagKeys = [];

    this.addTag = function(tag){
        this.tags[tag.name] = tag;

Tag = function(name){
    this.name = name;
    this.posts = {};
    this.postKeys = [];

    this.addPost = function(post){
        this.posts[post.name] = post;

    this.hasPost = function(post){
        return posts[post.name] != null;

Diagram API:

Diagram1 = function(){
    var svg = d3.select("#diagram-1").style("padding","10px");
    var postSeed;

    this.boot = function(){
        postSeed = new PostSeed().boot();

    var drawPosts = function(){
        .attr("cy",function(d){d.y = 30; return d.y;})
        .attr("cx",function(d,i){d.x = (i*40)+20; return d.x;})
        .attr("r",function(d){return d.tagKeys.length*3});

    var drawTags = function(){
        .attr("y",function(d){d.y = 300; return d.y;})
        .attr("x",function(d,i){d.x = (i*120)+20; return d.x;})
        .attr("height",function(d){return d.postKeys.length*3;});

    var drawLabels = function(){
        var labels = svg.selectAll("text");
        .text(function(d){return d.name;})
        .attr("x",function(d,i){return (i*40)+20;});
        .text(function(d){return d.name;})
        .attr("x",function(d,i){return (i*120)+20;});

    var drawLinks = function(){
        var lines = [];
        $.each(postSeed.allTags(),function(i, tag){
            var lineColor = '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);
            for(var i=0;i < tag.postKeys.length;i++){
                var post = tag.posts[tag.postKeys[i]];
                lines.push(new Line(tag.x, tag.y, post.x, post.y, lineColor));
        .style("stroke", function(d){return d.color;})
        .attr("x1",function(d){return d.x1;})
        .attr("y1",function(d){return d.y1;})
        .attr("x2",function(d){return d.x1;})
        .attr("y2",function(d){return d.y1;})
        .attr("x2",function(d){return d.x2;})
        .attr("y2",function(d){return d.y2;});

    var Line = function(x1,y1,x2,y2,color){
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.color = color;


Seed Data APIs:

TagSeed = function(){
    var tags = new Array(6);

    this.random = function(){
        var randomSize = Math.floor((Math.random()*4)+3); // 3-7 tags per post
        var randomTags = new Array(randomSize);
        for(var i=0; i < randomSize; i++){
            var index = Math.floor(Math.random()*tags.length);
            randomTags[i] = tags[index];
        return randomTags;

    this.boot = function(){
        for(var i=0; i < tags.length; i++){
            tags[i] = new Tag("t_"+i);
        return this;

    this.allTags = function(){return tags};

PostSeed = function(){
    var posts = new Array(20);
    var tagSeed = new TagSeed().boot();

    this.boot = function(){
        for(var i=0; i < posts.length; i++) {
            posts[i] = new Post("p_"+i);
            var tags = tagSeed.random();
            for(var j=0; j < tags.length; j++){
        return this;

    this.allPosts = function(){return posts};
    this.allTags = function(){return tagSeed.allTags()};
comments powered by Disqus

All content except noted photos and videos copyright © Vijayaraj Chakravarthy. All rights reserved. *Any images or videos not listed as mine are copyright to their respective owners and were used under creative common license or fair use standards. If a photo or video is your material and you do not wish it to be on the site, please email me vijayrc@outlook.com and I will remove it immediately.