Dc.js传单标记弹出窗口显示输入数据中的字段

时间:2017-01-24 12:56:11

标签: javascript leaflet dashboard dc.js dc.leaflet.js

我是一名dc.js新手,他在一个显示图表和地图信息的仪表板上工作。

除了默认设置之外,我目前无法在标记弹出窗口中显示信息,这似乎是点的坐标(地理位置)和出现次数。目前的代码是:

var facilities = xf.dimension(function(d) { return d.geo; });
var facilitiesGroup = facilities.group().reduceCount();

dc.leafletMarkerChart("#test .map",groupname)
  .dimension(facilities)
  .group(facilitiesGroup)
  .width(540)
  .height(440)
  .center([0,0])
  .zoom(7)
  .cluster(true)
  .filterByArea(true)
  .renderPopup(true)
  .popup();

我尝试按如下方式更改弹出窗口:

  .popup(function(d,feature) { return feature.name +" : "+feature.items; });

包括位置名称和项目数量。但是,弹出窗口现在只提及" undefined:undefined"。

我确信这是一个简单的解决方案,由于我的经验有限,我只是无视。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

dc.js和crossfilter的核心是一种map和reduce,其中为每个值找到了bin,然后聚合了每个bin中的行。

但听起来您正试图直接在传单地图中显示您的数据而不进行任何聚合。如果您确实要汇总,则必须决定如何汇总items(您还没有显示您的数据,因此我不知道它是什么),并且可能需要请不要使用name,因为名字通常不会汇总。

所以我建议告诉crossfilter按名称(假设它是唯一的)而不是位置,然后保持位置和项目,以及保持计数。不幸的是,这在某种程度上是交叉过滤的核心目的,所以代码有点尴尬:

var facilities = xf.dimension(function(d) { return d.name; });
var facilitiesGroup = facilities.group().reduce(
    function(p, v) { // add
        p.items = v.items;
        p.geo = v.geo;
        ++p.count;
        return p;
    },
    function(p, v) { // remove
        --p.count;
        return p;
    },
    function() { // init
        return {count: 0};
    }
);

我们只是假设名称是唯一的,并从我们看到的第一条记录中抓取字段。现在,crossfilter组将返回一组键值对,其中name将是key,而{count, items, geo}将是值,因此我们可以告诉dc-leaflet如何阅读这些:

dc.leafletMarkerChart("#test .map",groupname)
    // ...
    .valueAccessor(function(kv) {
        return kv.value.count;
    })
    .locationAccessor(function(kv) {
        return kv.value.geo;
    })
    .popup(function(kv) {
        return kv.key + " : " + kv.value.items;
    })

kv是一个我喜欢用来提醒自己的惯例,数据d几乎总是一个键值对。 (在某些直流图表中,它将是一个包含data成员的对象,该成员是键值对。)

请注意,这与dc-leaflet默认行为不同,要按位置聚合,并将位置设置为键。如果您的位置保证是唯一的,您也可以这样做,但这对我来说似乎有风险(数据可能会丢失)。如果你的意思是在没有聚合的情况下显示原始数据,我认为使用真正独特的密钥会更好。

答案 1 :(得分:1)

leafletMarkerChart在我的情况下不起作用。它没有显示任何错误或弹出窗口。在标准dc-leaflet.js函数上使用相同的方法,您可以执行以下操作:

var restaurantsGroup = restaurantNames.group().reduce(
                    function(p, v) { // add
                    p.name = v.name;
                    p.price_range = v.price_range;
                    p.stars = v.stars;
                    p.latitude = v.latitude;
                    p.longitude = v.longitude;
            ++p.count;
            return p;
                },
                function(p, v) { // remove
                --p.count;
                return p;
                },
                function() { // init
                return {count: 0};
                }
            );


var marker = dc_leaflet.markerChart("#demo1 .map", groupname) //map formatting
      .dimension(restaurantNames)
      .group(restaurantsGroup)
      .width(700)
      .height(500)
      .center([43.733372, -79.354782])
      .zoom(11)
      .cluster(true) 
    .valueAccessor(function(kv) {
          return kv.value.count;
    })
    .locationAccessor(function(kv) {
          return [kv.value.latitude,kv.value.longitude] ;
     })
    .popup(function(kv,marker) {
          return kv.value.name + " - " + kv.value.stars + " * - "  + 
           kv.value.price_range + "$";
      });