【问题标题】:creating multiple pie/donut charts创建多个饼图/甜甜圈图
【发布时间】:2016-05-12 20:25:48
【问题描述】:

这是我一直在努力的fiddle

我正在尝试弄清楚如何调整此代码,以便我可以制作我的圆环图的多个实例——根据每个对象的“toursCreated”的大小缩放到不同的大小(但这是次要的)。

现在我只是想了解如何制作倍数 - 我需要进行哪些代码调整,因此我为存储在数据数组中的每个数据对象生成一个饼图。

这是目前为止的代码...

var width = 200,
    height = 150,
    radius = Math.min(width, height) / 2;

var percentageFormat = d3.format("%");

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6"]);

var arc = d3.svg.arc()
    .outerRadius(radius)
    .innerRadius(40);

var labelArc = d3.svg.arc()
    .outerRadius(radius - 18)
    .innerRadius(radius - 18);

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.region; });

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

function render (data) {

  var tots = d3.sum(data, function(d) {
    console.log(d.region);
    return d.region;
  });

  data.forEach(function(d) {
    d.percentage = d.region / tots;
    console.log(d.percentage);
  });

  var g = svg.selectAll(".arc")
      .data(pie(data))
      .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.region); });

  g.append("text")
      .attr("transform", function(d) { return "translate(" +     labelArc.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .text(function(d) { return percentageFormat(d.data.percentage); });

  console.log(data);

  var middle = data;

  console.log(middle);
  
  var innerG = svg.append("g")
      .attr("class", "innerArc")
      .append("circle")
      .attr("r", 40)
      .style("fill", "grey");

  var salesPeopleTotal = svg.append("g")
      .attr("class", "sumTotal-text")
      .selectAll("text")
      .data([middle[0]])
      .enter().append("text")
      .text(tots)
      .attr('y', "5")
      .attr('x', "-10")
      .style("fill", "white");
}

var salesPeople = [
   { "region": "West",
     "toursCreated": 644,
    "totalStaff": 644,
    "activeStaff": 399,
    "inactiveStaff": 245  
   },
  { "region": "North-West",
     "toursCreated": 467,
    "totalStaff": 644,
    "activeStaff": 399,
    "inactiveStaff": 245  
   },
  { "region": "South-West",
     "toursCreated": 320,
    "totalStaff": 644,
    "activeStaff": 399,
    "inactiveStaff": 245  
   }
];

var inactive = {"name": "inactive"};
inactive.region = salesPeople[0].inactiveStaff;

var active = {"name": "active"};
active.region = salesPeople[0].activeStaff;

var myArray = [];
myArray.push(inactive);
myArray.push(active);

render(myArray);

【问题讨论】:

  • 为什么不使用像 nvd3.org 这样的 d3 包装器/框架?
  • @RhysBradbury 嗯,因为我只是想了解如何在 D3 中直接执行此操作。不想使用框架。
  • 很公平,也许将 d3 逻辑保存在一个类中,然后使用 new 运算符创建图表对象,所有这些都使用 updateChart prototype 方法。您可以将一些初始选项作为object 传递给图表,因为您迭代图表初始化objects 的Array
  • 您必须修改代码才能在 svg 选择器上工作。目前您正在将 svg 附加到正文中,您可以使用 svgs 吗?也许扩展 JQuery?
  • @RhysBradbury 祝福你。感谢您帮助我理解这些内容。

标签: javascript d3.js svg charts


【解决方案1】:

也许将 d3 逻辑保存在一个类中,然后使用 new 运算符创建图表对象。

参考:
http://www.w3schools.com/js/js_object_prototypes.asp

//if you use the new operator on a function, you get an object.
//var chartObj = new Chart({selector: '#myChartHtmlId svg', data: {}});
function Chart(initObject) {
  //set Chart properties.
  this.width = 200;
  this.height = 200;
  this.selector = initObject.selector;
  this.d3svg = d3.select(this.selector);
  this.data = initObj.data;

  for (prop in initObject) {
    //to overwrite defaults use:
    //new Chart({width: 500, height: 500});
    this[prop] = initObject[prop];
  }
  this.render();
}

//now once you've used:
//var chartObj = new Chart();
//you can now:
//chartObj.updateData(someVarWithData);
Chart.prototype.updateData = function(data) {
  this.data = data;
  this.render();
};

Chart.prototype.render = function() {
  var svg = this.d3sv;
  //continue d3 stuff.
  //access the object data with this.data
};

html:
....显然在体内..

<svg id="myChartHtmlId"></svg>

然后使用:

var charts = [];

for (var i = 0, j = arrayOfChartInitObjects.length; i < j; i++) {
  var chartInitObj = arrayOfChartInitObjects[i];
  charts.push(new Chart(chartInitObj));
}

如果其中任何一个没有意义/您需要进一步解释,请评论我的回答。

我希望这会有所帮助。

里斯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多