[Solved] d3 javascript series chart


enter image description here

I’ve managed to get the diagonal markers and pointers in alignment, pointing to the correct circle colors to represent that set. I am keen to fine tune this chart and have more control over the padding and chart width/height parameters. The chart looks stable but would be keen to test it with different values and sized data sets.

/LATEST/
http://jsfiddle.net/0ht35rpb/33/

var width = 760;
var height = 400;

var svg = d3.select('#serieschart')
  .append("svg:svg")
  .attr("width", width)
  .attr("height", height);

//Count
//Checkins
//Popularity

var data = [{
  "name": "Twitter",
  "items": [{
    "id": 0,
    "label": "Count",
    "value": 200
  }, {
    "id": 1,
    "label": "Checkins",
    "value": 1000
  }, {
    "id": 2,
    "label": "Popularity",
    "value": 30
  }]
}, {
  "name": "Facebook",
  "items": [{
    "id": 0,
    "label": "Count",
    "value": 500
  }, {
    "id": 1,
    "label": "Checkins",
    "value": 300
  }, {
    "id": 2,
    "label": "Popularity",
    "value": 740
  }]
}, {
  "name": "Ebay",
  "items": [{
    "id": 0,
    "label": "Count",
    "value": 4000
  }, {
    "id": 1,
    "label": "Checkins",
    "value": 1000
  }, {
    "id": 2,
    "label": "Popularity",
    "value": 40
  }]
}, {
  "name": "Foursquare",
  "items": [{
    "id": 0,
    "label": "Count",
    "value": 2000
  }, {
    "id": 1,
    "label": "Checkins",
    "value": 3000
  }, {
    "id": 2,
    "label": "Popularity",
    "value": 4500
  }]
}];



var legend_group = svg.append("g")
  .attr("class", "legend")
  .attr("width", 80)
  .attr("height", 100)
  .append("svg:g")
  .attr("class", "legendsection")
  .attr("transform", "translate(0,30)");

var legend = legend_group.selectAll("circle").data(data[0].items);

legend.enter().append("circle")
  .attr("cx", 70)
  .attr("cy", function(d, i) {
    return 15 * i;
  })
  .attr("r", 7)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", function(d, i) {
    return colores_google(i);
  });

legend.exit().remove();





var legendtext = legend_group.selectAll("text").data(data[0].items);

legendtext.enter().append("text")
  .attr("class", "labels")
  .attr("dy", function(d, i) {
    return 15 * i;
  })
  .attr("text-anchor", function(d) {
    return "start";
  })
  .text(function(d) {
    return d.label;
  });

legendtext.exit().remove();

var m = [80, 20, 20, 10];
var w =+ width - m[0];
var h =+ height - m[1];

var chart = svg.append("g")
  .attr("class", "serieschart")
  .attr("width", w)
  .attr("height", h);

var outerRadius = [];
// organise the data. 
// Insert indices and sort items in each series
// keep a running total of max circle size in each series
// for later positioning
var x = 0;
var totalWidth = d3.sum(
  data.map(function(series) {
    series.items.forEach(function(item, i) {
      item.index = i;
    });
    series.items.sort(function(a, b) {
      return b.value - a.value;
    });
    var maxr = Math.sqrt(series.items[0].value);
    outerRadius.push(maxr);
    x += maxr;
    series.xcentre = x;
    x += maxr;
    return maxr * 2;
  })
);

// make scales for position and colour
var scale = d3.scale.linear().domain([0, totalWidth]).range([0, w]);
//var colScale = d3.scale.category10();

function colores_google(n) {
  var colores_g = ["#f7b363", "#448875", "#c12f39", "#2b2d39", "#f8dd2f"];
  return colores_g[n % colores_g.length];
}

function fetchValue(items, label) {
  for (i = 0; i <= items.length; i++) {
    if (items[i].label == label) {
      return items[i].value;
    }
  }
}

function fetchRadius(items, label) {
  for (i = 0; i <= items.length; i++) {
    if (items[i].label == label) {
      return Math.sqrt(items[i].value);
    }
  }
}


// add a group per series, position the group according to the values and position scale  we calculated above
var groups = chart.selectAll("g.seriesGroup").data(data);
var newGroups = groups.enter().append("g").attr("class", "seriesGroup");
newGroups.append("text")
  .attr("class", "seriesName")
  .attr("text-anchor", "middle");
newGroups.append("line")
  .attr("class", "seriesName")
  .attr("y1", h - 40)
  .attr("y2", h / 2);
newGroups.append("text")
  .attr("class", "datumValue")
  .attr("y", 10)
  //.attr("transform", "rotate(-45)")
;
newGroups.append("g").attr("class", "circleGroup");
newGroups.append("g").attr("class", "datumLine")
  .append("line")
  .attr("class", "datumValue")
  .attr("y2", 40);

var focus = "Count";
groups.attr("transform", function(d) {
  return "translate(" + scale(d.xcentre) + ",0)";
});

groups.select("text.seriesName")
  .text(function(d) {
    return d.name;
  })
  .attr("y", h - 20);

groups.select("text.datumValue")
  .text(function(d) {
    return fetchValue(d.items, focus);
  })
  .attr("transform", function(d) {
    return "translate(" + ((h / 2) - 20 - scale(fetchRadius(d.items, focus))) + ",20) rotate(-45)";
  });

groups.select("line.datumValue")
  .attr("y1", function(d) {
    return (h / 2) - scale(fetchRadius(d.items, focus));
  })
  .attr("x2", function(d) {
    return (h / 2) - scale(fetchRadius(d.items, focus) + 20);
  });

// then add circles per series, biggest first as items are sorted
// colour according to index (the property we inserted previously so we can
// keep track of their original position in the series)
var circles = groups
  .select(".circleGroup")
  .selectAll("circle").data(function(d) {
    return d.items;
  }, function(d) {
    return d.index;
  });
circles.enter().append("circle").attr("cy", h / 2).attr("cx", 0);

circles
  .attr("r", function(d) {
    return scale(Math.sqrt(d.value));
  })
  .style("fill", function(d) {
    return colores_google(d.index);
  });

solved d3 javascript series chart