From 985aa5f83b820535e77eb85270dc7f99e21074fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sun, 17 Mar 2024 16:01:48 +0100 Subject: [PATCH] Partial Correct heatMap implementation --- .../heatmap-activity.component.html | 13 +- .../heatmap-activity.component.ts | 288 +++++++++--------- .../taskgroup-activity.component.html | 2 +- .../taskgroup-activity.component.ts | 2 +- 4 files changed, 160 insertions(+), 145 deletions(-) diff --git a/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.html b/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.html index 9c020bf..94db31a 100644 --- a/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.html +++ b/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.html @@ -1,8 +1,11 @@ -
+
diff --git a/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.ts b/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.ts index 768ebba..301e822 100644 --- a/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.ts +++ b/frontend/src/app/statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component.ts @@ -1,168 +1,180 @@ -import {Component, Input, OnInit, ViewChild} from '@angular/core'; -import {ApexAxisChartSeries, ChartComponent, ChartType} from "ng-apexcharts"; -import {ChartOptions} from "../taskgroup-activity.component"; +import {Component, Input, OnChanges, ViewChild} from '@angular/core'; + +import { + ApexAxisChartSeries, + ApexTitleSubtitle, + ApexDataLabels, + ApexChart, + ApexPlotOptions, ChartComponent, ApexXAxis, ApexYAxis, ApexTooltip +} from "ng-apexcharts"; +import {generate} from "rxjs"; import * as moment from "moment"; import {HistoryService, TaskgroupActivityInfo, TaskgroupPathInfo} from "../../../../api"; - -interface XYData { - x: any, - y: any -} +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + dataLabels: ApexDataLabels; + title: ApexTitleSubtitle; + plotOptions: ApexPlotOptions; + xAxis: ApexXAxis, + yAxis: ApexYAxis, + tooltip: ApexTooltip +}; @Component({ selector: 'app-heatmap-activity', templateUrl: './heatmap-activity.component.html', styleUrls: ['./heatmap-activity.component.css'] }) -export class HeatmapActivityComponent implements OnInit{ +export class HeatmapActivityComponent implements OnChanges{ - @ViewChild("chart") chart?: ChartComponent; - public chartOptions: Partial = this.generateChartOptions() + @ViewChild("chart") chart: ChartComponent | undefined; + @Input() selectedTaskgroupPath: TaskgroupPathInfo | undefined + public chartOptions: Partial | undefined; - @Input() selectedTaskgroupPath?: TaskgroupPathInfo + maxValue = 120 constructor(private historyService: HistoryService) { + } - ngOnInit() { - this.chartOptions = this.generateChartOptions(); - } - - generateChartOptions(): Partial { - return { - series: this.generateSeries(), - chart: { - height: 350, - type: 'heatmap', - }, - title: { - text: "" - }, - dataLabels: { - enabled: false - }, - colors: ["#008FFB"], - }; - } - - generateSeries() : ApexAxisChartSeries { - const series: ApexAxisChartSeries = [] - + ngOnChanges() { if(this.selectedTaskgroupPath != undefined) { - const startingDate = new Date(2023, 4, 9); - const endDate = new Date(2023, 11, 20); - let activityInfos: TaskgroupActivityInfo[]; this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet( - this.selectedTaskgroupPath.rootTasktroup.taskgroupID, - moment().subtract(6, "months").format("YYYY-MM-DD"), - moment().add(2, 'days').format("YYYY-MM-DD"), - true + this.selectedTaskgroupPath!.rootTasktroup.taskgroupID, + moment().startOf('year').format("YYYY-MM-DD"), + moment().endOf("year").format("YYYY-MM-DD"), + false ).subscribe({ next: resp => { - activityInfos = resp; - const data: XYData[][] = []; - let currentDate: moment.Moment = moment(activityInfos[0].date).subtract(moment(activityInfos[0].date).day(), 'days'); - - //Offset until data starts - let index = currentDate.day(); - while(currentDate < moment(activityInfos[0].date)) { - if(data[currentDate.day()] == undefined) { - data[currentDate.day()] = []; + const taskgroupActivityInfo = resp; + console.log("Chat Options") + this.chartOptions = { + series: [ + { + name: "Monday", + data: this.generateData(moment().startOf('year'),taskgroupActivityInfo) + }, + { + name: "Tuesday", + data: this.generateData(moment().startOf('year').add(1, "days"),taskgroupActivityInfo) + }, + { + name: "Wednesday", + data: this.generateData(moment().startOf('year').add(2, "days"), taskgroupActivityInfo) + }, + { + name: "Thursday", + data: this.generateData(moment().startOf('year').add(3, "days"), taskgroupActivityInfo) + }, + { + name: "Friday", + data: this.generateData(moment().startOf('year').add(4, "days"), taskgroupActivityInfo) + }, + { + name: "Saturday", + data: this.generateData(moment().startOf('year').add(5, "days"), taskgroupActivityInfo) + }, + { + name: "Sunday", + data: this.generateData(moment().startOf('year').add(6, "days"), taskgroupActivityInfo) + } + ], + chart: { + height: 350, + type: "heatmap" + }, + xAxis: { + labels: { + show: false + } + }, + yAxis: { + labels: { + show: true + } + }, + plotOptions: { + heatmap: { + shadeIntensity: 0.5, + colorScale: { + ranges: [ + { + from: 0, + to: 5, + name: "low", + color: "#00A100" + }, + { + from: 6, + to: 20, + name: "medium", + color: "#128FD9" + }, + { + from: 21, + to: 45, + name: "high", + color: "#FFB200" + }, + { + from: 46, + to: this.maxValue, + name: "extreme", + color: "#FF0000" + } + ] + } + } + }, + dataLabels: { + enabled: true, + style: { + fontSize: "12px" + } + }, + title: { + text: "HeatMap Chart with Color Range" + }, + tooltip: { + enabled: true, + y: { + formatter: function (value, { seriesIndex, dataPointIndex, w }) { + return "Spent " + value + " Minutes on
" + w.config.series[seriesIndex].data[dataPointIndex].extraInfo.format("dddd, MMMM D, YYYY") + "
" + }, + title: { + formatter: seriesName => "" + } + } } - - - data[currentDate.day()][index] = { - x: moment(currentDate).toDate(), - y: 0 - } - currentDate.add(1, 'days'); - } - - //inside data - activityInfos.forEach(activityInfo => { - const momentDate: moment.Moment = moment(activityInfo.date); - const seriesIndex = momentDate.day(); - - if(data[seriesIndex] == undefined) { - data[seriesIndex] = []; - } - - data[seriesIndex][index] = { - x: activityInfo.date, - y: activityInfo.activeMinutes - } - - - if(seriesIndex == 6) { - index++; - } - }) - - currentDate = moment(activityInfos[activityInfos.length-1].date); - currentDate = currentDate.add(1, "days"); - //offset outside data - for(let i=moment(activityInfos[activityInfos.length-1].date).day(); i<7; i++) { - data[i][index] = { - x: moment(currentDate).toDate(), - y: 0 - } - console.log(currentDate) - currentDate = currentDate.add(1, "days"); - } - - - series.push({ - name: "Saturday", - data: data[6] - }); - series.push({ - name: "Friday", - data: data[5] - }); - series.push({ - name: "Thursday", - data: data[4] - }); - series.push({ - name: "Wednesday", - data: data[3] - }); - series.push({ - name: "Tuesday", - data: data[2] - }); - series.push({ - name: "Monday", - data: data[1] - }); - series.push({ - name: "Sunday", - data: data[0] - }); + }; } }) - return series; - } else { - return series; } - } - generateData(start: moment.Moment, end: moment.Moment) { - const data: TaskgroupActivityInfo[] = []; - let currentDate: moment.Moment = moment(start); - while(currentDate <= end) { - data.push({ - date: currentDate.format("YYYY-MM-DD"), - activeMinutes: Math.floor(Math.random() * (100 + 1)) + private generateData(startingDate: moment.Moment, data: TaskgroupActivityInfo[]) { + let currentDate = startingDate; + + let series = [] + let endingDate = startingDate.clone().endOf('year'); + + while(currentDate.isBefore(endingDate)) { + let x = "w" + currentDate.isoWeek(); + let y = this.findTaskgroupActivityInfoByDate(currentDate, data) + let extraInfo = currentDate.clone() + + series.push({ + x: x, + y: y, + extraInfo: extraInfo }) - currentDate = currentDate.add(1, 'days'); + currentDate = currentDate.add(7, "days"); } - return data; + return series; } - setSelectedTaskgroupPath(taskgroupPath: TaskgroupPathInfo) { - this.selectedTaskgroupPath = taskgroupPath; - this.chartOptions = this.generateChartOptions(); + private findTaskgroupActivityInfoByDate(date: moment.Moment, data: TaskgroupActivityInfo[]) { + return data.find(taskActivity => moment(taskActivity.date).isSame(date)) } } diff --git a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html index 59d25d6..3d73666 100644 --- a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html +++ b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html @@ -14,5 +14,5 @@ - +
diff --git a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts index 526fdf5..c8bd252 100644 --- a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts +++ b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts @@ -70,7 +70,7 @@ export class TaskgroupActivityComponent implements OnInit{ this.simpleActivityDiagram.setSelectedTaskgroupPath(this.selectedTaskgroupPath!); } - this.heatMap?.setSelectedTaskgroupPath(this.selectedTaskgroupPath!); + //this.heatMap?.setSelectedTaskgroupPath(this.selectedTaskgroupPath!); } onSelectChartType() {