向下钻取 (Highcharts) 不适用于 Angular 中的动态数据

问题描述

我在我的 angular 项目中使用了 high chart API,我的问题是当我获得动态数据时我成功地生成了 highchart 但是当我点击任何状态时我的钻取功能没有被击中或不工作。在我的场景中需要将 highchart 与下钻一起使用,因此经过大约 5 个小时的搜索和开发,我还没有从 google 或 highcharts 自己的论坛中得到任何解决方案。

这是我的代码

generateMap() {
this.Highcharts = Highcharts;

const usMapData = require("@highcharts/map-collection/countries/us/us-all.geo.json");
const usMap = Highcharts.geojson(usMapData);

this.chartOptions = {
  chart: {
    height: (8 / 16) * 100 + "%",},events: {
    drilldown: function (e) {
      this.methodMap(e.point.splitName);
      const chart = this as any;
      const mapKey = "countries/us/" + e.point.drilldown + "-all";
      const mapData = require(`@highcharts/map-collection/${mapKey}.geo.json`);
      const provinceData = Highcharts.geojson(mapData);

      chart.addSeriesAsDrilldown(e.point,{
        name: e.point.name,data: provinceData,dataLabels: {
          enabled: true,format: '{point.name}'
        }
      });

      chart.setTitle(null,{ text: e.point.name });
    },drillup() {
      const chart = this as any;
    }
  },title: {
    text: ""
  },colorAxis: {
    min: 0,minColor: "#E6E7E8",maxColor: "#417BCC"
  },mapNavigation: {
    enabled: true,buttonoptions: {
      verticalAlign: "bottom"
    }
  },plotOptions: {
    map: {
      states: {
        hover: {
          color: "#F8BA03"
        }
      }
    },series: {
      point: {
        events: {
          click: function (e) {
          }
        }
      }
    }
  },series: [
    {
      animation: {
        duration: 1000
      },name: "United States",data: null,dataLabels: {
        enabled: true,color: '#FFFFFF',format: `{point.splitName}`,style: {
          textTransform: 'uppercase',}
      },}
  ],drilldown: {}
};

this.CurrentvendorService.getAllvendorStates().pipe(
  tap(result => {
    this.chart.showLoading();
    
    usMap.forEach((el: any,i) => {
      el.splitName = el.properties["hc-key"].split('-')[1].toupperCase();
      el.drilldown = el.properties["hc-key"];
      const getFirstMatchedvendor = result.data.find(vendorObj => vendorObj.State_Code == el.splitName);
      if (getFirstMatchedvendor) {
        el.value = getFirstMatchedvendor.vendor_Count;
      }
    });
    
    this.chartOptions.series = [
      {
        data: usMap
      }
    ];
    
    this.updateFromInput = true;
    this.chart.hideLoading();
  },(error: any) => {
      this.gifLoader = false
      this.errorMessage = error.error.message;
      this.snackBar.open(this.errorMessage,'',{
        duration: 2000,});
      console.log(`error on retriving all vendors state list : ${error}`);
    }
  ),finalize(() => {})).subscribe();
}

组件.html

<highcharts-chart
          [Highcharts]="Highcharts"
          [constructorType]="chartConstructor"
          [callbackFunction]="chartCallback"
          [options]="chartOptions"
          style="width: 100%; height: 400px; display: block;"
          [(update)]="updateFromInput"
        ></highcharts-chart>

generateMap() 调用 ngOnInit()。如果我使用静态数据而不是服务。它的作用就像一种魅力,但这里的情况并非如此。我需要深入研究我的动态数据。请帮我解决这个问题。

解决方法

经过几个小时的努力,找到了我自己的问题答案。 我仍在学习和提高对编程问题细节的关注。

解决方案

让我用勺子喂你,你只需复制粘贴就可以了。

一些全局声明:

Highcharts;
chartConstructor = "mapChart";
chartOptions: Highcharts.Options;
updateFromInput = false;
chart;
chartCallback;

将以下代码片段放入组件构造函数中

this.chartCallback = chart => {
    this.chart = chart;
};

将下面的代码放入ngOnInit()

this.generateMap();

现在是主要部分:

generateMap() {
    const self = this;
    self.Highcharts = Highcharts;

    const usMapData = require("@highcharts/map-collection/countries/us/us-all.geo.json");
    const usMap = Highcharts.geojson(usMapData);

    self.chartOptions = {
        chart: {
            height: (8 / 16) * 100 + "%",events: {
                drilldown: function (e: any) {
                    setTimeout(() => {
                        self.methodMap(e.point.splitName);
                        const mapKey = "countries/us/" + e.point.drilldown + "-all";
                        const mapData = require(`@highcharts/map-collection/${mapKey}.geo.json`);
                        const provinceData = Highcharts.geojson(mapData);
                        self.chart.hideLoading();
                        self.chart.addSeriesAsDrilldown(e.point,{
                            name: e.point.name,data: provinceData,dataLabels: {
                                enabled: true,format: '{point.name}'
                            }
                        } as Highcharts.SeriesOptionsType);

                        self.chart.setTitle(null,{ text: e.point.name });
                    },100);
                },drillup() {
                    self.resetMethod();
                }
            }
        },title: {
            text: ""
        },colorAxis: {
            min: 0,minColor: "#E6E7E8",maxColor: "#417BCC"
        },mapNavigation: {
            enabled: true,buttonOptions: {
                verticalAlign: "bottom"
            }
        },plotOptions: {
            map: {
                states: {
                    hover: {
                        color: "#F8BA03"
                    }
                }
            }
        },series: [
            {
                type: "map",name: "United States",data: null,dataLabels: {
                    enabled: true,color: '#FFFFFF',format: `{point.splitName}`,style: {
                        textTransform: 'uppercase',}
                },}
        ],drilldown: {}
    };

    self.CurrentVendorService.getAllVendorStates().pipe(
        tap(result => {
            self.chart.showLoading();

            usMap.forEach((el: any,i) => {
                el.splitName = el.properties["hc-key"].split('-')[1].toUpperCase();
                el.drilldown = el.properties["hc-key"];
                const getFirstMatchedVendor = result.data.find(vendorObj => vendorObj.State_Code == el.splitName);
                if (getFirstMatchedVendor) {
                    el.value = getFirstMatchedVendor.Vendor_Count;
                }
            });

            self.chartOptions.series = [
                {
                    type: "map",data: usMap
                }
            ];

            self.updateFromInput = true;
            self.chart.hideLoading();
        },(error: any) => {
                self.gifLoader = false
                self.errorMessage = error.error.message;
                self.snackBar.open(self.errorMessage,'',{
                    duration: 2000,});
                console.log(`error on retriving all vendors state list : ${error}`);
            }
        ),finalize(() => { })).subscribe();
}

是的,您将根据需要自定义上述业务逻辑。但这就是我想要的。我对 self.chartOptions 对象进行了一些修改并添加了 setTimeout

干杯!