AngularJS2 与 D3.js集成实现自定义可视化的方法


Posted in Javascript onDecember 01, 2017

本文介绍了ANGULAR2 与 D3.js集成实现自定义可视化的方法,分享给大家,具体如下:

目标

  1. 展现层与逻辑层分离
  2. 数据与可视化组件相分离
  3. 数据与视图双向绑定,实时更新
  4. 代码结构清晰,易于维护与修改

基本原理

angular2 的组件生命周期钩子方法\父子组件交互机制\模板语法

源码解析

代码结构很简单,其中除主页index.html和main.ts之外的代码结构如下所示:

AngularJS2 与 D3.js集成实现自定义可视化的方法

代码结构

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 汽泡图组件类

  1. ngOnChanges() 生命周期方法,可以在输入属性values发生变化时,自动被调用;
  2. @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 汽泡图类

  1. d3.js 语法定义的汽泡图类,自带一个绘制方法和擦除方法
  2. 需要在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();
  }
}

效果展示

AngularJS2 与 D3.js集成实现自定义可视化的方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
利用XMLHTTP传递参数在另一页面执行并刷新本页
Oct 26 Javascript
Jquery 选中表格一列并对表格排序实现原理
Dec 15 Javascript
JavaScript全排列的六种算法 具体实现
Jun 29 Javascript
在每个匹配元素的外部插入新元素的方法
Dec 20 Javascript
JavaScript常用小技巧小结
Dec 29 Javascript
ES6正则表达式扩展笔记
Jul 25 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
Aug 28 Javascript
Easy UI动态树点击文字实现展开关闭功能
Sep 30 Javascript
vue单页应用加百度统计代码(亲测有效)
Jan 31 Javascript
vue二级路由设置方法
Feb 09 Javascript
vue的全局提示框组件实例代码
Feb 26 Javascript
vue中element 上传功能的实现思路
Jul 06 Javascript
javascript Function函数理解与实战
Dec 01 #Javascript
React Native react-navigation 导航使用详解
Dec 01 #Javascript
分析JS单线程异步io回调的特性
Dec 01 #Javascript
JavaScript定义及输出螺旋矩阵的方法详解
Dec 01 #Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
Dec 01 #Javascript
利用babel将es6语法转es5的简单示例
Dec 01 #Javascript
微信小程序实现鼠标拖动效果示例
Dec 01 #Javascript
You might like
奉献出一个封装的curl函数 便于调用(抓数据专用)
2013/07/22 PHP
PHP大批量插入数据库的3种方法和速度对比
2014/07/08 PHP
PHP中使用Imagick操作PSD文件实例
2015/01/26 PHP
PHP设计模式之适配器模式原理与用法分析
2018/04/25 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
jquery 打开窗口返回值实现代码
2010/03/04 Javascript
基于jquery实现漂亮的动态信息提示效果
2011/08/02 Javascript
文本框文本自动补全效果示例分享
2014/01/19 Javascript
javascript闭包入门示例
2014/04/30 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
简述AngularJS的控制器的使用
2015/06/16 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
轻松掌握JavaScript状态模式
2016/09/07 Javascript
js闭包用法实例详解
2016/12/13 Javascript
jQuery实现二维码扫描功能
2017/01/09 Javascript
分享一道关于闭包、bind和this的面试题
2017/02/20 Javascript
node使用UEditor富文本编辑器的方法实例
2017/07/11 Javascript
js正则相关知识点专题
2018/05/10 Javascript
Django中实现一个高性能计数器(Counter)实例
2014/07/09 Python
在Python中操作时间之tzset()方法的使用教程
2015/05/22 Python
使用EduBlock轻松学习Python编程
2018/10/08 Python
python 普通克里金(Kriging)法的实现
2019/12/19 Python
python 实现从高分辨图像上抠取图像块
2020/01/02 Python
python opencv根据颜色进行目标检测的方法示例
2020/01/15 Python
新版Pycharm中Matplotlib不会弹出独立的显示窗口的问题
2020/06/02 Python
python mock测试的示例
2020/10/19 Python
python 进制转换 int、bin、oct、hex的原理
2021/01/13 Python
极简鞋类,赤脚的感觉:Lems Shoes
2019/08/06 全球购物
J2EE相关知识面试题
2013/08/26 面试题
网络工程师个人的自我评价范文
2013/10/01 职场文书
解除施工合同协议书
2014/10/17 职场文书
党的群众路线教育实践活动个人对照检查材料(企业)
2014/11/05 职场文书
说谎欺骗人检讨书300字
2014/11/18 职场文书
vue项目两种方式实现竖向表格的思路分析
2021/04/28 Vue.js
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python
zabbix配置nginx监控的实现
2022/05/25 Servers