D3 图表过渡要么获得正确的数字或宽度,但不能同时获得两者
D3 chart transition either gets right number or width, but not both
我刚拿起D3,开始玩条形图动画。我有 5 个柱,当我点击时过渡到 3 并返回。我可以:
- 将 5 根柱线变为 3 条形,然后返回 5 条形,而不会动态更改条形宽度,或者
- 具有动态变化的条形宽度,但只有 3 个柱线(通过注释掉 .enter() 和 .append())。
将不胜感激任何关于如何获得两者的帮助!完整文件在这里:
https://github.com/datapress/learningD3/blob/master/chart.html
var sortOrder = false;
d3.selectAll("rect")
.on("click", function() {
sortOrder = !sortOrder
var rectID = d3.select(this).attr("id");
var dataset0 = [1, 2, 3, 4, 5];
var dataset1 = [5, 1, 1];
var dataset2 = [1, 5, 1];
var dataset3 = [1, 1, 5];
var dataset4 = [5, 5, 1];
var dataset5 = [1, 5, 5];
if (sortOrder) {
if (rectID == 0) { dataset = dataset1 };
if (rectID == 1) { dataset = dataset2 };
if (rectID == 2) { dataset = dataset3 };
if (rectID == 3) { dataset = dataset4 };
if (rectID == 4) { dataset = dataset5 };
} else {
dataset = dataset0
}
xScale.domain(d3.range(dataset.length))
yScale.domain([0, d3.max(dataset, function(d) { return d; })])
svg.selectAll("rect")
.data(dataset)
.exit()
.remove()
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.transition()
.duration(1000)
.attr({
x: function(d, i) { return xScale(i); },
y: function(d) { return h - yScale(d); },
width: xScale.rangeBand(),
height: function(d) { return yScale(d); },
fill: function(d) { return "rgb(0, 0, " + (255 - Math.round(d) * 36) + ")"; }
});
});
这很直截了当,但这是您的代码修复以更新两者:
http://jsfiddle.net/TheMcMurder/r0ptsfLr/
注意:您没有遵循 d3 的进入、更新、退出方法。您有进入和退出,但对于页面上存在但需要使用新数据进行更改的栏,您在任何地方都没有隐式更新。
下面是一个简化的示例:
var data =[45, 10]
var data2 =[45, 10, 20, 25, 30, 45]
/*The purpose of this JSfiddle is to show how enter, update, and exit works in d3js. The data values above are the data. The image had three manually created black circles. My update will resize them to the appropriate size (based on data) and change their color to blue. All newly drawn objects will be turned green and any object that is exiting will be turned red.
The transitions are delayed to make it easier to see. No delay is needed for this to work.
*/
//creating the svg so I can draw objects on it
var svg = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 5000)
//creating initial circle objects
var circle1 = svg.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 25)
// another circle object
var circle2 = svg.append("circle")
.attr("cx", 100)
.attr("cy", 200)
.attr("r", 25)
// another circle object
var circle3 = svg.append("circle")
.attr("cx", 100)
.attr("cy", 300)
.attr("r", 25)
setTimeout( function(){
enter_update_exit(data)
}, 2500 )
setTimeout( function(){
enter_update_exit(data2)
}, 10000 )
setTimeout( function(){
enter_update_exit(data)
}, 15000 )
function enter_update_exit (data){
var circle_array = svg.selectAll("circle")
.data(data);
//**********************************************************************************
// Enter: all pieces of data that do not have a node to bind to. In this case where
// there are already three circles ('nodes') there would have to be more than 3
// data points in our dataset to have enter run at all;
//**********************************************************************************
circle_array.enter()
.append("circle")
.attr("cx", 100)
.attr("cy", function(d, i){
return (i + 1)*100
})
.attr("r", 0)
.attr("fill", "#78AB46")
.transition()
.duration(1500)
.attr("r", function (d){return d;});
//**********************************************************************************
// Update: Every node that is bound to data, in this case that is everything we've
// entered and everything that has just been bound from the .data(data) bind.
//**********************************************************************************
circle_array.transition()
.duration(1500)
.delay(1500)
.style('fill', 'steelblue')
.attr('r', function (d){
return d;
});
//**********************************************************************************
// Exit: Every node ('circles') that exists in your selection that you don't have
// bound data to
//**********************************************************************************
circle_array.exit()
.transition().duration(1500).delay(1500)
.style("fill", "red")
.transition().duration(1500).delay(3000)
.attr("r", 0).transition().remove();
}
http://jsfiddle.net/TheMcMurder/H3HTe/
我希望这有所帮助!
相关文章:
- JS可以在Chrome中工作,但不能在Firefox中工作
- WebRTC视频聊天可以在FF中使用,但不能在Chrome中使用
- jQuery Datepicker可以在Safari中工作,但不能在FF或Chrome中工作
- 三角库可以与firefox一起使用,但不能在Chrome中使用
- Highcharts可以从服务器加载数据,但不能更新
- 刷新GoogleMaps tile服务器可以使用JavaScript,但不能使用GWT
- node.js可以识别字符模式,但不能识别数字模式
- 如何在元素中处理鼠标事件,但不能在其子元素上处理
- Json到CSV下载,可以在chrome中工作,但不能在IE浏览器中工作
- jQuery$.post可以在chrome、safari中工作,但不能在FF中工作(声明成功回调函数未定义)
- Javascript可以在chrome中使用,但不能在其他浏览器中使用
- Iframe加载调整大小在Chrome中工作,但不能在IE或Firefox中工作
- Rails Production-可以工作,但不能编辑/删除/创建记录
- 能够在Highcharts中看到值,但不能看到图形
- D3 图表过渡要么获得正确的数字或宽度,但不能同时获得两者
- Jquery可以发布带逗号的数字,但不能用点发布
- 文本框接受字符和数字或字母,但不能只接受数字
- 函数可用于文本输入,但不能用于数字输入
- 匹配包含下划线、小写ASCII字母、ASCII数字、连字符或点的字符串,但不能以点和连字符开头
- 对文本和数字进行排序可以在Firefox和Chrome中使用,但不能在Safari中使用