1

我是 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; });

包括位置的名称和那里的项目数量。但是,弹出窗口现在只提到“未定义:未定义”。

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

4

2 回答 2

3

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 组将返回一个键值对数组,其中 name 将是 thekey并且 the{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几乎总是键值对的约定。(在某些 dc 图表中,它将是一个对象,其中包含一个data成员,该成员是键值对。)

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

于 2017-01-25T12:08:11.897 回答
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 + "$";
      });
于 2017-04-14T02:28:53.077 回答