我尝试使用Mike Bostock的Towards reusable charts方法更新D3.js图表的宽度。它抛出了NaNs,我不知道为什么。
// Rag chart
.directive( 'ragChart', [
function () {
return {
restrict: 'E',
scope: {
data: '=',
id: '=',
width: '=',
height: '='
},
link: function (scope, element) {
// Default bottom color
var bottomColor = 'green';
var height = scope.height;
// Create canvas
var parent = d3.select(element[0]);
// Render graph
var render = function(data, width, height) {
console.log(height);
console.log(width);
var svg = parent.append('svg:svg')
.attr('class', 'rag')
.attr('width', scope.width)
.attr('height', height);
var svgG = svg.append('svg:g')
.attr('transform', 'translate(0,' + height + ')');
// Width of charts
var x = d3.scale.ordinal().rangeRoundBands([0, width]);
// Height of chart
var y = d3.scale.linear().range([0, height]);
// Color of charts
if (bottomColor == 'red'){
var color = d3.scale.ordinal().range(['rag-red', 'rag-amber', 'rag-green']);
}
else {
var color = d3.scale.ordinal().range(['rag-green', 'rag-amber', 'rag-red']);
}
// Stack data together
var remapped =['green-data', 'amber-data', 'red-data']
.map(function(dat,i){
return data.map(function(d,ii){
return {x: ii, y: d[i+1] };
});
});
// Use stacked layout
var stacked = d3.layout.stack()(remapped);
// Scale charts on axes
x.domain(stacked[0].map(function(d) {return d.x;}));
y.domain([0, d3.max(stacked[stacked.length - 1], function(d) { return d.y0 + d.y; })]);
// Group if multiple charts/bars in order to color
var valgroup = svgG.selectAll('g.valgroup')
.data(stacked)
.enter().append('svg:g')
.attr('class', 'valgroup')
.attr('class', function(d, i){ return color(i);});
// Draw bars
var rect = valgroup.selectAll('rect')
.data(function(d){return d;})
.enter().append('svg:rect')
.attr('x', function(d) { return x(d.x); })
.attr('y', function(d) { return -y(d.y0) - y(d.y); })
.attr('width', x.rangeBand())
.attr('height', function(d) { return y(d.y); })
};
render.height = function(data) {
if(!arguments.length) return height;
height = parseInt(data);
//duration = 0;
console.log(this);
return this;
};
render(scope.data, scope.width, scope.height);
// Watch for data-, width- or height changes and render charts new in case an update occurs
// Use true for 'objectEquality' property so comparisons are done on equality and not reference
scope.$watch('data', function(){
//render(scope.data, scope.width, scope.height);
}, true);
scope.$watch('width', function(){
console.log('test');
parent.call(render.height(scope.height));
//scope.render(scope.data, scope.width, scope.height);
}, true);
scope.$watch('height', function(){
//scope.render(scope.data, scope.width, scope.height);
}, true);
}
};
}
]);
小提琴:http://jsfiddle.net/vbdbbhur/
点击按钮时应该改变它的宽度,但显然没有。
我还发现this这个非常有用的示例实际上非常符合我想要实现的目标,但遗憾的是我并不了解如何在我的代码中实现它。
任何人都可以给我一个提示吗?