CodeIn House

  • Laravel
  • WordPress
  • jQuery
  • Javascript
  • Contact
Home   D3   How to use D3JS with Angular? D3 Charts Angular Tutorial

How to use D3JS with Angular? D3 Charts Angular Tutorial

June 15, 2021 by SNK

draw d3 charts with angular

In this tutorial we are going to see how to use d3 in angular. D3 is helps to build real real world reporting with different forms of visualizations using bar charts and pie charts or any kind that you can draw with SVG and canvas.

Today we are going to useĀ  d3 with angular so that we can combine both features of both angular and d3 for our project. In this angular d3 example we are going to create a angular project from scratch and import d3 in angular and create a simple chart inside it.

It will help us to know how can we integrate and customize d3 chart inside angular. Let’s get started.

What are we going to do ?

  1. Install fresh project of angular.
  2. Install d3 dependencies.
  3. Prepare JSON Data
  4. Create a chart component.
  5. Draw bar chart in chart component.

How to Draw Bar Chart With Angular & D3

To draw bar chart with angular first we have to make our project with d3 dependency ready for angular and start drawing the chart. Let’s get on with clear angular d3 example so, that it would be easy to know how it works.

Step 1 – Installing Fresh Project of Angular

Since you are already searching for d3 I assume that you already know how to setup an angular project and get started. If you don’t know comment down below.

Step 2 – Install D3 Dependencies

To make angular d3 to ready to build charts with d3 we need to install some dependency so go to your project root and install the dependency below

npm install d3 && @types/d3

Step 3 – Preparing JSON Data

Once the dependencies are install it is time to prepare JSON data for the charts. So it highly depends on how you provide the data but this is how I prepared it. I find it most efficient way to control it over the chart.

Also, prepare the domain by calculating the highest value from your chart data. See the copy of my app.component.ts file below to go in detail.

app.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
 
  data: {name: string, series: { name: string, value: number }[] }[];
  barColor = ['#a9ce97', '#a5b5de'];
  domain = [100, 1000];
 
  constructor() {
    this.data = [
      {
        name: 'Row1',
        series: [
          {name: 'Bar1', value: 150},
          {name: 'Bar2', value: 200}
        ],
      },
      {
        name: 'Row2',
        series: [
          {name: 'Bar1', value: 300},
          {name: 'Bar2', value: 400}
        ],
      },
      {
        name: 'Row3',
        series: [
          {name: 'Bar1', value: 500},
          {name: 'Bar2', value: 1000}
        ],
      }
    ];
  }
}

Step 4 – Creating a Chart Component

Now let us create a chart component which you can use it across all your projects and reuse it in entire application rather than writing everything inside app.component.ts file. I am going to create bar chart so I will create a component named bar chart.

Go to terminal and type ng g c BarChartVertical --skipTests=true

Once the component is created it would have been automatically registered in app.module.ts. If there is not present in app.module.ts in declarations section, add it.

Once everything done add Bar Chart Vertical component to your app.component.html

app.component.html
1
<app-bar-chart-vertical [data]="data" [domain]="domain" [barColors]="barColor"></app-bar-chart-vertical>

Step 5 – Drawing an Bar Chart Component

Finally, it is time to draw the bar chart component. You have recently checkout this blog, I have recently drawn vertical bar chart using d3 in core JavaScript. If you haven’t been through it, have time go through it.

I am going to draw same chart but inside angular which is going to use the power of typescript. Now create the template reference where you want to draw your chart by copying and paste this in your bar-chart-vertical.component.html

bar-chart-vertical.component.html
1
<div #svgContainer></div>

Copy these code below inside bar-chart-vertical.component.ts

bar-chart-vertical.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import {
  AfterViewInit,
  Component,
  ElementRef,
  HostListener,
  Input,
  OnChanges,
  SimpleChanges,
  ViewChild
} from '@angular/core';
import * as d3 from 'd3';
import {ScaleBand} from 'd3';
 
