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

Dc.js leaflet marker popup showing fields from input data

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

我目前无法在标记弹出窗口上显示信息 window 除了默认值,这似乎是一个点的坐标 (geo) 和出现的次数。当前代码是:

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".

我敢肯定,由于我的经验有限,我只是忽略了一个简单的解决方案。有人可以帮忙吗?

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

但听起来您正试图在没有任何聚合的情况下直接在传单地图中显示您的数据。如果你确实想聚合,你必须决定如何聚合 items (你没有显示你的数据所以我不知道它是什么),并且可能不得不离开 name 因为名称通常不会聚合。

所以我建议告诉 crossfilter 按名称(假设它是唯一的)而不是位置进行分类,然后保留位置和项目,并保持计数。不幸的是,这与 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 组将 return 一个 key-value 对的数组,其中名称将是 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 几乎总是一对 key-value 的约定。 (在某些 dc 图表中,它将是一个包含 data 成员的对象,该成员是 key-value 对。)

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

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 + "$";
      });