Javascript 以角度10显示ngIf条件下的图表

Javascript 以角度10显示ngIf条件下的图表,javascript,angular,typescript,charts,angular-material,Javascript,Angular,Typescript,Charts,Angular Material,我将ChartJS与角度材质一起使用,并尝试使用localStorage对象在条件下显示图表 现在,我将本地存储对象设置为ChartData,并尝试让ChartData.DataPoints的条件下的图表显示,这是ChartData对象中的一个值 由于某种原因,我得到了一份工作 无法读取null的属性“getContext” 错误。如果ChartData.Datapoints在数组中有任何值,则图表将显示,如果没有,则隐藏。我该怎么做 view.component.html <!-

我将ChartJS与角度材质一起使用,并尝试使用localStorage对象在条件下显示图表

现在,我将本地存储对象设置为ChartData,并尝试让ChartData.DataPoints的条件下的图表显示,这是ChartData对象中的一个值

由于某种原因,我得到了一份工作

无法读取null的属性“getContext”

错误。如果ChartData.Datapoints在数组中有任何值,则图表将显示,如果没有,则隐藏。我该怎么做

view.component.html

    <!-- Charts -->
    <mat-card *ngIf="ChartData.DataPoints">
      <canvas id="viewChart"></canvas>
  </mat-card>

查看.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'
            }
        }
    });
}
导出类ViewComponent实现OnInit、OnDestroy、AfterViewInit{
viewData:任何;
viewName:字符串;
视图标签:编号;
页面索引:编号;
页面大小:数字;
sortCol:字符串;
排序方向:字符串;
过滤器:视图过滤器;
加载类型:字符串;
函数名:字符串[];
图表数据:任何;
FunctionsActive:boolean[];
获取数据:任何;
操作:ViewDataSource;
数据源:ViewDataSource;
页面大小选项:数字[]=[10,20,50];
contextMenuPosition={x:'0px',y:'0px'};
@ViewChild(MatSort)排序:MatSort;
@ViewChild(MatPaginator)分页器:MatPaginator;
@ViewChild(MatMenuTrigger)上下文菜单:MatMenuTrigger;
navSub:订阅;
selection=新SelectionModel(true,[]);
primaryTableValue:任何;
selectedIndexData:ViewDataSource;
帆布:任何;
ctx:任何;
图表图例:任何;
构造函数(私有actionService:actionService,私有路由:ActivatedRoute,私有路由器:路由器,公共对话框:MatDialog,
专用启动服务:启动服务){
//在虚拟ViewData上初始化这两个字段,以便mat表不会抛出错误。
this.viewData={
ColumnObjects:新数组(),
视图数据:{
DataRows:新数组()
}
};
}
恩戈尼尼特(){
//初始化数据源
this.dataSource=新的ViewDataSource(this.actionService);
//在组件第一次被导航到时初始化该组件。
这是initData();
//订阅路由器,以便此组件的任何新导航都会加载新数据。
this.navSub=this.router.events.subscribe((e:any)=>{
if(导航结束的实例){
这是initData();
}
});
//订阅数据源中的视图
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);
}
});
//图表
this.canvas=document.getElementById('viewChart');
this.ctx=this.canvas.getContext('2d');
this.ChartData=JSON.parse(localStorage.getItem('ChartData');
const data=this.ChartData;
//tslint:禁用下一行:仅箭头功能
const driverLabel=data.map(函数(e:any[])){
返回e[1];
});
//tslint:禁用下一行:仅箭头功能
const firstDataPoint=data.map(函数(e:any[])){
返回e[3];
});
//tslint:禁用下一行:仅箭头功能
const secondDataPoint=data.map(函数(e:any[])){
返回e[4];
});
//tslint:禁用下一行:仅箭头功能
const thirdDataPoint=data.map(函数(e:any[])){
返回e[5];
});
const viewChart=新图表(this.ctx{
类型:'bar',
数据:{
标签:driverLabel,
数据集:[
{
标签:“计划里程”,
数据:firstDataPoint,
边框宽度:1
},
{
标签:“实际英里数”,
数据:第二个数据点,
边框宽度:1
},
{
标签:“路线差异”,
数据:第三点,
边框宽度:1
}
]
},
选项:{
比例:{
雅克斯:[{
滴答声:{
贝吉纳泽罗:是的
}
}]
},
图例:{
显示:对,
位置:'右'
}
}
});
}

document.getElementById('viewChart')在this.ChartData=JSON.parse(localStorage.getItem('ChartData'))解决之前为空;尝试将此逻辑拆分为ngOnInit和NgoAfterContentInit我有点困惑,你的意思是它将是两个OnInit吗?@Xesenixone应该在获得document.getElementById的正确值后完成初始化的一部分('viewChart'),它将在view之后可用,并将呈现模板。您需要检查它是否实际为空。是的,在运行onInit之前,它是否为空