Javascript 如果源json更新(添加或删除项目),则动态更新D3 Sunburst
我是D3新手,如果源json被修改,我会尝试动态更新图表。但我无法做到这一点 请查收 Js:Javascript 如果源json更新(添加或删除项目),则动态更新D3 Sunburst,javascript,jquery,json,d3.js,sunburst-diagram,Javascript,Jquery,Json,D3.js,Sunburst Diagram,我是D3新手,如果源json被修改,我会尝试动态更新图表。但我无法做到这一点 请查收 Js: var width = 500, height = 500, radius = Math.min(width, height) / 2; var x = d3.scale.linear() .range([0, 2 * Math.PI]); var y = d3.scale.sqrt() .range([0, radius]); var color = d3.sca
var width = 500,
height = 500,
radius = Math.min(width, height) / 2;
var x = d3.scale.linear()
.range([0, 2 * Math.PI]);
var y = d3.scale.sqrt()
.range([0, radius]);
var color = d3.scale.category10();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ") rotate(-90 0 0)");
var partition = d3.layout.partition()
.value(function(d) {
return d.size;
});
var arc = d3.svg.arc()
.startAngle(function(d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
})
.endAngle(function(d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
})
.innerRadius(function(d) {
return Math.max(0, y(d.y));
})
.outerRadius(function(d) {
return Math.max(0, y(d.y + d.dy));
});
//d3.json("/d/4063550/flare.json", function(error, root) {
var root = initItems;
var g = svg.selectAll("g")
.data(partition.nodes(root))
.enter().append("g");
var path = g.append("path")
.attr("d", arc)
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
})
.on("click", click)
.each(function(d) {
this.x0 = d.x;
this.dx0 = d.dx;
});
//.append("text")
var text = g.append("text")
.attr("x", function(d) {
return y(d.y);
})
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.attr("transform", function(d) {
return "rotate(" + computeTextRotation(d) + ")";
})
.text(function(d) {
return d.name;
})
.style("fill", "white");
function computeTextRotation(d) {
var angle = x(d.x + d.dx / 2) - Math.PI / 2;
return angle / Math.PI * 180;
}
function click(d) {
console.log(d)
// fade out all text elements
if (d.size !== undefined) {
d.size += 100;
};
text.transition().attr("opacity", 0);
path.transition()
.duration(750)
.attrTween("d", arcTween(d))
.each("end", function(e, i) {
// check if the animated element's data e lies within the visible angle span given in d
if (e.x >= d.x && e.x < (d.x + d.dx)) {
// get a selection of the associated text element
var arcText = d3.select(this.parentNode).select("text");
// fade in the text element and recalculate positions
arcText.transition().duration(750)
.attr("opacity", 1)
.attr("transform", function() {
return "rotate(" + computeTextRotation(e) + ")"
})
.attr("x", function(d) {
return y(d.y);
});
}
});
} //});
// Word wrap!
var insertLinebreaks = function(t, d, width) {
alert(0)
var el = d3.select(t);
var p = d3.select(t.parentNode);
p.append("g")
.attr("x", function(d) {
return y(d.y);
})
// .attr("dx", "6") // margin
//.attr("dy", ".35em") // vertical-align
.attr("transform", function(d) {
return "rotate(" + computeTextRotation(d) + ")";
})
//p
.append("foreignObject")
.attr('x', -width / 2)
.attr("width", width)
.attr("height", 200)
.append("xhtml:p")
.attr('style', 'word-wrap: break-word; text-align:center;')
.html(d.name);
alert(1)
el.remove();
alert(2)
};
//g.selectAll("text")
// .each(function(d,i){ insertLinebreaks(this, d, 50 ); });
d3.select(self.frameElement).style("height", height + "px");
// Interpolate the scales!
function arcTween(d) {
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, 1]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d, i) {
return i ? function(t) {
return arc(d);
} : function(t) {
x.domain(xd(t));
y.domain(yd(t)).range(yr(t));
return arc(d);
};
};
}
function arcTweenUpdate(a) {
console.log(path);
var _self = this;
var i = d3.interpolate({ x: this.x0, dx: this.dx0 }, a);
return function(t) {
var b = i(t);
console.log(window);
_self.x0 = b.x;
_self.dx0 = b.dx;
return arc(b);
};
}
setTimeout(function() {
path.data(partition.nodes(newItems))
.transition()
.duration(750)
.attrTween("d", arcTweenUpdate)
}, 2000);
var宽度=500,
高度=500,
半径=数学最小值(宽度、高度)/2;
var x=d3.scale.linear()
.range([0,2*Math.PI]);
var y=d3.scale.sqrt()
.范围([0,半径]);
var color=d3.scale.category10();
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度)
.附加(“g”)
.attr(“变换”、“平移”(+width/2+)、“+(height/2+10)+”)旋转(-90 0);
var partition=d3.layout.partition()
.价值(功能(d){
返回d.size;
});
var arc=d3.svg.arc()
.startAngle(功能(d){
返回Math.max(0,Math.min(2*Math.PI,x(d.x));
})
.端角(功能(d){
返回Math.max(0,Math.min(2*Math.PI,x(d.x+d.dx));
})
.内半径(功能(d){
返回数学最大值(0,y(d.y));
})
.外层(功能(d){
返回Math.max(0,y(d.y+d.dy));
});
//d3.json(“/d/4063550/flare.json”),函数(错误,根){
var root=initItems;
var g=svg.selectAll(“g”)
.data(分区.节点(根))
.enter().append(“g”);
var path=g.append(“路径”)
.attr(“d”,弧)
.样式(“填充”,功能(d){
返回颜色((d.children?d:d.parent).name);
})
.on(“单击”,单击)
.每个功能(d){
这是x=d.x;
这是d.dx0=d.dx;
});
//.append(“文本”)
var text=g.append(“文本”)
.attr(“x”,函数(d){
返回y(d.y);
})
.attr(“dx”,“6”)//保证金
.attr(“dy”,“.35em”)//垂直对齐
.attr(“转换”,函数(d){
返回“旋转(“+ComputeExtraotation(d)+”);
})
.文本(功能(d){
返回d.name;
})
.样式(“填充”、“白色”);
函数计算拉伸(d){
变量角度=x(d.x+d.dx/2)-Math.PI/2;
返回角度/Math.PI*180;
}
功能点击(d){
控制台日志(d)
//淡出所有文本元素
如果(d.尺寸!==未定义){
d、 尺寸+=100;
};
text.transition().attr(“不透明度”,0);
path.transition()
.持续时间(750)
.attrTween(“d”,arcTween(d))
.每个(“结束”,功能(e,i){
//检查动画元素的数据e是否位于d中给定的可视角度范围内
如果(e.x>=d.x&&e.x<(d.x+d.dx)){
//获取关联文本元素的选择
var arcText=d3.select(this.parentNode).select(“text”);
//淡入文本元素并重新计算位置
arcText.transition()持续时间(750)
.attr(“不透明度”,1)
.attr(“转换”,函数(){
返回“旋转(“+ComputeExtraotation(e)+”)”
})
.attr(“x”,函数(d){
返回y(d.y);
});
}
});
} //});
//字包装!
var insertLinebreaks=函数(t、d、宽度){
警报(0)
var el=d3。选择(t);
var p=d3.select(t.parentNode);
p、 附加(“g”)
.attr(“x”,函数(d){
返回y(d.y);
})
//.attr(“dx”,“6”)//保证金
//.attr(“dy”,“.35em”)//垂直对齐
.attr(“转换”,函数(d){
返回“旋转(“+ComputeExtraotation(d)+”);
})
//p
.append(“外来对象”)
.attr('x',-width/2)
.attr(“宽度”,宽度)
.attr(“高度”,200)
.append(“xhtml:p”)
.attr('style','wrap:break-word;text-align:center;'))
.html(d.name);
警报(1)
el.移除();
警报(2)
};
//g、 选择全部(“文本”)
//.each(函数(d,i){insertLinebreaks(this,d,50);});
d3.选择(self.frameElement).style(“height”,height+“px”);
//插值比例!
函数arcTween(d){
var xd=d3.interpolate(x.domain(),[d.x,d.x+d.dx]),
yd=d3.插值(y.域(),[d.y,1]),
yr=d3.插值(y.范围(),[d.y?20:0,半径];
返回函数(d,i){
返回i?函数(t){
返回弧(d);
}:功能(t){
x、 结构域(xd(t));
y、 域(yd(t))。范围(yr(t));
返回弧(d);
};
};
}
函数arcTweenUpdate(a){
console.log(路径);
var _self=这个;
var i=d3.interpolate({x:this.x0,dx:this.dx0},a);
返回函数(t){
var b=i(t);
控制台日志(窗口);
_self.x0=b.x;
_self.dx0=b.dx;
返回弧(b);
};
}
setTimeout(函数(){
path.data(partition.nodes(newItems))
.transition()
.持续时间(750)
.attrween(“d”,arcTweenUpdate)
}, 2000);
对于enter()和工作转换,您需要为d3提供一种识别数据中每个项目的方法。.data()函数还有第二个参数,可用于返回用作id的内容。enter()将使用该id确定对象是否为新对象
试着改变
path.data(partition.nodes(newItems))
.data(partition.nodes(root));
到
在小提琴侧,
setTimeout
没有运行,因为:
d3.select(self.frameElement).style("height", height + "px");
您将获得未捕获的SecurityError:未能从“窗口”读取“帧”属性:阻止了具有原点“”的帧访问具有原点的帧,并且从未调用setTimeout
所以您可以删除这一行d3.select(self.frameElement).style(“height”,height+“px”)代码>仅用于小提琴
除此之外:
您的超时函数应该如下所示:
setTimeout(function() {
//remove the old graph
svg.selectAll("*").remove();
root = newItems;
g = svg.selectAll("g")
.data(partition.nodes(newItems))
.enter().append("g");
/make path
path = g.append("path")
.attr("d", arc)
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
})
.on("click", click)
.each(function(d) {
this.x0 = d.x;
this.dx0 = d.dx;
});
//make text
text = g.append("text")
.attr("x", function(d) {
return y(d.y);
})
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.attr("transform", function(d) {
return "rotate(" + computeTextRotation(d) + ")";
})
.text(function(d) {
return d.name;
})
.style("fill", "white");
}
工作小提琴除了@Cyril建议删除以下行之外:
d3.select(self.frameElement).style("height", height + "px");
我对你的小提琴做了进一步的修改:
这里使用的想法是添加一个函数updateChart
,它接受项
,然后生成图表:
var updateChart = function (items) {
// code to update the chart with new items
}
updateChart(initItems);
setTimeout(function () { updateChart(newItems); }, 2000);
这不使用
var updateChart = function (items) {
// code to update the chart with new items
}
updateChart(initItems);
setTimeout(function () { updateChart(newItems); }, 2000);
// DATA JOIN - Join new data with old elements, if any.
var gs = svg.selectAll("g").data(partition.nodes(root));
// ENTER
var g = gs.enter().append("g").on("click", click);
// UPDATE
var path = g.append("path");
gs.select('path')
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
})
//.on("click", click)
.each(function(d) {
this.x0 = d.x;
this.dx0 = d.dx;
})
.transition().duration(500)
.attr("d", arc);
var text = g.append("text");
gs.select('text')
.attr("x", function(d) {
return y(d.y);
})
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.attr("transform", function(d) {
return "rotate(" + computeTextRotation(d) + ")";
})
.text(function(d) {
return d.name;
})
.style("fill", "white");
// EXIT - Remove old elements as needed.
gs.exit().transition().duration(500).style("fill-opacity", 1e-6).remove();