【问题标题】:Inserting NVD3 chart in Leaflet popup在 Leaflet 弹出窗口中插入 NVD3 图表
【发布时间】:2016-05-26 13:19:01
【问题描述】:

在我的AngularJs Web 应用程序中,我正在使用Leaflet.jsLeaflet markercluster 构建地图。

为了渲染图表,我使用了nvd3.jsnvd3-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 饼图(特别是一个甜甜圈)图表,该图表将显示rates 的分布那个特定的民族。

问题是当前地图已正确渲染并且标记放置完美,但是当我单击标记时,出现的弹出窗口为空(见图)。我用谷歌搜索,但找不到任何可以帮助我的东西。


这就是我构建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,因为我发现它有点矫枉过正并且不太喜欢它。你觉得我还是用它比较好?

【问题讨论】:

    标签: javascript angularjs popup leaflet angular-nvd3


    【解决方案1】:

    我自己解决了这个问题,我发布了一个答案,因为它可能对未来的用户有帮助。

    我忘记的最重要的事情是在弹出窗口中插入一个&lt;svg&gt; 元素,这导致图表无法呈现,因为没有“画布”我们是库可以呈现它..

    标记生成:

    var marker = new customCircleMarker(countries.names[c].latlng, {stroke: false, className: 'the-class-name', fillOpacity: 1, weight: 1})
    
    marker.bindPopup('<div id="chart-' + key + '" class="country-popup-chart-container"><svg class="country-popup-chart"></svg></div>', {closeButton: false})
    marker.countrycode = key
    marker.rates = geolocLoad[key].rate
    marker.count = geolocLoad[key].count
    
    marker.on('click', function(e){
      $scope.$emit('marker:click', this.countrycode, this.count, this.rates)
    })
    

    click 上调用$emit 触发图表生成:

    $scope.$on('marker:click', function(caller, countrycode, count, rates) {
    
      var popupChartData = [{
        label: 'low',
        value: rates.low,
        color: '#2ecc71'
      }, {
        label: 'medium',
        value: rates.medium,
        color: '#f1c40f'
      }, {
        label: 'high',
        value: rates.high,
        color: '#e74c3c'
      }]
    
      nv.addGraph(function(){
        var chart = nv.models.pieChart()
          .x(function(d) { return d.label })
          .y(function(d) { return d.value })
          .showLabels(false)
          .donut(true)
          .donutRatio(0.5)
    
        d3.select('#chart-' + countrycode + ' svg')
          .datum(popupChartData)
          .call(chart)
    
        return chart
      })
    }) 
    

    使用以下CSS

    div.country-popup-chart-container{
      height: 80px;
      width: 200px;
    }
    

    最终结果是:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-29
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多