forked from ttc/micro-frontend
-ระ บบ pie chart และคำนวณ สี
This commit is contained in:
@@ -200,18 +200,19 @@
|
|||||||
<button class="btn btn--ghost btn--compact">จัดการหมวดหมู่</button>
|
<button class="btn btn--ghost btn--compact">จัดการหมวดหมู่</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="pie-panel__content">
|
<div class="pie-panel__content">
|
||||||
<div class="pie-chart" [style.background]="expenseGradient">
|
<div class="pie-chart" [style.background]="ActSumDataGradient">
|
||||||
<div class="pie-chart__center">
|
<div class="pie-chart__center">
|
||||||
<p>รวมเดือนนี้</p>
|
<p>รวมเดือนนี้</p>
|
||||||
<strong>฿732K</strong>
|
<strong>฿732K</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="pie-legend">
|
<ul class="pie-legend">
|
||||||
<li class="pie-legend__item" *ngFor="let part of expenseBreakdown">
|
<li class="pie-legend__item" *ngFor="let idx of myActSumData.pie.expense">
|
||||||
<span class="swatch" [style.background]="part.color"></span>
|
<span class="swatch" [style.background]="idx.color"></span>
|
||||||
<div>
|
<div>
|
||||||
<p class="pie-legend__label">{{ part.label }}</p>
|
<p class="pie-legend__label">{{ idx.label }}</p>
|
||||||
<p class="pie-legend__value">{{ part.value }}%</p>
|
<p class="pie-legend__value">{{ idx.percent }}%</p>
|
||||||
|
<p class="pie-legend__value">{{ idx.value }} บาท</p>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
||||||
import { GeneralService } from '../../services/generalservice';
|
import { GeneralService } from '../../services/generalservice';
|
||||||
import { IDropAct, IStateDrop, IStateResultResponse, IActData } from '../../interfaces/dashboard.interface'
|
import { IDropAct, IStateDrop, IStateResultResponse, IActData, IActSumData } from '../../interfaces/dashboard.interface'
|
||||||
import { DashboardStateService } from '../../services/state/dashboard-state.service';
|
import { DashboardStateService } from '../../services/state/dashboard-state.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -20,6 +20,21 @@ export class MainDashboardComponent implements OnInit {
|
|||||||
myActData: IActData[] = [];
|
myActData: IActData[] = [];
|
||||||
// myDropAct: IStateDrop[] = [];
|
// myDropAct: IStateDrop[] = [];
|
||||||
myDropAct: IStateDrop = { income: [], expense: [] };
|
myDropAct: IStateDrop = { income: [], expense: [] };
|
||||||
|
myActSumData: IActSumData = {
|
||||||
|
summary: {
|
||||||
|
totalIncome: '',
|
||||||
|
totalExpense: '',
|
||||||
|
netProfit: '',
|
||||||
|
profitRate: '',
|
||||||
|
adjustedProfitRate: '',
|
||||||
|
period: ''
|
||||||
|
},
|
||||||
|
pie: {
|
||||||
|
income: [],
|
||||||
|
expense: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ActSumDataGradient: any
|
||||||
|
|
||||||
|
|
||||||
readonly ownerName = 'Nuttakit';
|
readonly ownerName = 'Nuttakit';
|
||||||
@@ -59,14 +74,14 @@ export class MainDashboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
readonly revenueTrend = [
|
// readonly revenueTrend = [
|
||||||
{ label: 'ม.ค.', value: 52 },
|
// { label: 'ม.ค.', value: 52 },
|
||||||
{ label: 'ก.พ.', value: 61 },
|
// { label: 'ก.พ.', value: 61 },
|
||||||
{ label: 'มี.ค.', value: 73 },
|
// { label: 'มี.ค.', value: 73 },
|
||||||
{ label: 'เม.ย.', value: 68 },
|
// { label: 'เม.ย.', value: 68 },
|
||||||
{ label: 'พ.ค.', value: 82 },
|
// { label: 'พ.ค.', value: 82 },
|
||||||
{ label: 'มิ.ย.', value: 77 }
|
// { label: 'มิ.ย.', value: 77 }
|
||||||
];
|
// ];
|
||||||
|
|
||||||
readonly quickRatios = [
|
readonly quickRatios = [
|
||||||
{ label: 'กระแสเงินสด', value: '+฿312K', status: 'positive' },
|
{ label: 'กระแสเงินสด', value: '+฿312K', status: 'positive' },
|
||||||
@@ -183,7 +198,6 @@ export class MainDashboardComponent implements OnInit {
|
|||||||
{ label: 'อื่นๆ', value: 8, color: '#e11d48' }
|
{ label: 'อื่นๆ', value: 8, color: '#e11d48' }
|
||||||
];
|
];
|
||||||
|
|
||||||
readonly expenseGradient = this.buildExpenseGradient();
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.setupFormControl();
|
this.setupFormControl();
|
||||||
@@ -192,14 +206,20 @@ export class MainDashboardComponent implements OnInit {
|
|||||||
this.myDropAct = data;
|
this.myDropAct = data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// ผลลับท์ ของ รายการ
|
||||||
this.dashboardStateService.getStateAccountResult().subscribe(data => {
|
this.dashboardStateService.getStateAccountResult().subscribe(data => {
|
||||||
if (data) {
|
if (data) {
|
||||||
this.myActData = data;
|
this.myActData = data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// ผลลัพการ คำนวณ ของ ปัญชี ต่างๆ
|
||||||
|
this.dashboardStateService.getStateSumResult().subscribe(data => {
|
||||||
|
if (data) {
|
||||||
|
this.myActSumData = data;
|
||||||
|
this.ActSumDataGradient = this.buildExpenseGradient()
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setupFormControl(){
|
setupFormControl(){
|
||||||
this.arrearsForm = new FormGroup({
|
this.arrearsForm = new FormGroup({
|
||||||
// email: new FormControl('',[Validators.required, Validators.email, Validators.maxLength(100)]),
|
// email: new FormControl('',[Validators.required, Validators.email, Validators.maxLength(100)]),
|
||||||
@@ -226,15 +246,20 @@ export class MainDashboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private buildExpenseGradient(): string {
|
private buildExpenseGradient(): string {
|
||||||
|
if (!this.myActSumData?.pie?.expense?.length) return '';
|
||||||
|
|
||||||
let current = 0;
|
let current = 0;
|
||||||
const segments = this.expenseBreakdown
|
const segments = this.myActSumData.pie.expense
|
||||||
.map(part => {
|
.map(part => {
|
||||||
const start = current;
|
const start = current;
|
||||||
const end = current + part.value;
|
const percent = parseFloat(part.percent); // แปลงจาก string → number
|
||||||
|
const end = current + percent;
|
||||||
current = end;
|
current = end;
|
||||||
return `${part.color} ${start}% ${end}%`;
|
return `${part.color} ${start}% ${end}%`;
|
||||||
})
|
})
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
return `conic-gradient(${segments})`;
|
return `conic-gradient(${segments})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Component, OnInit, ViewChild } from '@angular/core';
|
|||||||
import { ChartConfiguration, ChartOptions } from 'chart.js';
|
import { ChartConfiguration, ChartOptions } from 'chart.js';
|
||||||
import { BaseChartDirective } from 'ng2-charts';
|
import { BaseChartDirective } from 'ng2-charts';
|
||||||
import { GeneralService } from '../../services/generalservice';
|
import { GeneralService } from '../../services/generalservice';
|
||||||
import { IDropAct, IStateDrop, IActData } from '../../interfaces/dashboard.interface';
|
import { IDropAct, IStateDrop, IActData, IActSumData } from '../../interfaces/dashboard.interface';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -16,6 +16,20 @@ export class MainDashboardContentComponent implements OnInit {
|
|||||||
@ViewChild(BaseChartDirective) chart?: BaseChartDirective;
|
@ViewChild(BaseChartDirective) chart?: BaseChartDirective;
|
||||||
myDropAct!: IStateDrop;
|
myDropAct!: IStateDrop;
|
||||||
myActData: IActData[] = [];
|
myActData: IActData[] = [];
|
||||||
|
myActSumData: IActSumData = {
|
||||||
|
summary: {
|
||||||
|
totalIncome: '',
|
||||||
|
totalExpense: '',
|
||||||
|
netProfit: '',
|
||||||
|
profitRate: '',
|
||||||
|
adjustedProfitRate: '',
|
||||||
|
period: ''
|
||||||
|
},
|
||||||
|
pie: {
|
||||||
|
income: [],
|
||||||
|
expense: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private generalService: GeneralService,
|
private generalService: GeneralService,
|
||||||
@@ -84,8 +98,8 @@ export class MainDashboardContentComponent implements OnInit {
|
|||||||
next: (result: any) => {
|
next: (result: any) => {
|
||||||
if (result.code === '200') {
|
if (result.code === '200') {
|
||||||
this.generalService.trowApi(result);
|
this.generalService.trowApi(result);
|
||||||
this.myDropAct = result.data
|
this.myActSumData = result.data
|
||||||
this.dashboardStateService.setStateResult(this.myDropAct)
|
this.dashboardStateService.setStateSumResult(this.myActSumData);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
|
|||||||
@@ -18,11 +18,41 @@ export interface IActData {
|
|||||||
actcmt?: string,
|
actcmt?: string,
|
||||||
actacpdtm?: string
|
actacpdtm?: string
|
||||||
}
|
}
|
||||||
|
export interface IStateResultResponse {
|
||||||
|
data: IStateDrop;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IStateResultResponse {
|
export interface IStateResultResponse {
|
||||||
data: IStateDrop;
|
data: IStateDrop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface IActSumData {
|
||||||
|
summary: IActSummary;
|
||||||
|
pie: IActPie;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IActSummary {
|
||||||
|
totalIncome: string;
|
||||||
|
totalExpense: string;
|
||||||
|
netProfit: string;
|
||||||
|
profitRate: string;
|
||||||
|
adjustedProfitRate: string;
|
||||||
|
period: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IActPie {
|
||||||
|
expense: IActCategory[];
|
||||||
|
income: IActCategory[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IActCategory {
|
||||||
|
label: string;
|
||||||
|
value: number;
|
||||||
|
percent: string;
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
// ข้อมูลสินค้าหลัก
|
// ข้อมูลสินค้าหลัก
|
||||||
// export interface IProduct {
|
// export interface IProduct {
|
||||||
// id: string;
|
// id: string;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { IDropAct, IStateDrop, IActData } from '../../interfaces/dashboard.interface';
|
import { IDropAct, IStateDrop, IActData, IActSumData } from '../../interfaces/dashboard.interface';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@@ -8,7 +8,8 @@ import { IDropAct, IStateDrop, IActData } from '../../interfaces/dashboard.inter
|
|||||||
export class DashboardStateService {
|
export class DashboardStateService {
|
||||||
// ประกาศ BehaviorSubject ด้วย Interface
|
// ประกาศ BehaviorSubject ด้วย Interface
|
||||||
private dashboardState = new BehaviorSubject<IStateDrop | null>(null);
|
private dashboardState = new BehaviorSubject<IStateDrop | null>(null);
|
||||||
private accountting = new BehaviorSubject<IActData[] | null>(null);
|
private accounttingState = new BehaviorSubject<IActData[] | null>(null);
|
||||||
|
private actsumState = new BehaviorSubject<IActSumData | null>(null);
|
||||||
|
|
||||||
// ส่ง Observable ไปให้ components subscribe
|
// ส่ง Observable ไปให้ components subscribe
|
||||||
getStateResult(): Observable<IStateDrop | null> {
|
getStateResult(): Observable<IStateDrop | null> {
|
||||||
@@ -22,7 +23,12 @@ export class DashboardStateService {
|
|||||||
|
|
||||||
|
|
||||||
setStateAccountResult(dashboard: IActData[]): void {
|
setStateAccountResult(dashboard: IActData[]): void {
|
||||||
this.accountting.next(dashboard);
|
this.accounttingState.next(dashboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setStateSumResult(sumResult: IActSumData): void {
|
||||||
|
this.actsumState.next(sumResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
// เคลียร์ state
|
// เคลียร์ state
|
||||||
@@ -31,9 +37,15 @@ export class DashboardStateService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getStateAccountResult(): Observable<IActData[] | null> {
|
getStateAccountResult(): Observable<IActData[] | null> {
|
||||||
return this.accountting.asObservable();
|
return this.accounttingState.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
getStateSumResult(): Observable<IActSumData | null> {
|
||||||
|
return this.actsumState.asObservable();
|
||||||
|
}
|
||||||
// ดึงค่า current state (ไม่ใช่ observable)
|
// ดึงค่า current state (ไม่ใช่ observable)
|
||||||
// getCurrentState(): IDropAct | null {
|
// getCurrentState(): IDropAct | null {
|
||||||
// return this.dashboardState.value;
|
// return this.dashboardState.value;
|
||||||
|
|||||||
Reference in New Issue
Block a user