ngx-admin におけるチャートデータの PNG/SVG 一括エクスポート実装

ngx-admin は Angular 8 以上と Nebular フレームワークをベースに構築された管理画面テンプレートで、Bootstrap 4 および Angular Material の UI コンポーネントを活用し、Chart.js などのチャートライブラリとの連携も容易です。この記事では、ngx-admin 上で実装するチャートのエクスポート機能について、PNG および SVG 形式への完全な対応方法を解説します。

ngx-admin のチャート統合構成

ngx-admin では主に Chart.js を元にしたチャートコンポーネントが提供されています。このチャート機能は、angular2-chartjs モジュールによって提供され、以下のモジュールファイルでグローバルに有効化されています:

  • src/app/pages/e-commerce/e-commerce.module.ts
  • src/app/pages/charts/charts.module.ts

これらのモジュールでは ChartModule がインポート済みであり、チャート表示の基盤が整っています。

環境準備

ファイルの保存処理には、HTML5 Canvas の toBlob() メソッドと、file-saver ライブラリが必要です。以下の依存関係をインストールしてください:

npm install file-saver
npm install --save-dev @types/file-saver

チャートエクスポート用サービスの実装

再利用性を高めるため、以下のような共用サービスを作成します:

import { Injectable } from '@angular/core';
import { saveAs } from 'file-saver';

@Injectable({
  providedIn: 'root'
})
export class ChartExporter {

  // PNG 出力処理(Canvas 要素から)
  exportAsPng(elementId: string, filename: string): void {
    const canvas = document.querySelector<HTMLCanvasElement>(`#${elementId}`);
    if (!canvas || !canvas.toBlob) return;
    canvas.toBlob(blob => {
      if (blob) saveAs(blob, `${filename}.png`);
    }, 'image/png');
  }

  // SVG 出力処理(SVG 要素から)
  exportAsSvg(elementId: string, filename: string): void {
    const svg = document.querySelector<SVGSVGElement>(`#${elementId}`);
    if (!svg) return;
    
    const serializer = new XMLSerializer();
    const source = serializer.serializeToString(svg);
    
    // namespace 宣言の補完
    const xmlHeader = '';
    const mimetype = 'image/svg+xml;charset=utf-8';
    const blob = new Blob([xmlHeader, source], { type: mimetype });
    
    saveAs(blob, `${filename}.svg`);
  }
}

チャートコンポーネントでの zdję필

以下は、チャートコンポーネントにエクスポートボタンを実装する例です:

import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
import { ChartExporter } from './chart-exporter.service';

@Component({
  selector: 'app-dashboard-chart',
  template: `
    <div class="chart-container">
      <div class="controls">
        <button class="btn btn-primary" (click)="onPngExport()">PNG 取得</button>
        <button class="btn btn-success" (click)="onSvgExport()">SVG 取得</button>
      </div>
      <canvas #chartCanvas id="mainChart" width="400" height="200"></canvas>
      <svg id="iconChart" style="width: 400px; height: 200px;"></svg>
    </div>
  `
})
export class DashboardChartComponent implements AfterViewInit {
  @ViewChild('chartCanvas', { static: false }) chartCanvas?: ElementRef<HTMLCanvasElement>;

  constructor(private exporter: ChartExporter) {}

  ngAfterViewInit(): void {
    // チャート初期化処理(Chart.js など)
  }

  onPngExport(): void {
    this.exporter.exportAsPng('mainChart', 'datareport');
  }

  onSvgExport(): void {
    this.exporter.exportAsSvg('iconChart', 'iconreport');
  }
}

Styling Considerations for SVG Export

SVG 形式でエクスポートする際、CSS スタイルが反映されないことがあります。この問題に対処するには、以下の方法が考えられます:

  • このコンポーネントスコープ内で SVG 要素にインラインスタイル
  • style タグを SVG 内に埋め込む(DOM ランタイム段階で注入)
  • computedStyle を使用して、計算済みスタイルを抜き出し SVG 要素に適用

Background Rendering Safety

チャート描画完了前にエクスポートが実行されると、空白イメージが出力されることがあります。TMP 解決策として、以下のような安全策を加えると良いでしょう:

onPngExport(): void {
  setTimeout(() => {
    this.exporter.exportAsPng('mainChart', 'report');
  }, 150); // 最小限の遅延付与
}

より正確には、チャート初期化完了のイベント(例:Chart.js の onUpdate)を監視し、描画状態を制御することが推奨されます。

タグ: ngx-admin Chart.js Angular SVG Canvas

7月7日 22:08 投稿