使用新的 data.json 更新 d3 饼图 [英] update d3 pie chart with new data.json

查看:29
本文介绍了使用新的 data.json 更新 d3 饼图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个动态数据源,它经常在浏览器中创建一个新的 json.

我能够使用下面的代码从这个 json 创建一个饼图(也在 this fiddle)

var data=[{"crimeType":"mip","totalCrimes":24},{"crimeType":"theft","totalCrimes":558},{"crimeType":"drugs","totalCrimes":81},{"crimeType":"arson","totalCrimes":3},{"crimeType":"assault","totalCrimes":80},{"crimeType":"burglary","totalCrimes":49},{"crimeType":"disorderlyConduct","totalCrimes":63},{"crimeType":"mischief","totalCrimes":189},{"crimeType":"dui","totalCrimes":107},{"crimeType":"resistingArrest","totalCrimes":11},{"crimeType":"sexCrimes","totalCrimes":24},{"crimeType":"other","totalCrimes":58}];无功宽度= 800,高度 = 250,半径 = Math.min(width, height)/2;var 颜色 = d3.scale.ordinal().range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);var arc = d3.svg.arc().outerRadius(半径 - 10).innerRadius(半径 - 70);var pie = d3.layout.pie().排序(空).value(函数(d){返回 d.totalCrimes;});var svg = d3.select("body").append("svg").attr("宽度", 宽度).attr("高度", 高度).append("g").attr("transform", "translate(" + width/2 + "," + height/2 + ")");var g = svg.selectAll(".arc").data(饼图(数据)).enter().append("g").attr("class", "arc");g.append("路径").attr("d", 弧).style(填充",功能(d){返回颜色(d.data.crimeType);});g.append("文本").attr(转换",函数(d){返回 "translate(" + arc.centroid(d) + ")";}).attr("dy", ".35em").style("文本锚", "中间").text(功能(d){返回 d.data.crimeType;});

此数据更新频繁,那么更新饼图的最佳方法是什么?看看这个小提琴.这里我有另一个名为 data2 的 json.

我怎么能简单地用 data2 替换数据并让饼图动画/更新?

注意:在某些更新中,值可能 == 0

解决方案

我已经创建了一个工作版本并将其发布在这里:http://www.ninjaPixel.io/StackOverflow/doughnutTransition.html(由于某种原因,我无法获得在小提琴中演奏球的过渡,所以只是将其发布到我的网站上).>

为了使代码更清晰,我省略了您的标签,将data"重命名为data1",并使用一些单选按钮在数据数组之间切换.以下代码段显示了重要的部分.你可以从我上面的页面得到完整的代码.

var svg = d3.select("#chartDiv").append("svg").attr("宽度", 宽度).attr("高度", 高度).append("g").attr("id", "饼图").attr("transform", "translate(" + width/2 + "," + height/2 + ")");var path = svg.selectAll("path").数据(馅饼(数据1)).进入().append("路径");path.transition().duration(500).attr("fill", function(d, i) { return color(d.data.crimeType); }).attr("d", 弧).each(function(d) { this._current = d; });//存储初始角度功能变化(数据){路径.数据(馅饼(数据));path.transition().duration(750).attrTween("d", arcTween);//重绘弧线}//将显示的角度存储在 _current 中.//然后,从 _current 插入到新的角度.//在过渡期间,_current 由 d3.interpolate 就地更新.函数 arcTween(a) {var i = d3.interpolate(this._current, a);this._current = i(0);返回函数(t){返回弧(i(t));};}

您可能会发现这个 Mike Bostock 的代码很有帮助,我在那里学会了如何做到这一点.

I have a dynamic data source that creates a new json in the browser frequently.

I was able to create a pie chart from this json using the code below (also at this fiddle)

var data=[{"crimeType":"mip","totalCrimes":24},{"crimeType":"theft","totalCrimes":558},{"crimeType":"drugs","totalCrimes":81},{"crimeType":"arson","totalCrimes":3},{"crimeType":"assault","totalCrimes":80},{"crimeType":"burglary","totalCrimes":49},{"crimeType":"disorderlyConduct","totalCrimes":63},{"crimeType":"mischief","totalCrimes":189},{"crimeType":"dui","totalCrimes":107},{"crimeType":"resistingArrest","totalCrimes":11},{"crimeType":"sexCrimes","totalCrimes":24},{"crimeType":"other","totalCrimes":58}];


var width = 800,
height = 250,
radius = Math.min(width, height) / 2;

var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(radius - 70);

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



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

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.crimeType);
});

g.append("text")
    .attr("transform", function (d) {
    return "translate(" + arc.centroid(d) + ")";
})
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .text(function (d) {
    return d.data.crimeType;
});

This data updates frequenty so what would be the best way to update the pie? Look at this fiddle. Here I have another json called data2.

How could I simply replace data with data2 and have the pie animate/update?

Note: on some updates values could == 0

解决方案

I have created a working version and have posted it here: http://www.ninjaPixel.io/StackOverflow/doughnutTransition.html (for some reason I couldn't get the transitions to play ball in fiddle, so have just posted it to my website instead).

To make the code clearer I have omitted your labelling, renamed 'data' to 'data1', and have stuck in some radio buttons to flip between the data arrays. The following snippet shows the important bits. You can get the whole code from my page above.

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

var path = svg.selectAll("path")
    .data(pie(data1))
    .enter()
    .append("path");

  path.transition()
      .duration(500)
      .attr("fill", function(d, i) { return color(d.data.crimeType); })
      .attr("d", arc)
      .each(function(d) { this._current = d; }); // store the initial angles


function change(data){
    path.data(pie(data));
    path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs

}

// Store the displayed angles in _current.
// Then, interpolate from _current to the new angles.
// During the transition, _current is updated in-place by d3.interpolate.
function arcTween(a) {
  var i = d3.interpolate(this._current, a);
  this._current = i(0);
  return function(t) {
    return arc(i(t));
  };
}

You may find this code of Mike Bostock's helpful, it is where I learned how to do this.

这篇关于使用新的 data.json 更新 d3 饼图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