Integrate D3 Js with Angular

  • Siddhesh Kand
  • Dec 22, 2022
angular

Assuming you have read our angular getting started to blog.

Today we will integrate the D3 js library with angular, one of the best data visualization libraries out there.


D3.js is a JavaScript library for manipulating documents based on data. 

D3 helps you bring data to life using HTML, SVG, and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.


Let's Install D3 js in our angular project with its corresponding types

npm i --save d3
npm i --save-dev @types/d3

We suggest that instead of writing d3 code in your component directly we can create a separate component that encapsulates the logic of the d3 chart

Thus making it reusable

So Let's create a component to encapsulate the logic of d3 js


ng generate component d3-line-chart


Now Inside the component ts file add the following code


import { Component, ElementRef, Input, OnChanges, OnInit } from '@angular/core';
import * as d3 from 'd3'


@Component({
  selector: 'app-line-chart',
  templateUrl: './line-chart.component.html',
  styleUrls: ['./line-chart.component.scss']
})
export class D3LineChartComponent implements OnChanges {
  @Input() public data: { value: number, date: string }[];


  private width = 700;
  private height = 700;
  private margin = 50;


  public svg;
  public svgInner;
  public yScale;
  public xScale;
  public xAxis;
  public yAxis;
  public lineGroup;


  constructor(public chartElem: ElementRef) {
  }


  public ngOnChanges(changes): void {
    if (changes.hasOwnProperty('data') && this.data) {
      console.log(this.data)
      this.initializeChart();
      this.drawChart();


      window.addEventListener('resize', () => this.drawChart());
    }
  }


  private initializeChart(): void {
    this.svg = d3
      .select(this.chartElem.nativeElement)
      .select('.linechart')
      .append('svg')
      .attr('height', this.height);
    this.svgInner = this.svg
      .append('g')
      .style('transform', 'translate(' + this.margin + 'px, ' + this.margin + 'px)');


    this.yScale = d3
      .scaleLinear()
      .domain([d3.max(this.data, d => d.value) + 1, d3.min(this.data, d => d.value) - 1])
      .range([0, this.height - 2 * this.margin]);


    this.yAxis = this.svgInner
      .append('g')
      .attr('id', 'y-axis')
      .style('transform', 'translate(' + this.margin + 'px,  0)');


    this.xScale = d3.scaleTime().domain(d3.extent(this.data, d => new Date(d.date)));


    this.xAxis = this.svgInner
      .append('g')
      .attr('id', 'x-axis')
      .style('transform', 'translate(0, ' + (this.height - 2 * this.margin) + 'px)');


    this.lineGroup = this.svgInner
      .append('g')
      .append('path')
      .attr('id', 'line')
      .style('fill', 'none')
      .style('stroke', 'red')
      .style('stroke-width', '2px')
  }


  private drawChart(): void {
    this.width = this.chartElem.nativeElement.getBoundingClientRect().width;
    this.svg.attr('width', this.width);


    this.xScale.range([this.margin, this.width - 2 * this.margin]);


    const xAxis = d3
      .axisBottom(this.xScale)
      .ticks(10)
      .tickFormat(d3.timeFormat('%m / %Y'));


    this.xAxis.call(xAxis);


    const yAxis = d3
      .axisLeft(this.yScale);


    this.yAxis.call(yAxis);


    const line = d3
      .line()
      .x(d => d[0])
      .y(d => d[1])
      .curve(d3.curveMonotoneX);


    const points: [number, number][] = this.data.map(d => [
      this.xScale(new Date(d.date)),
      this.yScale(d.value),
    ]);


    this.lineGroup.attr('d', line(points));
  }
}


Inside the component HTML file


<div class="linechart"></div>


Now we can use this component throughout our project

Let's say you want to integrate this inside App Component


Inside the .ts file you can use the following structure to pass data to the above d3 shared component


data = [
	  {
	    "value": 74,
	    "date": "2012-10-05"
	  },
	  {
	    "value": 65,
	    "date": "2012-08-05"
	  }, 
]


Inside the .HTML file


<app-d3-line-chart [data]=”data”></app-d3-line-chart>


Vola! You can use the above component anywhere inside your project

Stay tuned for more such content on D3 and more chart integrations!


Copyright © 2024 Oxvsys Automation Technologies Pvt. Ltd.