257 lines
6.9 KiB
TypeScript
257 lines
6.9 KiB
TypeScript
import { Component, computed, input, signal } from '@angular/core';
|
|
import { format } from 'date-fns';
|
|
import { EChartsOption } from 'echarts';
|
|
import { LineChart } from 'echarts/charts';
|
|
import {
|
|
GridComponent,
|
|
MarkPointComponent,
|
|
TooltipComponent,
|
|
} from 'echarts/components';
|
|
import { ECharts } from 'echarts/core';
|
|
import { UtilNgxEchartsModule } from '../../../core/components/ngx-echarts/util-ngx-echarts.module';
|
|
|
|
@Component({
|
|
selector: 'app-trend-graph',
|
|
imports: [UtilNgxEchartsModule],
|
|
template: `<div
|
|
dksEcharts
|
|
[defaultHeight]="70"
|
|
[options]="options()"
|
|
[extentions]="extentions()"
|
|
(chartInit)="setChartInstance($event)"
|
|
></div>`,
|
|
styles: ``,
|
|
})
|
|
export class TrendGraphComponent {
|
|
data = input<{ date: Date; ordinanceType: string; revenueSum: number }[]>();
|
|
|
|
private chart?: ECharts;
|
|
|
|
public readonly options = computed<EChartsOption>(() => {
|
|
return this.generateEchartsOptions();
|
|
});
|
|
|
|
extentions = signal([
|
|
LineChart,
|
|
GridComponent,
|
|
TooltipComponent,
|
|
MarkPointComponent,
|
|
]);
|
|
|
|
constructor() {
|
|
// effect(() => {
|
|
// console.log(`chartvalue changed`, this.data(), this.chart);
|
|
// const currentData = this.data();
|
|
// if (!currentData) return;
|
|
// const groupedByOrdinanceType = [...currentData]
|
|
// .sort(
|
|
// ({ date: aDate }, { date: bDate }) =>
|
|
// new Date(aDate).getTime() - new Date(bDate).getTime()
|
|
// )
|
|
// .reduce((sum, { ordinanceType, revenueSum }) => {
|
|
// return {
|
|
// ...sum,
|
|
// [ordinanceType]: [
|
|
// ...(sum[ordinanceType] ? sum[ordinanceType] : []),
|
|
// revenueSum,
|
|
// ],
|
|
// };
|
|
// }, {} as Record<string, number[]>);
|
|
// setTimeout(() => {
|
|
// if (!!this.chart) {
|
|
// console.log({
|
|
// xAxis: [
|
|
// {
|
|
// data: [
|
|
// ...new Set(
|
|
// this.data()?.map(({ date }) =>
|
|
// format(new Date(date), 'EEE: dd.MM')
|
|
// )
|
|
// ),
|
|
// ],
|
|
// },
|
|
// ],
|
|
// series: [
|
|
// ...Object.entries(groupedByOrdinanceType).map(
|
|
// ([ot, revenues]) => {
|
|
// return {
|
|
// id: ot,
|
|
// data: revenues,
|
|
// };
|
|
// }
|
|
// ),
|
|
// // {
|
|
// // data: [
|
|
// // {
|
|
// // value: this.data(),
|
|
// // },
|
|
// // ],
|
|
// // },
|
|
// ],
|
|
// });
|
|
// this.chart.setOption({
|
|
// xAxis: [
|
|
// {
|
|
// data: [
|
|
// ...new Set(
|
|
// this.data()?.map(({ date }) =>
|
|
// format(new Date(date), 'EEEE: dd.MM')
|
|
// )
|
|
// ),
|
|
// ],
|
|
// },
|
|
// ],
|
|
// series: [
|
|
// ...Object.entries(groupedByOrdinanceType).map(
|
|
// ([ot, revenues]) => {
|
|
// return {
|
|
// id: ot,
|
|
// data: [{ value: revenues }],
|
|
// };
|
|
// }
|
|
// ),
|
|
// // {
|
|
// // data: [
|
|
// // {
|
|
// // value: this.data(),
|
|
// // },
|
|
// // ],
|
|
// // },
|
|
// ],
|
|
// });
|
|
// }
|
|
// }, 1000);
|
|
// });
|
|
}
|
|
|
|
generateEchartsOptions(): EChartsOption {
|
|
|
|
const baseOptions: EChartsOption = {
|
|
grid: {
|
|
left: '30px',
|
|
right: '30px',
|
|
bottom: '3px',
|
|
top: '15px',
|
|
// containLabel: false,
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
boundaryGap: false,
|
|
axisLabel: { show: false },
|
|
axisTick: { show: false },
|
|
axisLine: { show: true },
|
|
splitLine: { show: false },
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
axisLabel: { show: false },
|
|
axisTick: { show: false },
|
|
axisLine: { show: true },
|
|
splitLine: { show: false },
|
|
min: 0,
|
|
max: 'dataMax',
|
|
},
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
// axisPointer: {
|
|
// type: 'cross',
|
|
// label: {
|
|
// precision: 2,
|
|
// },
|
|
// },
|
|
formatter: function (params: any) {
|
|
const param = params[0];
|
|
const dateLabel = param.name;
|
|
const revenueValue = param.value;
|
|
|
|
const formattedRevenue =
|
|
typeof revenueValue === 'number'
|
|
? revenueValue.toLocaleString('de-DE', {
|
|
style: 'currency',
|
|
currency: 'EUR',
|
|
})
|
|
: revenueValue; // Fallback falls kein Zahlenwert
|
|
|
|
return `${dateLabel}<br/><b>Umsatz: ${formattedRevenue}</b>`;
|
|
},
|
|
backgroundColor: 'rgba(50,50,50,0.7)',
|
|
borderColor: '#333',
|
|
borderWidth: 0,
|
|
textStyle: {
|
|
color: '#fff',
|
|
},
|
|
},
|
|
series: [
|
|
{id: '1. KTW', data: []},
|
|
{id: '2. TSW', data: []},
|
|
{id: '3. BTW', data: []},
|
|
// {
|
|
// data: [],
|
|
// type: 'line',
|
|
// // smooth: true,
|
|
// // showSymbol: false,
|
|
// emphasis: {
|
|
// focus: 'series',
|
|
// },
|
|
// markPoint: {
|
|
// symbol: 'circle',
|
|
// symbolSize: 25,
|
|
// label: {
|
|
// formatter: '{c}€',
|
|
// },
|
|
// data: [
|
|
// { name: 'min', type: 'min' },
|
|
// { name: 'max', type: 'max' },
|
|
// { name: 'Current day', x: 'Di', y: 14744 },
|
|
// ],
|
|
// },
|
|
// },
|
|
],
|
|
};
|
|
|
|
// return baseOptions
|
|
|
|
const currentData = this.data();
|
|
if (!currentData) return baseOptions;
|
|
|
|
const groupedByOrdinanceType = [...currentData]
|
|
.sort(
|
|
({ date: aDate }, { date: bDate }) =>
|
|
new Date(aDate).getTime() - new Date(bDate).getTime()
|
|
)
|
|
.reduce((sum, { ordinanceType, revenueSum }) => {
|
|
return {
|
|
...sum,
|
|
[ordinanceType]: [
|
|
...(sum[ordinanceType] ? sum[ordinanceType] : []),
|
|
revenueSum,
|
|
],
|
|
};
|
|
}, {} as Record<string, number[]>);
|
|
|
|
return {
|
|
...baseOptions,
|
|
xAxis: {
|
|
...baseOptions.xAxis,
|
|
// data: [
|
|
// ...new Set(
|
|
// this.data()?.map(({ date }) => format(new Date(date), 'EEE: dd.MM'))
|
|
// ),
|
|
// ],
|
|
},
|
|
series: [
|
|
...Object.entries(groupedByOrdinanceType).map(([ot, revenues]) => {
|
|
return {
|
|
id: ot,
|
|
data: revenues,
|
|
};
|
|
}),
|
|
],
|
|
};
|
|
}
|
|
|
|
setChartInstance(chart: ECharts) {
|
|
this.chart = chart;
|
|
}
|
|
}
|