@Component({
  selector: 'app-bar-chart-vertical',
  templateUrl: './bar-chart-vertical.component.html',
  styleUrls: ['./bar-chart-vertical.component.css']
})
export class BarChartVerticalComponent implements AfterViewInit, OnChanges {
 
  @Input() data!: { name: string, series: { name: string, value: number }[] }[];
  @Input() height = 300;
  @Input() margin = {top: 10, left: 50, right: 10, bottom: 20};
  @Input() innerPadding = 0.1;
  @Input() outerPadding = 0.1;
  @Input() seriesInnerPadding = 0.1;
  @Input() domain = [0, 1000];
  @Input() barColors = ['#00aeef', '#f98e2b', '#7C77AD'];
 
  public svg!: d3.Selection<SVGGElement, unknown, null, undefined>;
  public isRendered = false;
 
  @ViewChild('svgContainer', {read: ElementRef, static: true}) svgContainerRef!: ElementRef<HTMLDivElement>;
 
  constructor() {
  }
 
  @HostListener('window:resize')
  onResize() {
    this.createChart();
  }
 
  ngOnChanges(changes: SimpleChanges) {
    if (this.isRendered) {
      this.createChart();
    }
  }
 
  ngAfterViewInit(): void {
    this.createChart();
    this.isRendered = true;
  }
 
  private createSVG(): void {
    this.svg = d3.select(this.svgContainerRef.nativeElement)
      .append('svg')
      .attr('width', '100%')
      .attr('height', this.height)
      .append('g')
      .attr('width', '100%')
      .attr('transform', 'translate(0, 0)')
      .attr('class', 'bar-chart-vertical');
  }
 
  private isDataValid(): boolean {
    return this.data && this.data.length > 0;
  }
 
  private getBandScale(domain: string[], range: any, innerPadding = 0, outerPadding = 0) {
    const scale: any | ScaleBand<string> = d3.scaleBand()
      .range(range)
      .domain(domain)
      .paddingInner(innerPadding)
      .paddingOuter(outerPadding);
    scale.type = 'BAND';
    return scale;
  }
 
  private createChart(): void {
    if (!this.isRendered) {
      this.createSVG();
    }
    if (this.isDataValid()) {
      const margin = {
        top: this.margin.top,
        right: this.margin.right,
        bottom: this.margin.bottom,
        left: this.margin.left,
      }
 
      let height = this.height - margin.top - margin.bottom;
      const width = this.svgContainerRef.nativeElement.getBoundingClientRect().width - margin.left - margin.right;
      const groupNames = this.data.map(item => item.name);
      const groupLabels = this.data.length > 0 ? this.data[0].series.map(item => item.name) : [];
 
      const xScale = this.getBandScale(groupNames, [0, width], this.innerPadding, this.outerPadding).round(true);
      const x1Scale = this.getBandScale(groupLabels, [0, xScale.bandwidth()], this.seriesInnerPadding, this.outerPadding).round(true);
 
      let chartContainer = this.svg.selectAll<SVGGElement, number>('g.chart-container').data([1]);
      chartContainer = chartContainer.enter()
        .append('g')
        .attr('class', 'chart-container')
        .merge(chartContainer)
        .attr('transform', `translate(${margin.left}, ${margin.right})`);
 
      let chartWrap = chartContainer.selectAll<SVGGElement, number>('g.chart-wrap').data([1]);
      chartWrap = chartWrap.enter()
        .append('g')
        .attr('class', 'chart-wrap')
        .merge(chartWrap)
        .attr('transform', 'translate(0, 0)');
 
      const xAxis = chartWrap.selectAll<SVGGElement, number>('g.x-axis').data([1]);
      xAxis.enter()
        .append('g')
        .attr('class', 'x-axis')
        .merge(xAxis)
        .attr('transform', `translate(0, ${height})`)
        .call(d3.axisBottom(xScale)).selectAll('text')
        .style('text-anchor', 'middle');
 
      const y = d3.scaleLinear().domain(this.domain).nice().rangeRound([height, 0]);
 
      let barWrap = chartWrap.selectAll<SVGGElement, number>('g.bar-wrap').data([1]);
      barWrap.exit().remove();
      barWrap = barWrap.enter().append('g')
        .attr('class', 'bar-wrap')
        .merge(barWrap);
 
      let barGroup = barWrap.selectAll<SVGGElement, {name: string, series: {name: string, value: number}}>('g.bar-group').data(this.data);
      barGroup.exit().remove();
      barGroup = barGroup.enter().append('g')
        .attr('class', 'bar-group')
        .merge(barGroup)
        .attr('transform', d => `translate(${xScale(d.name)}, 0)`);
 
      let barRects = barGroup.selectAll<SVGRectElement, {name: string, value: number}>('rect.bar').data(d => d.series.map(item => item));
      barRects.enter()
        .append('rect')
        .merge(barRects)
        .attr('class', 'bar')
        .attr('width', x1Scale.bandwidth())
        .attr('height', d => height - y(d.value))
        .attr('x', (d: any) => x1Scale(d.name))
        .attr('y', d => y(d.value))
        .attr('fill', (d, i) => this.barColors[i]);
 
      let yAxis = chartWrap.selectAll<SVGGElement, number>('g.y-axis').data([1]);
      yAxis.enter()
        .append('g')
        .attr('class', 'y-axis')
        .merge(yAxis)
        .call(d3.axisLeft(y));
    }
  }
}

