#javascript #angular #typescript #charts #angular-material
#javascript #angular #typescript #Диаграммы #angular-материал
Вопрос:
Я использую ChartJS с материалом Angular и пытаюсь отобразить диаграмму при условии, используя объект localStorage.
Прямо сейчас для объекта локального хранилища установлено значение chartData, и я пытаюсь отобразить диаграмму при условии для chartData.DataPoints, которое является значением в объекте chartData.
По какой-то причине я получаю
Не удается прочитать свойство ‘getContext’ с нулевым значением
ошибка. Я хочу иметь его там, где, если chartData.Datapoints имеет какие-либо значения в массиве, тогда диаграмма будет отображаться, если нет, то она скрыта. Как мне это сделать?
view.component.html
<!-- Charts -->
<mat-card *ngIf="ChartData.DataPoints">
<canvas id="viewChart"></canvas>
</mat-card>
view.component.ts
export class ViewComponent implements OnInit, OnDestroy, AfterViewInit {
viewData: any;
viewName: string;
viewTag: number;
pageIndex: number;
pageSize: number;
sortCol: string;
sortDirection: string;
filter: ViewFilter;
loadType: string;
FunctionNames: string[];
ChartData: any;
FunctionsActive: boolean[];
fetchedData: any;
action: ViewDataSource;
dataSource: ViewDataSource;
pageSizeOptions: number[] = [10, 20, 50];
contextMenuPosition = { x: '0 px', y: '0 px'};
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
navSub: Subscription;
selection = new SelectionModel<TableRow>(true, []);
primaryTableValue: any;
selectedIndexData: ViewDataSource;
canvas: any;
ctx: any;
ChartLegend: any;
constructor(private actionService: ActionService, private route: ActivatedRoute, private router: Router, public dialog: MatDialog,
private launchService: LaunchService) {
// Init these two fields on a dummy ViewData so that the mat-table does not throw errors.
this.viewData = {
ColumnObjects: new Array(),
ViewData: {
DataRows: new Array()
}
};
}
ngOnInit() {
// Init the dataSource
this.dataSource = new ViewDataSource(this.actionService);
// Init the component the first time it is navigated to.
this.initData();
// Subscribe to the router, so that any new navigation to this component loads new data.
this.navSub = this.router.events.subscribe((e: any) => {
if (e instanceof NavigationEnd) {
this.initData();
}
});
// Subscribe to the View in the DataSource
this.dataSource.view.subscribe(x => {
if (x.ActionName) {
this.viewName = x.ActionName;
this.viewData = x;
this.fetchedData = this.viewData.TableData;
console.log(this.viewData);
this.primaryTableValue = (this.viewData.ViewData.DbrAction.PrimaryTable);
}
});
// Charts
this.canvas = document.getElementById('viewChart');
this.ctx = this.canvas.getContext('2d');
this.ChartData = JSON.parse(localStorage.getItem('ChartData'));
const data = this.ChartData;
// tslint:disable-next-line: only-arrow-functions
const driverLabel = data.map(function (e: any[]) {
return e[1];
});
// tslint:disable-next-line: only-arrow-functions
const firstDataPoint = data.map(function (e: any[]) {
return e[3];
});
// tslint:disable-next-line: only-arrow-functions
const secondDataPoint = data.map(function (e: any[]) {
return e[4];
});
// tslint:disable-next-line: only-arrow-functions
const thirdDataPoint = data.map(function (e: any[]) {
return e[5];
});
const viewChart = new Chart(this.ctx, {
type: 'bar',
data: {
labels: driverLabel,
datasets: [
{
label: 'Plan Miles',
data: firstDataPoint,
borderWidth: 1
},
{
label: 'Actual Miles',
data: secondDataPoint,
borderWidth: 1
},
{
label: 'Route Variance',
data: thirdDataPoint,
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
display: true,
position: 'right'
}
}
});
}
Комментарии:
1. document.getElementById(‘viewChart’) равен нулю до этого. chartData = JSON.parse(localStorage.GetItem(‘chartData’)); разрешен попробуйте разделить эту логику на ngOnInit и ngAfterContentInit
2. Я немного смущен, вы имеете в виду, что это будет два OnInit? @Xesenix
3. одна часть инициализации должна быть выполнена после того, как вы получите правильное значение для document.getElementById(‘viewChart’), которое будет доступно после того, как view отобразит шаблон. Вам нужно будет проверить, действительно ли оно не равно null
4. да, это значение равно нулю до тех пор, пока не будет запущен OnInit