Echarts 很强大有好用,是我工作中做数据 JavaScript 可视化功能的第一选择。本文就是目前项目的统计模块的 demo,希望对你有用。
最终效果
老规矩,先看一下最终效果。
分析问题
还记 AngularJS 指令怎样传递函数参数吗?我们将表格封装成了一个指令。如果不封装就没有传递函数参数的问题了吗?我们要重申的是,封装是必要的,封装可以复用代码。试想,如果在再加入一个图表,要求也可以按时间段下钻。如果不封装的话,下钻这块实现要写两次。而且真实场景多数是表格图表都会的。所以说还是封装成组件好。
实现
在前面我们已经将下钻功能放父作用域中,现在只用自定义图表组件,就可以通过指令中传递函数参数的方式调用父作用域中的下钻逻辑。看代码:
<div class="pie-chart" pie-chart source="profits" drill-down="drillDown(profit)"></div>
很简单吧?剩下的工作就是实现 echarts 插件的 AngularJS 版本。Echats 是 Enterprise Charts 的缩写,商业级数据图表,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器。此处我们把问题简化,只封装饼图。其实就是 AngularJS 整合第三方库 Javasctipt。
AngularJS 把 Javascript 的 context 分隔成两部分,一部分是原生的 Javascript 的 context,另一部分是 AngularJS 的 context。只有处在 AngularJS 的 context 中的操作才能享受到 Angular 的 data-binding、exception handling、$watch 等服务,但是对于外来者(如原生的 Javascript 操作、自定义的事件回调、第三方的库等)Angular 也不是一概不接见,可以使用 AngularJS 提供的 $apply()
函数将这些外来者包进 AngularJS 的 context 中,让 Angular 感知到他们产生的变化。如下面代码:
angular.module('myApp')
/**
* Define pie echart directive
* @param source {Array} chart data provider
* @param drillDown {Function} click to drill down
*/
.directive('pieChart', function($filter) {
return {
restrict: 'EA',
scope: {
source: '=',
drillDown: '&'
},
link: function($scope, element, attrs) {
var myChart = echarts.init(element[0]);
/**
* watch data source
*/
$scope.$watchCollection('source', function(newValue, oldValue) {
if (newValue) {
var legend = [];
angular.forEach(newValue, function(val) {
legend.push(val.name);
});
var option = {
tooltip: {
trigger: 'item',
formatter: function(params) {
return params.name + ' : ' +
$filter('number')(params.value) +
' (' + params.percent.toFixed(2) + '%)';
}
},
legend: {
orient: 'vertical',
left: 'left',
data: legend
},
series: [{
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: newValue,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
myChart.setOption(option);
}
myChart.resize();
});
/**
* click chart item to drill down
*/
myChart.on('click', function(params) {
$scope.$apply(function() {
$scope.drillDown({profit: params.data});
});
});
/**
* adjust the chart size when resizing the window
*/
window.onresize = function() {
myChart.resize();
};
}
};
})
上面代码我们将 click
事件的回调处理包进 AngularJS 的 context 中让 AngularJS 来管理,然后就可以使用强大的 AngularJS 机制来处理问题了。另外,我们使用 $watchCollection
监听图表数据源 source
的变化并相应更新图表的配置。可以看到表格、图表、面包屑实现了三方联动,很酷吗?
值得注意的是,使用 $watchCollection 只会监听数组类型的数据变化,通常比 $watch 性能更好。
参考示例
访问 codepen 查看完整示例代码及效果。
评论 (0)