fix-statistics #89
@ -23,6 +23,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -59,7 +60,14 @@ public class StatisticController {
|
||||
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(taskgroupPermissionResult.getResult().calcActivityInfo(includeSubTaskgroups,
|
||||
LocalDate.parse(startingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(endingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
|
||||
List<TaskgroupActivityInfo> activityInfos = taskgroupPermissionResult.getResult().calcActivityInfo(includeSubTaskgroups,
|
||||
LocalDate.parse(startingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(endingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||
activityInfos.sort(new Comparator<TaskgroupActivityInfo>() {
|
||||
@Override
|
||||
public int compare(TaskgroupActivityInfo o1, TaskgroupActivityInfo o2) {
|
||||
return o1.getDate().compareTo(o2.getDate());
|
||||
}
|
||||
});
|
||||
return ResponseEntity.ok(activityInfos);
|
||||
}
|
||||
}
|
||||
|
@ -17,4 +17,12 @@ public class TaskgroupActivityInfo {
|
||||
this.date = localDate;
|
||||
this.activeMinutes = activeMinutes;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public int getActiveMinutes() {
|
||||
return activeMinutes;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ public class TaskgroupPathInfo {
|
||||
@JsonProperty
|
||||
private String taskgroupPath;
|
||||
|
||||
@JsonProperty
|
||||
private TaskgroupEntityInfo rootTasktroup;
|
||||
|
||||
@JsonProperty
|
||||
private List<TaskgroupEntityInfo> directChildren;
|
||||
public TaskgroupPathInfo(Taskgroup taskgroup) {
|
||||
@ -21,6 +24,7 @@ public class TaskgroupPathInfo {
|
||||
stringBuilder.append("/");
|
||||
}
|
||||
this.taskgroupPath = stringBuilder.substring(0, stringBuilder.length()-1);
|
||||
this.rootTasktroup = new TaskgroupEntityInfo(taskgroup);
|
||||
directChildren = taskgroup.getChildren().stream().map(TaskgroupEntityInfo::new).toList();
|
||||
}
|
||||
}
|
||||
|
@ -18,5 +18,6 @@ export interface TaskgroupPathInfo {
|
||||
*/
|
||||
taskgroupPath: string;
|
||||
directChildren: Array<TaskgroupEntityInfo>;
|
||||
rootTasktroup: TaskgroupEntityInfo;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,8 @@ import { DraggableSchedulerComponent } from './schedules/draggable-scheduler/dra
|
||||
import { TaskgroupActivityComponent } from './statistics/taskgroup-activity/taskgroup-activity.component';
|
||||
import {NgxSliderModule} from "ngx-slider-v2";
|
||||
import {NgApexchartsModule} from "ng-apexcharts";
|
||||
import { SimpleActivityDiagramComponent } from './statistics/taskgroup-activity/simple-activity-diagram/simple-activity-diagram.component';
|
||||
import { HeatmapActivityComponent } from './statistics/taskgroup-activity/heatmap-activity/heatmap-activity.component';
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
@ -124,6 +126,8 @@ import {NgApexchartsModule} from "ng-apexcharts";
|
||||
DateTimePickerComponent,
|
||||
DraggableSchedulerComponent,
|
||||
TaskgroupActivityComponent,
|
||||
SimpleActivityDiagramComponent,
|
||||
HeatmapActivityComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -0,0 +1,8 @@
|
||||
<div style="text-align:center">
|
||||
<apx-chart
|
||||
[series]="chartOptions.series!"
|
||||
[chart]="chartOptions.chart!"
|
||||
[xaxis]="chartOptions.xaxis!"
|
||||
[title]="chartOptions.title!"
|
||||
></apx-chart>
|
||||
</div>
|
@ -0,0 +1,21 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HeatmapActivityComponent } from './heatmap-activity.component';
|
||||
|
||||
describe('HeatmapActivityComponent', () => {
|
||||
let component: HeatmapActivityComponent;
|
||||
let fixture: ComponentFixture<HeatmapActivityComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [HeatmapActivityComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(HeatmapActivityComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,168 @@
|
||||
import {Component, Input, OnInit, ViewChild} from '@angular/core';
|
||||
import {ApexAxisChartSeries, ChartComponent, ChartType} from "ng-apexcharts";
|
||||
import {ChartOptions} from "../taskgroup-activity.component";
|
||||
import * as moment from "moment";
|
||||
import {HistoryService, TaskgroupActivityInfo, TaskgroupPathInfo} from "../../../../api";
|
||||
|
||||
|
||||
interface XYData {
|
||||
x: any,
|
||||
y: any
|
||||
}
|
||||
@Component({
|
||||
selector: 'app-heatmap-activity',
|
||||
templateUrl: './heatmap-activity.component.html',
|
||||
styleUrls: ['./heatmap-activity.component.css']
|
||||
})
|
||||
export class HeatmapActivityComponent implements OnInit{
|
||||
|
||||
@ViewChild("chart") chart?: ChartComponent;
|
||||
public chartOptions: Partial<ChartOptions> = this.generateChartOptions()
|
||||
|
||||
@Input() selectedTaskgroupPath?: TaskgroupPathInfo
|
||||
|
||||
constructor(private historyService: HistoryService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.chartOptions = this.generateChartOptions();
|
||||
}
|
||||
|
||||
generateChartOptions(): Partial<ChartOptions> {
|
||||
return {
|
||||
series: this.generateSeries(),
|
||||
chart: {
|
||||
height: 350,
|
||||
type: 'heatmap',
|
||||
},
|
||||
title: {
|
||||
text: ""
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
colors: ["#008FFB"],
|
||||
};
|
||||
}
|
||||
|
||||
generateSeries() : ApexAxisChartSeries {
|
||||
const series: ApexAxisChartSeries = []
|
||||
|
||||
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
|
||||
).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()] = [];
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
})
|
||||
currentDate = currentDate.add(1, 'days');
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
setSelectedTaskgroupPath(taskgroupPath: TaskgroupPathInfo) {
|
||||
this.selectedTaskgroupPath = taskgroupPath;
|
||||
this.chartOptions = this.generateChartOptions();
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<div style="text-align:center">
|
||||
<apx-chart
|
||||
[series]="chartOptions.series!"
|
||||
[chart]="chartOptions.chart!"
|
||||
[xaxis]="chartOptions.xaxis!"
|
||||
[title]="chartOptions.title!"
|
||||
></apx-chart>
|
||||
</div>
|
||||
<div class="custom-slider">
|
||||
<ngx-slider class="ngx-slider" [options]="options" [formControl]="sliderControl"
|
||||
(userChange)="onUserChange($event)"></ngx-slider>
|
||||
</div>
|
@ -0,0 +1,21 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SimpleActivityDiagramComponent } from './simple-activity-diagram.component';
|
||||
|
||||
describe('SimpleActivityDiagramComponent', () => {
|
||||
let component: SimpleActivityDiagramComponent;
|
||||
let fixture: ComponentFixture<SimpleActivityDiagramComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SimpleActivityDiagramComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(SimpleActivityDiagramComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,146 @@
|
||||
import {Component, Input, ViewChild} from '@angular/core';
|
||||
import {FormControl} from "@angular/forms";
|
||||
import {ChangeContext, LabelType, Options} from "ngx-slider-v2";
|
||||
import {ApexAxisChartSeries, ChartComponent, ChartType} from "ng-apexcharts";
|
||||
import {HistoryService, TaskgroupPathInfo, TaskgroupService} from "../../../../api";
|
||||
import * as moment from "moment/moment";
|
||||
import {ChartOptions} from "../taskgroup-activity.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-simple-activity-diagram',
|
||||
templateUrl: './simple-activity-diagram.component.html',
|
||||
styleUrls: ['./simple-activity-diagram.component.css']
|
||||
})
|
||||
export class SimpleActivityDiagramComponent {
|
||||
@Input('selectedChartype') selectedChartype: string = "bar";
|
||||
@Input() selectedTaskgroupPath: TaskgroupPathInfo | undefined;
|
||||
|
||||
sliderControl: FormControl = new FormControl()
|
||||
dateRange: Date[] = this.createDateRange();
|
||||
selectedDateRange: Date[] = this.dateRange;
|
||||
value: number = this.dateRange[0].getTime();
|
||||
options: Options = {
|
||||
stepsArray: this.dateRange.map((date: Date) => {
|
||||
return { value: date.getTime() };
|
||||
}),
|
||||
translate: (value: number, label: LabelType): string => {
|
||||
return new Date(value).toDateString();
|
||||
},
|
||||
floor: 0,
|
||||
ceil: this.dateRange.length,
|
||||
};
|
||||
|
||||
@ViewChild("chart") chart?: ChartComponent;
|
||||
public chartOptions: Partial<ChartOptions> = this.generateChartOptions()
|
||||
|
||||
constructor(private taskgroupService: TaskgroupService,
|
||||
private historyService: HistoryService) {
|
||||
}
|
||||
|
||||
createDateRange(): Date[] {
|
||||
const dates: Date[] = [];
|
||||
for (let i: number = 1; i <= 31; i++) {
|
||||
|
||||
dates.push(moment().subtract(30-i, 'd').toDate());
|
||||
}
|
||||
this.sliderControl.setValue([dates[0], dates[dates.length-1]])
|
||||
return dates;
|
||||
}
|
||||
|
||||
createDateRangeBetween(minValue: moment.Moment, maxValue: moment.Moment) {
|
||||
const dates: Date[] = [];
|
||||
let currentDate = moment(minValue);
|
||||
|
||||
while(currentDate <= maxValue) {
|
||||
dates.push(currentDate.toDate());
|
||||
currentDate = currentDate.add(1, 'days');
|
||||
}
|
||||
|
||||
return dates;
|
||||
}
|
||||
|
||||
onUserChange(changeContext: ChangeContext) {
|
||||
console.log("min " + moment(changeContext.value).format("YYYY-MM-DD"));
|
||||
console.log("max " + moment(changeContext.highValue!).format("YYYY-MM-DD"))
|
||||
this.selectedDateRange = this.createDateRangeBetween(moment(changeContext.value), moment(changeContext.highValue!))
|
||||
this.chartOptions = this.generateChartOptions()
|
||||
}
|
||||
|
||||
generateChartOptions(): Partial<ChartOptions> {
|
||||
return {
|
||||
series: this.generateSeries(),
|
||||
chart: {
|
||||
height: 350,
|
||||
type: this.selectedChartype as ChartType,
|
||||
stacked: true
|
||||
},
|
||||
title: {
|
||||
text: ""
|
||||
},
|
||||
xaxis: {
|
||||
categories: this.selectedDateRange.map(date => date.toDateString())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
generateSeries() : ApexAxisChartSeries {
|
||||
const series: ApexAxisChartSeries = []
|
||||
|
||||
if(this.selectedTaskgroupPath != undefined) {
|
||||
this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
|
||||
this.selectedTaskgroupPath!.rootTasktroup.taskgroupID,
|
||||
moment(this.selectedDateRange[0]).format("YYYY-MM-DD"),
|
||||
moment(this.selectedDateRange[this.selectedDateRange.length-1]).format("YYYY-MM-DD"),
|
||||
false
|
||||
).subscribe({
|
||||
next: resp => {
|
||||
series.push(
|
||||
{
|
||||
name: this.selectedTaskgroupPath!.rootTasktroup.taskgroupName,
|
||||
data: resp.map(dailyActivityInfo => dailyActivityInfo.activeMinutes)
|
||||
}
|
||||
);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this.selectedTaskgroupPath?.directChildren.forEach(taskgroup => {
|
||||
|
||||
this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
|
||||
taskgroup.taskgroupID,
|
||||
moment(this.selectedDateRange[0]).format("YYYY-MM-DD"),
|
||||
moment(this.selectedDateRange[this.selectedDateRange.length-1]).format("YYYY-MM-DD"), true
|
||||
).subscribe({
|
||||
next: resp => {
|
||||
series.push(
|
||||
{
|
||||
name: taskgroup.taskgroupName,
|
||||
data: resp.map(dailyActivityInfo => dailyActivityInfo.activeMinutes)
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
console.log(series);
|
||||
return series;
|
||||
|
||||
}
|
||||
|
||||
updateSerieSelection() {
|
||||
this.chartOptions = this.generateChartOptions()
|
||||
}
|
||||
|
||||
setSelectedChartType(selectedChartype: string) {
|
||||
this.selectedChartype = selectedChartype;
|
||||
this.updateSerieSelection();
|
||||
}
|
||||
|
||||
setSelectedTaskgroupPath(selectedTaskgroupPath: TaskgroupPathInfo) {
|
||||
this.selectedTaskgroupPath = selectedTaskgroupPath;
|
||||
this.updateSerieSelection();
|
||||
}
|
||||
}
|
@ -1,28 +1,18 @@
|
||||
<div class="container">
|
||||
<app-navigation-link-list #navLinkList [navigationLinks]="defaultNavigationLinkPath"></app-navigation-link-list>
|
||||
<mat-form-field style="width: 90%">
|
||||
<mat-label>Toppings</mat-label>
|
||||
<mat-select [(ngModel)]="selectedTaskgroupPath" (ngModelChange)="updateSerieSelection()">
|
||||
<mat-label>Taskgroup</mat-label>
|
||||
<mat-select [(ngModel)]="selectedTaskgroupPath" (ngModelChange)="onSelectTaskgroupPath()">
|
||||
<mat-option *ngFor="let topping of taskgroupPaths" [value]="topping">{{topping.taskgroupPath}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field style="width: 10%;">
|
||||
<mat-label>Toppings</mat-label>
|
||||
<mat-select [(ngModel)]="selectedChartype" (ngModelChange)="updateSerieSelection()">
|
||||
<mat-label>ChartType</mat-label>
|
||||
<mat-select [(ngModel)]="selectedChartype" (ngModelChange)="onSelectChartType()">
|
||||
<mat-option *ngFor="let topping of availableChartTypes" [value]="topping">{{topping}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div style="text-align:center">
|
||||
<apx-chart
|
||||
[series]="chartOptions.series!"
|
||||
[chart]="chartOptions.chart!"
|
||||
[xaxis]="chartOptions.xaxis!"
|
||||
[title]="chartOptions.title!"
|
||||
></apx-chart>
|
||||
</div>
|
||||
<div class="custom-slider">
|
||||
<ngx-slider class="ngx-slider" [options]="options" [formControl]="sliderControl" (userChangeStart)="onUserChangeStart($event)"
|
||||
(userChangeEnd)="onUserChangeStop($event)" (userChange)="onUserChange($event)"></ngx-slider>
|
||||
</div>
|
||||
<app-simple-activity-diagram *ngIf="selectedChartype !== 'heatmap'" #simpleActivityDiagram [selectedChartype]="selectedChartype" [selectedTaskgroupPath]="selectedTaskgroupPath"></app-simple-activity-diagram>
|
||||
<app-heatmap-activity *ngIf="selectedChartype === 'heatmap'" #heatMap></app-heatmap-activity>
|
||||
</div>
|
||||
|
@ -7,17 +7,22 @@ import {
|
||||
ApexAxisChartSeries,
|
||||
ApexChart,
|
||||
ApexXAxis,
|
||||
ApexTitleSubtitle, ChartType
|
||||
ApexTitleSubtitle, ChartType, ApexPlotOptions, ApexDataLabels
|
||||
} from "ng-apexcharts";
|
||||
import {timeInterval} from "rxjs";
|
||||
import {FormControl} from "@angular/forms";
|
||||
import {HistoryService, TaskgroupPathInfo, TaskgroupService} from "../../../api";
|
||||
import {SimpleActivityDiagramComponent} from "./simple-activity-diagram/simple-activity-diagram.component";
|
||||
import {HeatmapActivityComponent} from "./heatmap-activity/heatmap-activity.component";
|
||||
|
||||
export type ChartOptions = {
|
||||
series: ApexAxisChartSeries;
|
||||
chart: ApexChart;
|
||||
xaxis: ApexXAxis;
|
||||
title: ApexTitleSubtitle;
|
||||
plotOptions: ApexPlotOptions,
|
||||
colors: any,
|
||||
dataLabels: ApexDataLabels;
|
||||
};
|
||||
@Component({
|
||||
selector: 'app-taskgroup-activity',
|
||||
@ -40,32 +45,13 @@ export class TaskgroupActivityComponent implements OnInit{
|
||||
}
|
||||
];
|
||||
|
||||
@ViewChild('simpleActivityDiagram') simpleActivityDiagram ?: SimpleActivityDiagramComponent
|
||||
@ViewChild('heatMap') heatMap ?: HeatmapActivityComponent
|
||||
|
||||
selectedChartype: string = "bar";
|
||||
availableChartTypes: string[] = ["bar", "line", "area"]
|
||||
availableChartTypes: string[] = ["bar", "line", "area", "heatmap"]
|
||||
selectedTaskgroupPath: TaskgroupPathInfo | undefined
|
||||
taskgroupPaths: TaskgroupPathInfo[] = []
|
||||
sliderControl: FormControl = new FormControl()
|
||||
dateRange: Date[] = this.createDateRange();
|
||||
selectedDateRange: Date[] = this.dateRange;
|
||||
value: number = this.dateRange[0].getTime();
|
||||
options: Options = {
|
||||
stepsArray: this.dateRange.map((date: Date) => {
|
||||
return { value: date.getTime() };
|
||||
}),
|
||||
translate: (value: number, label: LabelType): string => {
|
||||
return new Date(value).toDateString();
|
||||
},
|
||||
floor: 0,
|
||||
ceil: this.dateRange.length,
|
||||
};
|
||||
|
||||
@ViewChild("chart") chart?: ChartComponent;
|
||||
public chartOptions: Partial<ChartOptions> = this.generateChartOptions()
|
||||
|
||||
constructor(private taskgroupService: TaskgroupService,
|
||||
private historyService: HistoryService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.taskgroupService.taskgroupsPathGet().subscribe({
|
||||
@ -75,82 +61,22 @@ export class TaskgroupActivityComponent implements OnInit{
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
createDateRange(): Date[] {
|
||||
const dates: Date[] = [];
|
||||
for (let i: number = 1; i <= 31; i++) {
|
||||
|
||||
dates.push(moment().subtract(30-i, 'd').toDate());
|
||||
}
|
||||
this.sliderControl.setValue([dates[0], dates[dates.length-1]])
|
||||
return dates;
|
||||
}
|
||||
|
||||
createDateRangeBetween(minValue: moment.Moment, maxValue: moment.Moment) {
|
||||
const dates: Date[] = [];
|
||||
const numberDays = maxValue.diff(minValue, 'days');
|
||||
for(let i=0; i<=numberDays; i++) {
|
||||
dates.push(minValue.add(i, 'd').toDate());
|
||||
}
|
||||
return dates;
|
||||
}
|
||||
|
||||
onUserChangeStart(changeContext: ChangeContext) {
|
||||
|
||||
//console.log("onUserChangeStart" + new Date(changeContext.value));
|
||||
}
|
||||
|
||||
onUserChangeStop(changeContext: ChangeContext) {
|
||||
//console.log("onUserChangeStop" + new Date(changeContext.highValue!))
|
||||
}
|
||||
|
||||
onUserChange(changeContext: ChangeContext) {
|
||||
const dateRange = this.createDateRangeBetween(moment(changeContext.value), moment(changeContext.highValue!))
|
||||
this.chartOptions = this.generateChartOptions()
|
||||
}
|
||||
|
||||
generateChartOptions(): Partial<ChartOptions> {
|
||||
|
||||
return {
|
||||
series: this.generateSeries(),
|
||||
chart: {
|
||||
height: 350,
|
||||
type: this.selectedChartype as ChartType,
|
||||
stacked: true
|
||||
},
|
||||
title: {
|
||||
text: ""
|
||||
},
|
||||
xaxis: {
|
||||
categories: this.selectedDateRange.map(date => date.toDateString())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
generateSeries() : ApexAxisChartSeries {
|
||||
const series: ApexAxisChartSeries = []
|
||||
this.selectedTaskgroupPath?.directChildren.forEach(taskgroup => {
|
||||
this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
|
||||
taskgroup.taskgroupID,
|
||||
moment(this.selectedDateRange[0]).format("YYYY-MM-DD"),
|
||||
moment(this.selectedDateRange[this.selectedDateRange.length-1]).format("YYYY-MM-DD"), true
|
||||
).subscribe({
|
||||
next: resp => {
|
||||
series.push(
|
||||
{
|
||||
name: taskgroup.taskgroupName,
|
||||
data: resp.map(dailyActivityInfo => dailyActivityInfo.activeMinutes)
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
return series;
|
||||
constructor(private taskgroupService: TaskgroupService) {
|
||||
|
||||
}
|
||||
|
||||
updateSerieSelection() {
|
||||
this.chartOptions = this.generateChartOptions()
|
||||
onSelectTaskgroupPath() {
|
||||
if(this.simpleActivityDiagram != undefined) {
|
||||
this.simpleActivityDiagram.setSelectedTaskgroupPath(this.selectedTaskgroupPath!);
|
||||
}
|
||||
|
||||
this.heatMap?.setSelectedTaskgroupPath(this.selectedTaskgroupPath!);
|
||||
}
|
||||
|
||||
onSelectChartType() {
|
||||
if(this.simpleActivityDiagram != undefined) {
|
||||
this.simpleActivityDiagram.setSelectedChartType(this.selectedChartype);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2612,6 +2612,7 @@ components:
|
||||
required:
|
||||
- taskgroupPath
|
||||
- directChildren
|
||||
- rootTasktroup
|
||||
additionalProperties: false
|
||||
properties:
|
||||
taskgroupPath:
|
||||
@ -2621,6 +2622,9 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
||||
rootTasktroup:
|
||||
type: object
|
||||
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
||||
TaskgroupActivityInfo:
|
||||
required:
|
||||
- date
|
||||
|
Loading…
Reference in New Issue
Block a user