如何从AmChart更新clickMapObject侦听器中的全局数据 [英] How to update global data in clickMapObject listener from AmChart

查看:65
本文介绍了如何从AmChart更新clickMapObject侦听器中的全局数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习AmChart js lib,但我有一些疑问.

I'm learning about AmChart js lib and I have some doubts.

我有一张地图,显示了数据库中注册的所有设备(请看下面的打印图)

I have one map that show all devices registered in my database (look the print below)

因此,我想实现一种功能,当用户单击地图中某个国家/地区的气泡时,表格列表按国家/地区过滤,因此,在设备中,表格应仅显示来自以下国家/地区的设备:用户点击的气泡.

So, I would like to implement one functionality for when the user clicks on the bubble from one country in the map, the table list is filtered by country, so, in the device, table should show only devices from the country of the bubble that user clicked.

为了在用户单击气泡时执行此筛选,我使用来自Amchart(clickjMapObject)的addListener作为下面的示例.

for to do this filter when a user clicks in the bubble, I'm using the addListener from Amchart (clickjMapObject) as the example below.

 this.map.addListener('clickMapObject', function (event) {
    console.log(event);
    console.log(this.deviceList).
 });

console.log(event)它正在工作,但是当我尝试打印"deviceList"时,它不工作.我收到以下错误:

the console.log(event) it's working, but When I try to print "deviceList" not working. I get the following error:

错误TypeError:无法读取未定义的属性'devicesList'

ERROR TypeError: Cannot read property 'devicesList' of undefined

我不知道是否可以在侦听器中访问全局数组,所以,我不知道这是什么问题.你能帮我吗?

I don't know if it's possible to access global array in the listener, So, I don't know what's the problem. Could you please help me?

按照下面的完整代码进行操作. (在这段代码中,您可以看到如何填充"deviceList")

follow my complete code below. (in this code you can see how to I populate the "deviceList")

export class DevicesLocationComponent implements OnInit {

  public devicesList: Device[];
  public images = [];
  public country_location = [];
  public map: any;

  @ViewChild(DatatableComponent) table: DatatableComponent;

  constructor(private http: HttpClient, private deviceService: DeviceService) 
  {
    this.getCountryLocationJSON().subscribe(data => {
      this.country_location = data;
    });
  }


  /**
   * Build initial the chart and load devices location
   *
   * @memberof DevicesLocationComponent
   */
   public ngOnInit() {
     this.loadDeviceDataTable();
   }


   /**
    * This function is responsible to load datatable with devices data
    */
    private loadDeviceDataTable() {

      // load last used devices data
      this.deviceService.getAllDevices()
         .subscribe(((listDevices: Device[]) => {
              this.devicesList = listDevices;

             this.buildMapChart();   
      }));
    }

    /**
     * This function is responsible to build the map chart after load devices data on datatable.
     */
     private buildMapChart() {

        // get min and max values for define bubble size frm map chart
        const minBulletSize = 10;
        const maxBulletSize = 40;
        let min = Infinity;
        let max = -Infinity;
        for (const key in this.tardisDevicesGrouped) {
           if (this.tardisDevicesGrouped.hasOwnProperty(key)) {
               const value = this.tardisDevicesGrouped[key].length;
               if ( value < min ) {
                  min = value;
               }
               if ( value > max ) {
                 max = value;
               }
           }
        }

       // it's better to use circle square to show difference between values, not a radius
      const maxSquare = maxBulletSize * maxBulletSize * 2 * Math.PI;
      const minSquare = minBulletSize * minBulletSize * 2 * Math.PI;

      // create circle for each country
      for (const key in this.tardisDevicesGrouped) {
        if (this.tardisDevicesGrouped.hasOwnProperty(key)) {
          const value = this.tardisDevicesGrouped[key].length;
          const country_location = this.getLatLongCountry(key);

          // calculate size of a bubble
         let square = ( value - min ) / ( max - min ) * ( maxSquare - minSquare ) + minSquare;
         if ( square < minSquare ) {
           square = minSquare;
         }
         const size = Math.sqrt( square / ( Math.PI * 2 ) );

         // set each bubble size, value and colors for each country
         this.images.push( {
         'type': 'circle',
         'theme': 'light',
         'width': size,
         'height': size,
         'longitude': country_location.longitude,
         'latitude': country_location.latitude,
         'color': country_location.color,
         'title': country_location.country_name,
         'selectable': true,
         'value': value
       });
     }
   }

   this.map = AmCharts.makeChart('allocation-map', {
     'type': 'map',
     'hideCredits': true,
     'theme': 'light',
     'colorSteps': 10,
     'dataProvider': {
       'map': 'worldLow',
       'images': this.images,
       'zoomLevel': 1.0,
       'zoomLongitude': 10,
       'zoomLatitude': 52
     },
     'areasSettings': {
        'autoZoom': true,
        'selectable': true
     }
   });

   console.log(this.devicesList);  // It's working 

   this.map.addListener('clickMapObject', function (event) {
     console.log(event);
     console.log(this.devicesList);   // It's not working
    });
  }
}

推荐答案

在事件侦听器上方,您应声明一个用于存储当前作用域的变量

Above the event listener you should declare a variable storing the current scope

var self = this

然后在事件发生时触发的函数内部,应将此引用更改为self

Then inside the function triggered at the event you should change the this reference to self

console.log(self.devicesList);

最后,您的代码应如下所示:

At the end your code should look like this:

 console.log(this.devicesList);  // It's working 
 var self = this;
   this.map.addListener('clickMapObject', function (event) {
     console.log(event);
     console.log(self.devicesList);   // Now it will work
    });
  }

之所以会发生这种情况,是因为范围会根据您所在的位置而变化,因此,"this"在事件侦听器内部的含义与在组件内部的含义不同,引用会发生变化

This happens because the scope is changing depending on where you are, so "this" doesn't mean the same inside an event listener than inside a component, the reference changes

这篇关于如何从AmChart更新clickMapObject侦听器中的全局数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