下面是一个饼图的Angular指令,我希望在我的应用程序中重用它。该指令放置在由控制器驱动的视图中 - 控制器可以更新在任何时候传递给指令的数据集。
一旦我确定数据已经改变,我需要一个很好的清洁方法来彻底清除我的馅饼并重新绘制新数据。我对我的指令的数据参数有一个$ watch并且它可以工作(将触发价值变化)但是,我似乎无法找到一个好的&干净的方式来处理重绘馅饼。也许更新现有的馅饼更容易;或许用一个新的馅饼更容易完全重新开始。假设现有馅饼的更新最好,我该如何实现?
(是的,我知道这条指令的大部分都没有完整;我只是担心馅饼刷新所以不用担心)
'use strict';
module.exports = function(ngModule) {
ngModule.directive('pie', function() {
var graphId = 0;
return {
restrict: 'E',
scope: {
data: '=',
preset: '@'
},
template: '<div id="{{::uniqueId}}"></div>',
replace: true,
link: function(scope, element) {
// Once the DOM is ready...
element.ready(function() {
// Create our unique ID for our D3 pie chart container element
scope.uniqueId = 'pie' + graphId++;
// If the dashboard data set selection changes, we need to know about it
scope.$watch('data');
// Settings (undefined until presets)
var graphSettings = {};
// Presets
switch(scope.preset) {
case 'dashboard':
graphSettings.color = d3.scale.category20b();
graphSettings.graphHeight = 500;
graphSettings.graphWidth = 700;
graphSettings.outerRadius = 150;
graphSettings.innerRadius = graphSettings.outerRadius / 2;
graphSettings.sortMethod = null;
graphSettings.startAngle = 0;
graphSettings.endAngle = 2 * Math.PI;
graphSettings.transitionDelay = 0;
graphSettings.transitionDuration = 1500;
graphSettings.legendSize = 18;
graphSettings.legendSpacing = 4;
graphSettings.legendXOffset = -4;
break;
default:
console.log('Default preset!');
}
var svg = d3.select(element[0])
.append('svg')
.attr('height', graphSettings.graphHeight)
.attr('width', graphSettings.graphWidth)
.append('g')
.attr('transform', 'translate(' + graphSettings.outerRadius + ', ' + graphSettings.outerRadius + ')');
var arc = d3.svg.arc()
.innerRadius(graphSettings.innerRadius)
.outerRadius(graphSettings.outerRadius);
var pie = d3.layout.pie()
.value(function(d) {
return d.count;
})
.startAngle(graphSettings.startAngle)
.endAngle(graphSettings.endAngle)
.sort(graphSettings.sortMethod);
var path = svg.selectAll('path')
.data(pie(scope.data))
.enter()
.append('path')
.attr('fill', function(d) {
return graphSettings.color(d.data.label);
})
.transition().delay(graphSettings.transitionDelay).duration(graphSettings.transitionDuration)
.attrTween('d', function(d) {
var i = d3.interpolate(d.startAngle + 0.1, d.endAngle);
return function(t) {
d.endAngle = i(t);
return arc(d);
};
});
var legend = svg.selectAll('.legend')
.data(graphSettings.color.domain())
.enter()
.append('g')
.attr('class', 'legend')
.attr('transform', function(d, i) {
var height = graphSettings.legendSize + graphSettings.legendSpacing;
var offset = height * graphSettings.color.domain().length / 2;
var x = graphSettings.legendXOffset * graphSettings.legendSize;
var y = i * height - offset;
return 'translate(' + x + ', ' + y + ')';
});
// Legend shit
legend.append('rect') // LOL rekt
.attr('height', graphSettings.legendSize)
.attr('width', graphSettings.legendSize)
.style('fill', graphSettings.color); // This is dependent on the color domain being set previously
legend.append('text')
.attr('x', graphSettings.legendSize + graphSettings.legendSpacing)
.attr('y', graphSettings.legendSize - graphSettings.legendSpacing)
.style('font-family', 'FontAwesome')
.text(function(d) {
return d;
});
});
}
};
});
};