Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

enter image description here

How would this be adapted to superimpose a second set of circles?

  var data = [{
    "name": "Twitter",
    "items": [{
      "value": 2000
    }, {
      "value": 3000
    }]
  }, {
    "name": "Facebook",
    "items": [{
      "value": 200
    }, {
      "value": 300
    }]
  }, {
    "name": "Ebay",
    "items": [{
      "value": 1000
    }, {
      "value": 2000
    }]
  }, {
    "name": "Foursquare",
    "items": [{
      "value": 2000
    }, {
      "value": 3000
    }]
  }]

with the option of adding other data sets - the goal to create a 2D pyramid of sorts with different coloured circles representing the different data sets -- with the largest dataset taking the base circle.

http://jsfiddle.net/0aqvx66j/4/

function circleMaker() {


    var counter = 0;
    series = 0


    var set = svg.append("g")
      .attr("class", "series" + series);

    set.selectAll("circle")
      .data(data)
      .enter().append("circle")
      .attr("class", "series" + series)
      .attr("cy", 60)
      .attr("cx", function(d, i) {
        if (i) {
          return (counter += Math.sqrt(data[i - 1].items[series].value) + Math.sqrt(data[i].items[series].value));
        } else {
          return counter;
        }
      })
      .attr("fill", function(d, i) {
        var colorArray = ["#00ccff", "#fcdd0a"];
        return colorArray[series];
      })
      .attr("r", function(d) {
        return Math.sqrt(d.items[series].value);
      });

}

eventually maybe even flip between the different data sets to always place the largest circle as the background. So like this

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
129 views
Welcome To Ask or Share your Answers For Others

1 Answer

Most of it is just organising the data before plotting it. Within each series give each item an index, and then sort by value. The index property will then tell us the initial position of each item in the series. The first item in each series will now be the biggest value. Use this to build an offset for each series, and sum all these offsets to make a scale for positioning.

Then make group elements for each series, positioning using the offset we calculated.

Within each group, draw the circle elements. Since we sorted them they'll be drawn biggest first. The .index property can be used to colour by their original place in the series.

http://jsfiddle.net/0ht35rpb/2/

var width = 600;
var height = 400;
var svg = d3.select('svg').attr("width", width).attr("height",height);


  var data = [{
    "name": "Twitter",
    "items": [{
      "value": 2000
    }, {
      "value": 3000
    }]
  }, {
    "name": "Facebook",
    "items": [{
      "value": 200
    }, {
      "value": 300
    }]
  }, {
    "name": "Ebay",
    "items": [{
      "value": 2000
    }, {
      "value": 1000
    }]
  }, {
    "name": "Foursquare",
    "items": [{
      "value": 2000
    }, {
      "value": 3000
    },
    {
      "value": 4000
    }]
  }];


  // 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);
      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, width]);
  var colScale = d3.scale.category10();

  // add a group per series, position the group according to the values and position scale  we calculated above
 var groups = svg.selectAll("g").data(data);
 groups.enter().append("g");
 groups.attr("transform", function(d) {
        return ("translate("+scale(d.xcentre)+",0)");
 });

 // 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.selectAll("circle").data(function(d) { return d.items;}, function(d) { return d.index; });
 circles.enter().append("circle").attr("cy", height/2).attr("cx",0);

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...