如何在 AmChart 的 clickMapObject 侦听器中更新全局数据
How to update global data in clickMapObject listener from AmChart
我正在学习 AmChart js
库,我有一些疑问。
我有一张地图显示了我数据库中注册的所有设备(查看下面的印刷品)
所以,我想实现一项功能,当用户点击地图中某个国家/地区的气泡时,table 列表按国家/地区过滤,因此,在设备中,table 应该只显示来自用户点击的气泡所在国家/地区的设备。
为了在用户单击气泡时执行此过滤器,我使用 Amchart (clickjMapObject
) 的 addListener 作为以下示例。
this.map.addListener('clickMapObject', function (event) {
console.log(event);
console.log(this.deviceList).
});
console.log(event) 它正在工作,但是当我尝试打印时 "deviceList"
不工作。我收到以下错误:
ERROR TypeError: Cannot read property 'devicesList' of undefined
我不知道是否可以在侦听器中访问全局数组,所以,我不知道是什么问题。你能帮帮我吗?
按照我下面的完整代码进行操作。 (在此代码中,您可以看到我如何填充 "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
});
}
}
在事件侦听器之上,您应该声明一个存储当前作用域的变量
var self = this
然后在事件触发的函数内部,您应该将 this 引用更改为 self
console.log(self.devicesList);
最后您的代码应如下所示:
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" 事件侦听器内部与组件内部的含义不同,引用发生变化
我正在学习 AmChart js
库,我有一些疑问。
我有一张地图显示了我数据库中注册的所有设备(查看下面的印刷品)
所以,我想实现一项功能,当用户点击地图中某个国家/地区的气泡时,table 列表按国家/地区过滤,因此,在设备中,table 应该只显示来自用户点击的气泡所在国家/地区的设备。
为了在用户单击气泡时执行此过滤器,我使用 Amchart (clickjMapObject
) 的 addListener 作为以下示例。
this.map.addListener('clickMapObject', function (event) {
console.log(event);
console.log(this.deviceList).
});
console.log(event) 它正在工作,但是当我尝试打印时 "deviceList"
不工作。我收到以下错误:
ERROR TypeError: Cannot read property 'devicesList' of undefined
我不知道是否可以在侦听器中访问全局数组,所以,我不知道是什么问题。你能帮帮我吗?
按照我下面的完整代码进行操作。 (在此代码中,您可以看到我如何填充 "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
});
}
}
在事件侦听器之上,您应该声明一个存储当前作用域的变量
var self = this
然后在事件触发的函数内部,您应该将 this 引用更改为 self
console.log(self.devicesList);
最后您的代码应如下所示:
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" 事件侦听器内部与组件内部的含义不同,引用发生变化