120 lines
3.2 KiB
TypeScript
120 lines
3.2 KiB
TypeScript
import {Component, HostListener, Input, OnInit, ViewChild} from '@angular/core';
|
|
import {faCodeFork, faEye, faScaleBalanced, faStar} from '@fortawesome/free-solid-svg-icons';
|
|
import {Language, Project} from "../../shared/model/project/project.model";
|
|
import {
|
|
ApexChart,
|
|
ApexDataLabels,
|
|
ApexNonAxisChartSeries,
|
|
ApexPlotOptions,
|
|
ApexResponsive,
|
|
ChartComponent
|
|
} from "ng-apexcharts";
|
|
|
|
|
|
export type ChartOptions = {
|
|
series: ApexNonAxisChartSeries;
|
|
colors: string[];
|
|
chart: ApexChart;
|
|
responsive: ApexResponsive[];
|
|
labels: string[];
|
|
plotOptions: ApexPlotOptions;
|
|
dataLabels: ApexDataLabels;
|
|
};
|
|
|
|
@Component({
|
|
selector: 'app-project-card',
|
|
templateUrl: './project-card.component.html',
|
|
styleUrls: ['./project-card.component.css'],
|
|
standalone: false
|
|
})
|
|
export class ProjectCardComponent implements OnInit {
|
|
@Input() inverted: boolean = false;
|
|
|
|
@Input() project!: Project;
|
|
|
|
@ViewChild('language-chart')
|
|
languageChart: ChartComponent | undefined;
|
|
|
|
chartOptions: ChartOptions | undefined;
|
|
|
|
// Stats Icons Definitions
|
|
faLicense = faScaleBalanced;
|
|
|
|
faStars = faStar;
|
|
|
|
faCodeFork = faCodeFork;
|
|
|
|
faEye = faEye;
|
|
|
|
private windowResizeTimeout: any;
|
|
|
|
ngOnInit() {
|
|
if (!!this.project.languages) {
|
|
const windowWidth = window.innerWidth;
|
|
this.chartOptions = this.generateChart(this.project.languages, windowWidth);
|
|
}
|
|
|
|
}
|
|
|
|
@HostListener('window:resize', ['$event'])
|
|
getScreenSize(event: Event) {
|
|
clearTimeout(this.windowResizeTimeout);
|
|
|
|
this.windowResizeTimeout = setTimeout(() => {
|
|
if (!this.project.languages) return;
|
|
this.chartOptions = this.generateChart(
|
|
this.project.languages, window.innerWidth
|
|
);
|
|
}, 100);
|
|
}
|
|
|
|
get hasLicense(): boolean {
|
|
return this.project.license !== undefined;
|
|
}
|
|
|
|
get hasLanguage(): boolean {
|
|
return this.project.languages !== undefined &&
|
|
this.project.languages?.length > 0;
|
|
}
|
|
|
|
private generateChart(languages: Language[], windowWidth: number): ChartOptions {
|
|
const WIDTH_PROPORTION = .9*.8;
|
|
const DOUBLE_PADDING_WIDTH = 40;
|
|
|
|
const responsiveWindowWidth = windowWidth >= 530 ?
|
|
300 : (windowWidth*WIDTH_PROPORTION - DOUBLE_PADDING_WIDTH);
|
|
|
|
return {
|
|
series: languages.map(value => value.percentage),
|
|
colors: languages.map(value => value.color),
|
|
chart: {
|
|
width: 380,
|
|
type: "donut"
|
|
},
|
|
labels: languages.map(value => value.name),
|
|
responsive: [
|
|
{
|
|
breakpoint: 530,
|
|
options: {
|
|
chart: {
|
|
width: responsiveWindowWidth
|
|
},
|
|
legend: {
|
|
position: "bottom"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
plotOptions: {
|
|
pie: {
|
|
expandOnClick: true,
|
|
|
|
}
|
|
},
|
|
dataLabels: {
|
|
enabled: false
|
|
}
|
|
};
|
|
}
|
|
}
|