11import {
22 Component ,
3+ ElementRef ,
34 inject ,
45 input ,
56 OnChanges ,
7+ OnDestroy ,
68 OnInit ,
79 SimpleChanges ,
10+ viewChild ,
811} from '@angular/core' ;
912import { ReportsStateService } from '../reports-state.service' ;
1013
@@ -15,10 +18,33 @@ import {
1518 SettingsService ,
1619} from '@placeos/common' ;
1720import { TranslatePipe } from '@placeos/components' ;
18- import { LineChart , PieChart } from 'chartist' ;
21+ import {
22+ Chart ,
23+ LineController ,
24+ LineElement ,
25+ PointElement ,
26+ LinearScale ,
27+ CategoryScale ,
28+ PieController ,
29+ ArcElement ,
30+ Tooltip ,
31+ Legend ,
32+ } from 'chart.js' ;
1933import { format } from 'date-fns' ;
2034import { combineLatest } from 'rxjs' ;
2135
36+ Chart . register (
37+ LineController ,
38+ LineElement ,
39+ PointElement ,
40+ LinearScale ,
41+ CategoryScale ,
42+ PieController ,
43+ ArcElement ,
44+ Tooltip ,
45+ Legend ,
46+ ) ;
47+
2248@Component ( {
2349 selector : 'report-desks-charts' ,
2450 template : `
@@ -33,21 +59,19 @@ import { combineLatest } from 'rxjs';
3359 <div class="border-base-200 border-b p-4 text-xl font-bold">
3460 {{ 'APP.CONCIERGE.REPORTS_DAILY_HEADER' | translate }}
3561 </div>
36- <div
37- id="daily-chart"
38- class="ct-chart ct-octave mx-auto h-56 w-full max-w-full"
39- ></div>
62+ <div class="mx-auto h-56 w-full max-w-full p-2">
63+ <canvas #dailyChart></canvas>
64+ </div>
4065 </div>
4166 <div
4267 class="border-base-200 bg-base-100 h-72 flex-1 rounded-sm border"
4368 >
4469 <div class="border-base-200 border-b p-4 text-xl font-bold">
4570 {{ 'APP.CONCIERGE.REPORTS_LEVEL_UTIL_HEADER' | translate }}
4671 </div>
47- <div
48- id="level-chart"
49- class="ct-chart ct-octave mx-auto h-56 w-[24rem] max-w-full"
50- ></div>
72+ <div class="mx-auto h-56 w-[24rem] max-w-full p-2">
73+ <canvas #levelChart></canvas>
74+ </div>
5175 </div>
5276 </div>
5377 ` ,
@@ -57,7 +81,7 @@ import { combineLatest } from 'rxjs';
5781 display: block;
5882 }
5983
60- .is-print .ct-chart {
84+ .is-print canvas {
6185 width: 8cm !important;
6286 }
6387 ` ,
@@ -66,7 +90,7 @@ import { combineLatest } from 'rxjs';
6690} )
6791export class ReportDesksChartsComponent
6892 extends AsyncHandler
69- implements OnInit , OnChanges
93+ implements OnInit , OnChanges , OnDestroy
7094{
7195 private _state = inject ( ReportsStateService ) ;
7296 private _org = inject ( OrganisationService ) ;
@@ -79,8 +103,12 @@ export class ReportDesksChartsComponent
79103 this . _state . counts ,
80104 ] ) ;
81105
82- private _day_chart : any ;
83- private _level_chart : any ;
106+ private _daily_chart_el =
107+ viewChild < ElementRef < HTMLCanvasElement > > ( 'dailyChart' ) ;
108+ private _level_chart_el =
109+ viewChild < ElementRef < HTMLCanvasElement > > ( 'levelChart' ) ;
110+ private _day_chart : Chart | null = null ;
111+ private _level_chart : Chart | null = null ;
84112
85113 public ngOnInit ( ) {
86114 this . subscription (
@@ -100,6 +128,12 @@ export class ReportDesksChartsComponent
100128 }
101129 }
102130
131+ public override ngOnDestroy ( ) {
132+ super . ngOnDestroy ( ) ;
133+ this . _day_chart ?. destroy ( ) ;
134+ this . _level_chart ?. destroy ( ) ;
135+ }
136+
103137 public updateCharts ( ) {
104138 this . timeout (
105139 'update_charts' ,
@@ -108,39 +142,91 @@ export class ReportDesksChartsComponent
108142 this . updateDailyChart ( day_list ) ;
109143 const [ mappings , counts ] = await nextValueFrom ( this . stats ) ;
110144 this . updateLevelChart ( mappings , counts ) ;
111- this . timeout (
112- 'update_charts' ,
113- ( ) => this . updateDailyChart ( day_list ) ,
114- 500 ,
115- ) ;
116145 } ,
117146 50 ,
118147 ) ;
119148 }
120149
121150 public updateDailyChart ( list ) {
122- const data = {
123- labels : list . map ( ( _ ) => format ( _ . date , 'dd MMM' ) ) ,
124- series : [ list . map ( ( _ ) => + _ . utilisation ) ] ,
125- } ;
126- this . _day_chart = new LineChart ( '#daily-chart' , data ) ;
151+ const el = this . _daily_chart_el ( ) ?. nativeElement ;
152+ if ( ! el ) return ;
153+ this . _day_chart ?. destroy ( ) ;
154+ this . _day_chart = new Chart ( el , {
155+ type : 'line' ,
156+ data : {
157+ labels : list . map ( ( _ ) => format ( _ . date , 'dd MMM' ) ) ,
158+ datasets : [
159+ {
160+ data : list . map ( ( _ ) => + _ . utilisation ) ,
161+ borderColor : 'rgb(59, 130, 246)' ,
162+ backgroundColor : 'rgba(59, 130, 246, 0.1)' ,
163+ fill : true ,
164+ tension : 0.3 ,
165+ } ,
166+ ] ,
167+ } ,
168+ options : {
169+ responsive : true ,
170+ maintainAspectRatio : false ,
171+ animation : this . print ( ) ? false : undefined ,
172+ plugins : {
173+ legend : { display : false } ,
174+ } ,
175+ scales : {
176+ y : {
177+ beginAtZero : true ,
178+ } ,
179+ } ,
180+ } ,
181+ } ) ;
127182 }
128183
129184 public updateLevelChart ( mapping , count ) {
185+ const el = this . _level_chart_el ( ) ?. nativeElement ;
186+ if ( ! el ) return ;
130187 let { zones } = mapping || { zones : [ ] } ;
131188 if ( ! zones . length ) {
132189 zones = this . _settings . get ( 'app.use_region' )
133190 ? this . _org . levelsForRegion ( ) . map ( ( _ ) => _ . id )
134191 : this . _org . levelsForBuilding ( ) . map ( ( _ ) => _ . id ) ;
135192 }
136193 const zone_list = ( zones || [ ] ) . filter ( ( _ ) => ( count [ _ ] || 0 ) > 0 ) ;
137- const data = {
138- labels : zone_list . map ( ( _ ) => {
139- const level = this . _org . levelWithID ( [ _ ] ) ;
140- return level ?. display_name || level . name || '' ;
141- } ) ,
142- series : zone_list . map ( ( _ ) => count [ _ ] || 0 ) ,
143- } ;
144- this . _level_chart = new PieChart ( '#level-chart' , data ) ;
194+ const labels = zone_list . map ( ( _ ) => {
195+ const level = this . _org . levelWithID ( [ _ ] ) ;
196+ return level ?. display_name || level . name || '' ;
197+ } ) ;
198+ const data = zone_list . map ( ( _ ) => count [ _ ] || 0 ) ;
199+ this . _level_chart ?. destroy ( ) ;
200+ this . _level_chart = new Chart ( el , {
201+ type : 'pie' ,
202+ data : {
203+ labels,
204+ datasets : [
205+ {
206+ data,
207+ backgroundColor : [
208+ 'rgb(59, 130, 246)' ,
209+ 'rgb(16, 185, 129)' ,
210+ 'rgb(245, 158, 11)' ,
211+ 'rgb(239, 68, 68)' ,
212+ 'rgb(139, 92, 246)' ,
213+ 'rgb(236, 72, 153)' ,
214+ 'rgb(20, 184, 166)' ,
215+ 'rgb(249, 115, 22)' ,
216+ ] ,
217+ } ,
218+ ] ,
219+ } ,
220+ options : {
221+ responsive : true ,
222+ maintainAspectRatio : false ,
223+ animation : this . print ( ) ? false : undefined ,
224+ plugins : {
225+ legend : {
226+ position : 'right' ,
227+ } ,
228+ } ,
229+ } ,
230+ } ) ;
145231 }
146232}
0 commit comments