这里有新鲜出炉的 AngularJS Tutorial 中文版, 程序狗速度看过来!
AngularJS 前端 JS 框架
AngularJS 诞生于 Google 是一款优秀的前端 JS 框架, 已经被用于 Google 的多款产品当中 AngularJS 有着诸多特性, 最为核心的是: MVC 模块化自动化双向数据绑定语义化标签依赖注入, 等等
本篇文章主要介绍了 ANGULAR2 与 D3.js 集成实现自定义可视化的方法, 小编觉得挺不错的, 现在分享给大家, 也给大家做个参考一起跟随小编过来看看吧
本文介绍了 ANGULAR2 与 D3.js 集成实现自定义可视化的方法, 分享给大家, 具体如下:
目标
展现层与逻辑层分离
数据与可视化组件相分离
数据与视图双向绑定, 实时更新
代码结构清晰, 易于维护与修改
基本原理
angular2 的组件生命周期钩子方法 \ 父子组件交互机制 \ 模板语法
源码解析
代码结构很简单, 其中除主页 index.html 和 main.ts 之外的代码结构如下所示:
代码结构
- app.module.ts
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { FormsModule } from '@angular/forms';
- //components
- import { AppComponent } from './app.component';
- import { Bubbles } from './bubbles.component';
- @NgModule({
- declarations: [
- AppComponent,
- Bubbles
- ],
- imports: [
- BrowserModule,
- FormsModule
- ],
- providers: [],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
- app.component.html
实现宿主视图定义,
2 个按钮, 按钮可以绑定了 2 点点击事件, 执行相应的动作, 刷新数组, 同时完成汽泡图的更新;
1 个汽泡图子组件, 其中 values 为子组件的输入属性, 实现父子组件之间的通信, numArray 为汽泡图的输入数据数组, 后续为随机生成的数组
- <h1>
- <button (click)="refreshArr()">开始刷新气泡图</button>
- <button (click)="stopRefresh()">停止刷新气泡图</button>
- <bubbles [values]="numArray"></bubbles>
- </h1>
- app.component.ts
通过指定一个 3 秒刷新一次的定时器, 刷新数据, 这里需要注意, 需要先清空数组, 再添加元素, 直接修改数组元素值而不改变引用, 则无法刷新汽泡图
- import { Component, OnDestroy, OnInit } from '@angular/core';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.CSS']
- })
- export class AppComponent implements OnInit, OnDestroy {
- intervalId = 0;
- numArray = [];
- // 清除定时器
- private clearTimer() {
- console.log('stop refreshing');
- clearInterval(this.intervalId);
- }
- // 生成指定范围内的随机数
- private getRandom(begin, end) {
- return Math.floor(Math.random() * (end - begin));
- }
- ngOnInit() {
- for (let i in this.numArray) {
- this.numArray[i] = this.getRandom(0, 100000000); // "0", "1", "2",
- };
- }
- // 元素关闭清除定时器
- ngOnDestroy() { this.clearTimer(); }
- // 启动定时刷新数组
- refreshArr() {
- this.clearTimer()
- this.intervalId = window.setInterval(() => {
- this.numArray = [];
- for (let i=0;i<8;i++)
- {
- this.numArray.push(this.getRandom(0, 100000000));
- }
- }, 3000);
- }
- // 停止定时刷新数组
- stopRefresh() {
- this.clearTimer();
- }
- }
bubbles.component.ts 汽泡图组件类
ngOnChanges() 生命周期方法, 可以在输入属性 values 发生变化时, 自动被调用;
@ViewChild 可以获取对子元素 svg 的引用, 其中 #target 自定义变量用于标识 svg 子元素
- import { Component, Input, OnChanges, AfterViewInit, ViewChild} from '@angular/core';
- import {BubblesChart} from './bubbles.chart';
- declare var d3;
- @Component({
- selector: 'bubbles',
- template: '<svg #target width="900"height="300"></svg>',
- })
- export class Bubbles implements OnChanges, AfterViewInit {
- @Input() values: number[];
- chart: BubblesChart;
- @ViewChild('target') target;// 获得子组件的引用
- constructor() {
- }
- // 每当元素对象上绑定的数据 输入属性值 values 发生变化时, 执行下列函数, 实现图表动态变化
- ngOnChanges(changes) {
- if (this.chart) {
- // 先清空汽泡图, 再重新调用汽泡图对象的 render 方法, 根据变动后的值绘制图形
- this.chart.destroy();
- this.chart.render(changes.values.currentValue);
- }
- }
- ngAfterViewInit() {
- // 初始化汽泡图
- this.chart = new BubblesChart(this.target.nativeElement);
- this.chart.render(this.values);
- }
- }
bubbles.chart.ts 汽泡图类
d3.js 语法定义的汽泡图类, 自带一个绘制方法和擦除方法
需要在 index.html 当中先引入 <script src="//d3js.org/d3.v2.js"></script>
- declare var d3;
- // define a bubble chart class
- // Exports the visualization module
- export class BubblesChart {
- target: HTMLElement;
- // 构造函数, 基于一个 HTML 元素对象内部来绘制
- constructor(target: HTMLElement) {
- this.target = target;
- }
- // 渲染 入参为数值 完成基于一个数组的 汽泡图的绘制
- render(values: number[]) {
- console.log('start rendering');
- console.log(values);
- d3.select(this.target)
- // Get the old circles
- .selectAll('circle')
- .data(values)
- .enter()
- // For each new data point, append a circle to the target SVG
- .append('circle')
- // Apply several style attributes to the circle
- .attr('r', d => Math.log(d)) // 半径
- .attr('fill', '#5fc') // 颜色
- .attr('stroke', '#333') // 轮廓颜色
- .attr('transform', (d, i) => { // 移动位置
- var offset = i * 30 + 3 * Math.log(d);
- return `translate(${offset}, ${offset})`;
- });
- }
- destroy() {
- d3.select(this.target).selectAll('circle').remove();
- }
- }
效果展示
来源: http://www.phperz.com/article/18/0317/361563.html