今天客户有一个管理后台的系统,之前是我们公司做的,然后现在需要添加一个数据可视化的需求,之前我们一直都是用的百度Echarts做的数据图展示,但是脑海里面一直觉得阿里的antv看上去可玩性会更高一点,于是切换到了antv,网上找了一圈都觉得没有太多很好的关于Angular使用@antv/g2的例子,于是自己研究摸索了一下记录下来,如果大家有什么更好的方式也可以交流。

HTML结构,里面使用了ng-zorro-antd/grid的栅格化系统用来调整布局,自己可以根据自己的需求自定义调整

import { NzGridModule } from 'ng-zorro-antd/grid';
<div nz-row>
  <div nz-col nzSpan="12">
      <div #chart></div>
  </div>
  <div nz-col nzSpan="12">
    <button nz-button nzType="primary">Primary</button>
  </div>
</div>

然后component关键代码

import {
  AfterViewInit,
  Component,
  ElementRef,
  OnDestroy,
  OnInit,
  ViewChild
} from '@angular/core';
import { Chart } from '@antv/g2';
import { SystemService } from '../../../service/system.service';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-welcome',
  templateUrl: './welcome.component.html',
  styleUrls: ['./welcome.component.scss']
})
export class WelcomeComponent implements OnInit, AfterViewInit, OnDestroy {
  private unsubscribe = new Subject<void>();
  @ViewChild('chart') chartElement: ElementRef;
  public chart: any;
  constructor(private systemService: SystemService) {}

  ngOnInit(): void {}

  createChart(): void {
    const data = [
      { genre: 'Sports', sold: 275 },
      { genre: 'Strategy', sold: 115 },
      { genre: 'Action', sold: 120 },
      { genre: 'Shooter', sold: 350 },
      { genre: 'Other', sold: 150 }
    ];

    // Step 1: 创建 Chart 对象
    this.chart = new Chart({
      container: this.chartElement.nativeElement,
      autoFit: true,
      height: 300
    });

    // Step 2: 载入数据源
    this.chart.data(data);

    // Step 3:创建图形语法,绘制柱状图
    this.chart.interval().position('genre*sold');

    // Step 4: 渲染图表
    this.chart.render();

    setTimeout(() => {
      this.chart.forceFit();
    }, 0);
  }

  ngAfterViewInit(): void {
    this.createChart();
    this.systemService.viewLayoutChange
      .pipe(takeUntil(this.unsubscribe))
      .subscribe(() => {
        setTimeout(() => {
          this.chart.forceFit();
        }, 300);
      });
  }

  ngOnDestroy(): void {
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }
}

为了图表自适应容器大小,我autoFit设置为了true,然后在angular生命周期ngAfterViewInit才调用图表创建函数,并做了异步延迟处理

setTimeout(() => {
        this.chart.forceFit();
}, 0);

然后我的布局方式做侧边栏导航模式,在侧边栏收起和展开会又一个流触发,于是我做了订阅处理,来响应式的改变图的大小渲染

this.systemService.viewLayoutChange
      .pipe(takeUntil(this.unsubscribe))
      .subscribe(() => {
        setTimeout(() => {
          this.chart.forceFit();
        }, 300);
      });

发表评论