简体   繁体   English

d3多圈系列数据图

[英]d3 multi circle series data chart

在此处输入图片说明

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. 并可以选择添加其他数据集-创建2D金字塔金字塔的目的,该金字塔用代表不同数据集的不同彩色圆圈表示-最大的数据集取基圆。

http://jsfiddle.net/0aqvx66j/4/ 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 像这样

在此处输入图片说明

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. 然后,index属性将告诉我们该系列中每个项目的初始位置。 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. .index属性可用于按其在系列中的原始位置进行着色。

http://jsfiddle.net/0ht35rpb/2/ 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); });

mgraham's answer is great! mgraham的答案很好! But since I had already written this out (and then had to go to a meeting) here's how I would code it: 但是,由于我已经写出了这些内容(然后不得不去开会),因此我将编写以下代码:

 $(document).ready(function() { var el = $('.serieschart'); var w = el.data("width"); var h = el.data("height"); var margin = { top: 65, right: 90, bottom: 5, left: 150 }; var svg = d3.select(el[0]).append("svg") .attr("class", "series") .attr("width", w + margin.left + margin.right) .attr("height", h + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = [{ "name": "Twitter", "items": [{ "value": 2000 }, { "value": 3000 }] }, { "name": "Facebook", "items": [{ "value": 300 }, { "value": 200 }] }, { "name": "Ebay", "items": [{ "value": 1000 }, { "value": 2000 }] }, { "name": "Foursquare", "items": [{ "value": 2000 }, { "value": 3000 }] }] // sort items array descending by size // this will help us draw the bigger one first // introduce an index for color assignment data.forEach(function(d){ d.items.forEach(function(d1,i){ d1.id = i; }) d.items.sort(function(x, y){ return d3.descending(x.value, y.value); }); }); circleMaker(); function circleMaker() { var colors = d3.scale.category10(); var counter = 0, prevR = 0; svg.selectAll("g") .data(data) .enter() .append("g") .selectAll("circle") .data(function(d){ return d.items; }) .enter() .append("circle") .attr("cy", 60) .attr("cx", function(d, i) { dr = Math.sqrt(d.value); if (i === 0) { counter += prevR + dr; prevR = dr; } return counter; }) .attr("r", function(d){ return dr; }) .style("fill", function(d){ return colors(d.id); }); } }); 
 body { background: #eeeeee; } 
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="http://d3js.org/d3.v3.min.js"></script> <div id="holder"> <div class="serieschart" data-role="serieschart" data-width=450 data-height=180></div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM