使用角度7,我整合了一个chart.js几天的电费。在我的应用程序的各个部分,我有类似的图表,加载下一个/前一天按钮等。
重新创建图表(在任何下一个或前一天点击)我基本上遵循
this.mainChart = new Chart('idOfCanvasOnHtmlComponent', {....})
this.mainChart.update()
它似乎仍旧旧图表有时在mouseover
上显示某些点并且看起来很奇怪,就像有多个图表加载在mouseover
上这很烦人!
import { Component, OnInit, AfterContentInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatDatepickerInputEvent } from '@angular/material/datepicker';
import { MiscHelper } from 'src/app/helpers/MiscHelper';
import { ChargeUnitService } from 'src/app/services/charge.unit.service';
import { ChargeUnit } from 'src/app/entities/charge.unit';
import { UserMessage, UserMessageType } from 'src/app/entities/user.message';
import { MessageService } from 'src/app/services/message.service';
import { Constants } from 'src/app/Constants';
import * as moment from 'moment';
import { MatIconRegistry } from '@angular/material';
import { DomSanitizer } from '@angular/platform-browser';
import Chart = require('chart.js')
import { MeasuringPoint } from 'src/app/entities/measuring.point';
import { MeasuringPointService } from 'src/app/services/measuring.point.service';
@Component({
selector: 'app-charge-unit-daily',
templateUrl: './charge-unit-daily.component.html',
styleUrls: [
'./charge-unit-daily.component.css',
'../../entities-list.component.css'
]
})
export class ChargeUnitDailyComponent implements AfterContentInit {
static readonly CHART_ID = 'canvasDaily'
currentDate: Date = moment('2019-03-06T00:00:01').toDate() //set default here
/** Header */
dateFormControl = new FormControl(this.currentDate)
statusMessage = 'Default status'
refreshButtonDisabled: boolean = false
/** CHART */
mainChart: Chart;
protected loadingDate: Date = new Date()
constructor(
iconRegistry: MatIconRegistry,
sanitizer: DomSanitizer,
protected messageService: MessageService,
protected entitiesService: ChargeUnitService,
protected parentService: MeasuringPointService,
) {
iconRegistry.addSvgIcon(
'refresh',
sanitizer.bypassSecurityTrustResourceUrl('assets/img/refresh-icon.svg'));
//Do nothing
}
public ngAfterContentInit() {
setTimeout(() => { //to avoid error...
if (this.parentService.currentEntity == null){
this.parentService.currentEntity = new MeasuringPoint(7) //TODO: remove me
}
console.debug('currentDate 1 :', this.currentDate)
this.setChart(this.currentDate)
this.dateFormControl.setValue(this.currentDate)
}, 10);
// this.setStatus('Default canvas...', true)
}//End ngOnInit
/**
*
* @param aDate
*/
protected setChart(aDate: Date){
let lStartDate = new Date(aDate)
lStartDate.setHours(0)
lStartDate.setMinutes(0)
lStartDate.setSeconds(1)
let lEndDate = new Date(aDate)
lEndDate.setHours(23)
lEndDate.setMinutes(59)
lEndDate.setSeconds(59)
this.setStatus('Loading...', false)
this.loadingDate = new Date()
console.debug('----- setChart->aDate:', aDate)
this.resetChart()
this.entitiesService.getBetween(lStartDate, lEndDate).subscribe(
lData => {
console.debug('Received data from entitiesService:', lData);
let lDataArray = (lData as unknown) as []
let lChargeUnitsArray: ChargeUnit[] = []
lDataArray.forEach(element => {
lChargeUnitsArray.push(new ChargeUnit().deserialize(element))
})
this.setChartDataFromEntities(lStartDate, lChargeUnitsArray)
},
lError => {
this.messageService.add(new UserMessage('charge-unit-daily.component->setChart Error:', lError, UserMessageType.Error));
this.setStatus('Error loading chart data:' + lError.toString(), true)
},
() => {
//loading terminated
}
);
}
onDateChanged(anEventType: string, anEvent: MatDatepickerInputEvent<Date> ) {
console.debug('onDateChanged clicked', anEvent)
let lDate = anEvent.value as Date
this.currentDate = lDate
this.setChart(lDate)
}
/**
*
* @param aDate
* @param aChargeUnitArray
*/
setChartDataFromEntities( aDate: Date, aChargeUnitArray: ChargeUnit[] ){
console.debug('setChartDataFromEntities->aChargeUnitArray', aChargeUnitArray)
let lChartDataArray = []
let lChartDataLineDataArray: Array<number> = []
let lChartLabelsArray: string[] = []
//Lines and labels
aChargeUnitArray.forEach(element => {
lChartDataLineDataArray.push(element.charge)
lChartLabelsArray.push(MiscHelper.dateTimeHMSForChart(element.timestamp))
});
//setting chart data
lChartDataArray[0] = {
data: lChartDataLineDataArray,
label: MiscHelper.dateForChartTooltips(aDate),
borderColor: Constants.CHART_DATASETS_BORDER_COLORS[0],
backgroundColor: Constants.CHART_DATASETS_BACKGROUND_COLORS[0],// removed otherwise not working
borderWidth: 2,
fill: 'origin'
}
console.debug('setChartDataFromEntities->lChartDataArray', lChartDataArray)
this.mainChart = new Chart(ChargeUnitDailyComponent.CHART_ID, {
type: 'line',
data: {
labels: lChartLabelsArray,
datasets: lChartDataArray,
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
},
responsive: true,
},
})
this.mainChart.update()
let lDiff = new Date().getTime() - this.loadingDate.getTime()
this.setStatus('Chart loaded:' + moment(lDiff).format('mm\'ss\'\''), true)
}
/**
*
*/
public resetChart(){
this.mainChart = new Chart(ChargeUnitDailyComponent.CHART_ID, {
type: 'line',
fillOpacity: .3,
data: {
labels: [],
datasets: []
},
options: {
legend: {
display: true
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
},
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"]
}
})
this.mainChart.update()
}
onRefreshClicked(anEvent){
console.debug('onRefreshClicked', anEvent)
this.setChart(this.currentDate)
}
onPreviousClicked(anEvent){
console.debug('onPreviousClicked', anEvent)
this.currentDate.setDate(this.currentDate.getDate() - 1)
this.dateFormControl.setValue(this.currentDate)
this.setChart(this.currentDate)
}
onNextClicked(anEvent){
console.debug('onNextClicked', anEvent)
this.currentDate.setDate(this.currentDate.getDate() + 1)
this.dateFormControl.setValue(this.currentDate)
this.setChart(this.currentDate)
}
}
<mat-toolbar>
<span>
<mat-form-field>
<input matInput
[matDatepicker]="matDatepicker"
[formControl]="dateFormControl"
(dateChange)="onDateChanged('change', $event)"
>
<mat-datepicker-toggle matSuffix [for]="matDatepicker"></mat-datepicker-toggle>
<mat-datepicker #matDatepicker></mat-datepicker>
</mat-form-field>
</span>
<span class="fill-remaining-space">
<button mat-raised-button (click)="onPreviousClicked($event)" color="accent"><</button>
<button mat-raised-button (click)="onNextClicked($event)" color="accent">></button>
<button matTooltip="Refresh" mat-icon-button (click)="onRefreshClicked($event)" [disabled]="refreshButtonDisabled">
<mat-icon svgIcon="refresh" class="mat-icon-">Refresh</mat-icon>
</button>
</span>
<span><p>Status:{{statusMessage}}</p></span>
<script src="node_modules/chart.js/src/chart.js"></script>
</mat-toolbar>
<div class="canvasContainer" style="display: block; "><!--Mandatory div including chart-->
<canvas id="canvasDaily">{{mainChart}}</canvas>
</div>
我想出的行为是图表创建只需要进行一次。
然后属性设置像this.mainChart.data.datasets = [...]
或this.mainChart.data.datasets.push (...)
否则,似乎有一张僵尸图表留在背景中并出现在mouseover
上。
为什么??大问题....