Skip to content

Instantly share code, notes, and snippets.

@babette-landmesser
Created November 16, 2020 06:56
Show Gist options
  • Save babette-landmesser/7f389381814c127d66a6a3fcc203fb73 to your computer and use it in GitHub Desktop.
Save babette-landmesser/7f389381814c127d66a6a3fcc203fb73 to your computer and use it in GitHub Desktop.
The component file for line chart
import { Component, ElementRef, Input, OnChanges } 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 LineChartComponent 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));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment