【问题标题】:Cant assign data to ng2 piechart after receiving it in HTTP response在 HTTP 响应中接收到数据后,无法将数据分配给 ng2 饼图
【发布时间】:2017-05-30 23:02:25
【问题描述】:

我的 HTML 标记如下所示,我使用的是依赖于 chart.js 的 NG2-Chart 库的饼图:

<h2>Home</h2>
<div style="display: block">
    <canvas baseChart class="chart"
            [data]="pieChartData"
            [labels]="pieChartLabels"
            [chartType]="pie"
            (chartHover)="chartHovered($event)"
            (chartClick)="chartClicked($event)">
    </canvas>
</div>

我编写了以下代码,添加它工作得非常好。我也可以看到图表并获得对事件处理程序的调用。我的组件代码(工作)如下所示:

import {Component, OnInit, AfterViewInit, AfterContentInit} from '@angular/core';
import {NgClass} from '@angular/common';

import {PieChartData} from '../shared/pie-chart-data';
import {HotelsService} from '../components/hotel/hotels.service';
import {Hotel} from '../entities/hotel';


import * as _ from 'underscore/underscore';

@Component({
    selector:'home'
    , templateUrl:'app/home/home.component.html'
})
export class HomeComponent implements OnInit{
    hotels: Hotel[];
    hotelCountByCity; 
    data = new PieChartData();

    pieChartData = [];
    pieChartLabels=[];

    constructor(private _hotelsService: HotelsService){}

    ngOnInit(){
        this.getActiveHotelsByCity();        

        console.log("On Init");
    }

    // events
    public chartClicked(e:any):void {
        // TODO : should open another chart which is not decided.
    }

    public chartHovered(e:any):void {
        // TODO : do something
    }

    private getActiveHotelsByCity(){ 
        //this.data.pieChartType = "pie";
        this.pieChartLabels = ["One", "Two", "Three"]; 
        this.pieChartData = [100,200,300];
    }
}

但是当我尝试从 Web 服务获取数据并将其分配给饼图时,我得到了奇怪的错误。我的组件代码(不工作):

import {Component, OnInit, AfterViewInit, AfterContentInit} from '@angular/core';
import {NgClass} from '@angular/common';

import {PieChartData} from '../shared/pie-chart-data';
import {HotelsService} from '../components/hotel/hotels.service';
import {Hotel} from '../entities/hotel';

import * as _ from 'underscore/underscore';

@Component({
    selector:'home'
    , templateUrl:'app/home/home.component.html'
})
export class HomeComponent implements OnInit{
    hotels: Hotel[];
    hotelCountByCity; 
    data = new PieChartData();

pieChartData = [];
pieChartLabels=[];

constructor(private _hotelsService: HotelsService){}

ngOnInit(){
    this.getActiveHotelsByCity();        

    console.log("On Init");
}

// events
public chartClicked(e:any):void {
    // TODO : should open another chart which is not decided.
}



   public chartHovered(e:any):void {
        // TODO : do something
    }

    private getActiveHotelsByCity(){  
        this._hotelsService.getAllActiveHotels()
                                .subscribe(
                                    res => this.hotelCountByCity =
                                                    _.countBy(
                                                        res.data.hotels
                                                        ,function(hotel: Hotel) {
                                                            return hotel.address.city;
                                                        })
                                    ,null
                                    , ()=> {
                                        this.pieChartLabels = _.keys(this.hotelCountByCity);
                                        this.pieChartData = _.values(this.hotelCountByCity);
                                        console.log("Reached success part of request");
                                    }
                                );
    }
}

我最初得到的错误堆栈树如下:

异常:未捕获(承诺中):TypeError:无法设置属性堆栈 的 [object Object] 只有一个 getter TypeError:无法设置 [object Object] 的属性堆栈,只有一个 getter 在assignAll (http://localhost:3000/node_modules/zone.js/dist/zone.js:704:29) 在 ViewWrappedError.ZoneAwareError (http://localhost:3000/node_modules/zone.js/dist/zone.js:775:16) 在 ViewWrappedError.BaseError [作为构造函数] (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:1104:38) 在 ViewWrappedError.WrappedError [作为构造函数] (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:1133:20) 在新的 ViewWrappedError (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:5106:20) 在 _View_HomeComponent_Host0.DebugAppView._rethrowWithContext (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:9427:27) 在 _View_HomeComponent_Host0.DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:9413:22) 在 ViewRef_.detectChanges (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:7398:24) 在 RouterOutlet.activate (http://localhost:3000/node_modules/@angular/router/bundles/router.umd.js:3458:46) 在 ActivateRoutes.placeComponentIntoOutlet (http://localhost:3000/node_modules/@angular/router/bundles/router.umd.js:2955:20) 在 ActivateRoutes.activateRoutes (http://localhost:3000/node_modules/@angular/router/bundles/router.umd.js:2933:26) 在评估 (http://localhost:3000/node_modules/@angular/router/bundles/router.umd.js:2902:23) 在 Array.forEach (本机) 在 ActivateRoutes.activateChildRoutes (http://localhost:3000/node_modules/@angular/router/bundles/router.umd.js:2901:33) 在 ActivateRoutes.activate (http://localhost:3000/node_modules/@angular/router/bundles/router.umd.js:2896:18)

在互联网上搜索后,我意识到这不是真正的错误。我在互联网上找到了一些找到真正错误的建议,而我发现的真正错误是:

"TypeError: Chart.controllers[meta.type] 不是构造函数 在 Chart.Controller。 (http://localhost:3000/node_modules/chart.js/dist/Chart.bundle.js:8508:24) 在 Object.helpers.each (http://localhost:3000/node_modules/chart.js/dist/Chart.bundle.js:9345:15) 在 Chart.Controller.buildOrUpdateControllers (http://localhost:3000/node_modules/chart.js/dist/Chart.bundle.js:8497:12) 在 Chart.Controller.initialize (http://localhost:3000/node_modules/chart.js/dist/Chart.bundle.js:8356:7) 在新的 Chart.Controller (http://localhost:3000/node_modules/chart.js/dist/Chart.bundle.js:8339:6) 在新图表 (http://localhost:3000/node_modules/chart.js/dist/Chart.bundle.js:10684:21) 在 BaseChartDirective.getChartBuilder (http://localhost:3000/node_modules/ng2-charts/components/charts/charts.js:73:16) 在 BaseChartDirective.refresh (http://localhost:3000/node_modules/ng2-charts/components/charts/charts.js:114:27) 在 BaseChartDirective.ngOnInit (http://localhost:3000/node_modules/ng2-charts/components/charts/charts.js:18:18) 在 Wrapper_BaseChartDirective.detectChangesInInputProps (/ChartsModule/BaseChartDirective/wrapper.ngfactory.js:89:53) 在 _View_HomeComponent0.detectChangesInternal (/AppModule/HomeComponent/component.ngfactory.js:74:32) 在 _View_HomeComponent0.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:9305:18) 在 _View_HomeComponent0.DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:9410:48) 在 _View_HomeComponent_Host0.AppView.detectViewChildrenChanges (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:9331:23) 在 _View_HomeComponent_Host0.detectChangesInternal (/AppModule/HomeComponent/host.ngfactory.js:33:8)"

我不知道从这里去哪里。我在 ng2-charts gihub repo 上发布了问题。我被困住了,非常感谢您的帮助。

【问题讨论】:

  • 你好,你能告诉我 this.pieChartLabels = _.keys(this.hotelCountByCity); 的控制台输出吗? this.pieChartData = _.values(this.hotelCountByCity);你在这里做错了。它不是 ng2chart 要求的格式。如果可能,也添加 plnkr
  • ng2-chart 标签的类型为 string[],数据为 []。在升级 ng2-chart 库和 angular 2 最终版本之前,我使用了相同的代码。更新应用时出现此问题。
  • 好吧,我正在使用带有 angular 2.4.1 和 ng2-charts:1.4.4 的 ng2-chart。您的饼图标签和数据应采用这种形式 pieChartLabels:string[] = ['string1', 'string2', 'string3'];但我如果你使用 _.key 它会产生类似 0:'string1' 但我们只需要 string1 它的索引不是必需的。您可以使用 foreach 并使用数组推送在变量中推送所有这些字符串数据值,然后分配给 pieChartLabels。
  • 并保持默认值 pieChartLabels:string[] = ['loading'];公共饼图数据:数字[] = [100];你能试一次吗?

标签: angular chart.js ng2-charts


【解决方案1】:

我在互联网上做了一些研究并阅读了文档。我找不到我的问题的明确答案。以下过程对我有用:

  1. 我将 chart.js 从 2.4.0 降级到 2.3.0
  2. 我将布尔值添加到我的组件中,以指示是否从 RESTApi 接收到数据。我使用该标志使用 *ngIf 显示画布。

HTML 标记如下所示:

<canvas 
            baseChart 
            class="chart"
            [data]="data.pieChartData"
            [labels]="data.pieChartLabels"
            [chartType]="data.pieChartType"
            (chartHover)="chartHovered($event)"
            (chartClick)="chartClicked($event)"
            *ngIf="isDataAvailable"
            >
    </canvas>

【讨论】:

  • 所以问题是在组件初始化时图表中没有数据??这就是你使用布尔值的原因。 ?
  • 奇怪的是。但是这个问题不存在。
  • 这就是为什么先生我要求您保留默认值 pieChartLabels:string[] = ['loading'];公共饼图数据:数字[] = [100];在组件的开头,这样您就不会遇到此错误。您可以尝试与 2.4.0 相同的设置初始值吗?
  • 静态值数组将随时工作。它是我需要处理的异步 HTTP 调用。
  • 先生这个静态数组是用来创建图表的。当它获得异步 http 响应时,它将用新的动态数据替换静态数组,那么我们将不会收到此错误。所以现在我们有了解决方案。要么使用 *ngIf 并等待数据,要么使用一些加载数据默认值并显示消息等待数据。 :)
猜你喜欢
  • 2021-11-08
  • 2021-03-16
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-25
  • 2019-10-11
相关资源
最近更新 更多