This is it for d3 angular example tutorial. I hope you can use it similar concept to create the container for other charts like pie, bubble plot and many others. If you have any problem contact me through my contact form in this website.

SHARE ON
Buffer

Enjoyed this article?

Like us on

D3

Avatar for SNK

About SNK

Hello Welcome to my Blog. I develop Websites Using Laravel Framwork & WordPress. Get Latest updates on Facebook | Twitter

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Get Connected !! With Us

TOP POSTS

  • How to Setup Spring MVC Project From Scratch in Intellij IDEA ?
  • Spring Configuration Class in JAVA [Class VS XML Config]
  • Annotations Based Configuration in Spring Framework
  • How to Configure Spring Framework with XML Configurations?
  • How to Remove Project Name from URL in JSP Project in Intellij IDEA ?

TUTORIALS TILL DATE

  • September 2022 (6)
  • June 2021 (7)
  • October 2020 (5)
  • September 2020 (6)
  • September 2018 (14)
  • August 2018 (3)
  • July 2018 (4)
  • March 2018 (8)
  • February 2018 (5)
  • January 2018 (1)
  • December 2017 (2)
  • August 2017 (8)
  • May 2017 (1)
  • April 2017 (1)
  • March 2017 (4)
  • February 2017 (3)
  • January 2017 (4)

CATEGORIES

  • Angular (2)
  • CSS3 (3)
  • D3 (3)
  • HTML5 (7)
  • JAVA (11)
  • Javascript (20)
  • jQuery (8)
  • Laravel (35)
  • Others (3)
  • PHP (11)
  • Spring (2)
  • WordPress (10)

Top Categories

  • Angular
  • CSS3
  • D3
  • HTML5
  • JAVA
  • Javascript
  • jQuery
  • Laravel
  • Others
  • PHP
  • Spring
  • WordPress

Get in Touch

DMCA.com Protection Status

Recent Articles

  • How to Setup Spring MVC Project From Scratch in Intellij IDEA ?
  • Spring Configuration Class in JAVA [Class VS XML Config]
  • Annotations Based Configuration in Spring Framework
  • How to Configure Spring Framework with XML Configurations?
  • How to Remove Project Name from URL in JSP Project in Intellij IDEA ?

© 2012-22 CodeIn House.  •  All Rights Reserved.