В моем AngularJs
веб-приложении я создаю карту, используя Leaflet.js и маркерный кластер Leaflet.
Для отображения диаграмм я использую nvd3.js и nvd3-angular-directive
У меня есть разные данные, поступающие со всего мира, и я показываю простую CircleMarker
для каждой страны, которая получила данные.
Мои данные организованы следующим образом:
{
US : {country:"US", count:10, rate: {high: 3, medium: 4, low: 3}},
IT : {country:"IT", count:4, rate: {high: 1, medium: 1, low: 2}}
}
Это означает, что на карте CircleMarker
будет отображаться в центре США и Италии.
Теперь давайте перейдем к проблеме, я привязываю всплывающее окно к каждому CircleMarker
, я хочу, чтобы каждое всплывающее окно содержало круговую диаграмму nvd3
(в частности, пончик), которая будет показывать распределение rate
для этой конкретной нации.
Проблема в том, что в настоящее время карта отображается правильно, а маркеры размещены идеально, но когда я нажимаю на маркер, всплывающее окно пусто (см. рисунок). Я гуглил, но не смог найти ничего, что могло бы мне помочь.
Вот как я создаю
CircleMarkers
и кластер:
var markers = L.markerClusterGroup({
maxClusterRadius: 120,
iconCreateFunction: function (cluster) {
return L.divIcon({html: '<b>' + cluster.getChildCount() + '</b>', className: 'mycluster', iconSize: L.point(40, 40)});
}
})
var geolocData = {
US : {country:"US", count:10, rate: {high: 3, medium: 4, low: 3}},
IT : {country:"IT", count:4, rate: {high: 1, medium: 1, low: 2}}
}
for (key in geolocData){
var latlng = retrieveLatLongFromCountryCode(key)
var marker = new L.circleMarker(latlng, {stroke: false, className:'the-marker-class', fillOpacity: 1, color:'#00FF00', weight: 1})
var popupChartOptions = {
chart: {
type: 'pieChart',
height: 140,
donut: true,
donutRatio: 0.40,
x: function(d) { return d.label },
y: function(d) { return d.value },
color: [
'#2ecc71',
'#f1c40f',
'#e74c3c',
],
valueFormat: d3.format(',.0d')
}
}
var popupChartData = [{
label: 'low',
value: geolocData[key].rate.low
}, {
label: 'medium',
value: geolocData[key].rate.medium
}, {
label: 'high',
value: geolocData[key].rate.high
}]
marker.bindPopup('<nvd3 options="chartOptions" data="chartData"></nvd3>')
markers.addLayers(marker)
}
map.addLayer(markers)
ОБНОВЛЕНИЕ
Я немного изменил ситуацию. Во-первых, я расширил класс CircleMarker
var customCircleMarker = L.CircleMarker.extend({
options: {
countrycode: '',
rates: {},
count: 0
}
})
Затем я использую этот CustomCircleMarker
на своей карте.
var marker = new customCircleMarker(latlng, {stroke: false, className: 'the-class-name', fillOpacity: 1, weight: 1})
var popupChartData = [{
label: 'low',
value: [geolocLoad[key].rate.low]
}, {
label: 'medium',
value: [geolocLoad[key].rate.medium]
}, {
label: 'high',
value: [geolocLoad[key].rate.high]
}]
Затем я привязываю всплывающее окно, заполняю маркер своими пользовательскими данными и создаю обратный вызов on click
, который выдает сообщение с моими полезными данными.
marker.bindPopup('<div id="chart-' + key + '"></div>')
marker.countrycode = key
marker.rates = popupChartData
marker.count = geolocLoad[key].count
marker.on('click', function(e){
$scope.$emit('marker:click', this.countrycode, this.count, this.rates)
})
Получатель возьмет данные и отобразит диаграмму следующим образом:
$scope.$on('marker:click', function(caller, countrycode, count, rates){
console.log('received', countrycode, count, rates)
var width = 500,
height = 500
nv.addGraph(function(){
var chart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.width(width)
.height(height);
d3.select("#chart-"+countrycode)
.datum(rates)
.attr('width', width)
.attr('height', height)
.call(chart);
return chart;
})
})
К сожалению, это снова не работает..
ПРИМЕЧАНИЕ. Я не использую директиву angular-leaflet-directive, так как считаю ее излишней и мне она не очень нравится. Как вы думаете, лучше ли мне использовать его в любом случае?