如何为leaflet.js使用crossfilter的reduceSum函数
在yurukov's dc.leaflet.js example中,他正在使用reduceCount函数来处理tsv文件格式。但我想使用reduceSum来使用数据总和。
以下是我的数据:tsv:
type geo say
wind 38.45330,28.55529 10
wind 38.45330,28.55529 10
solar 39.45330,28.55529 10
这是我的代码:
<script type="text/javascript" src="../js/d3.js"></script>
<script type="text/javascript" src="../js/crossfilter.js"></script>
<script type="text/javascript" src="../js/dc.js"></script>
<script type="text/javascript" src="../js/leaflet.js"></script>
<script type="text/javascript" src="../js/leaflet.markercluster.js"></script>
<script type="text/javascript" src="../js/dc.leaflet.js"></script>
<script type="text/javascript">
/* Markers */
d3.csv("demo1.csv", function(data) {
drawMarkerSelect(data);
});
function drawMarkerSelect(data) {
var xf = crossfilter(data);
var facilities = xf.dimension(function(d) { return d.geo; });
var facilitiesGroup = facilities.group().reduceSum(function(d){return d.say});
dc.leafletMarkerChart("#demo1 .map")
.dimension(facilities)
.group(facilitiesGroup)
.width(1100)
.height(600)
.center([39,36])
.zoom(6)
.cluster(true);
var types = xf.dimension(function(d) { return d.type; });
var typesGroup = types.group().reduceSum(function(d){return d.say});
dc.pieChart("#demo1 .pie")
.dimension(types)
.group(typesGroup)
.width(200)
.height(200)
.renderLabel(true)
.renderTitle(true)
.ordering(function (p) {
return -p.value;
});
dc.renderAll();
}
</script>
但它不起作用。 我们如何使用reduceSum?
由于
答案 0 :(得分:2)
我已经重写了该问题,因为目前尚不清楚。我同意@Kees的意图,其目的可能是在汇总标记图中显示总和,而不是“ reduceSum不起作用”。
@Kees还指出了Leaflet.markercluster issue,其中提供了有关如何在标记簇内显示总和的基本信息。
问题就变成了如何将这些自定义项应用于dc.leaflet.js?
首先,我用另一列rnd
创建了示例数据的版本:
type geo rnd
wind 43.45330,28.55529 1.97191
wind 43.44930,28.54611 3.9155
wind 43.45740,28.54814 3.9922
...
我们可以像这样使用reduceSum
:
var facilitiesGroup = facilities.group().reduceSum(d => +d.rnd);
然后通过覆盖.marker()
,并包装默认回调,为每个标记添加值:
const old_marker_function = marker.marker();
marker.marker(function(d, map) {
const m = old_marker_function(d, map);
m.value = d.value;
return m;
});
我们可以使用.clusterOptions()
指定不同的图标呈现方式:
marker.clusterOptions({
iconCreateFunction: function(cluster) {
var children = cluster.getAllChildMarkers();
var sum = 0;
for (var i = 0; i < children.length; i++) {
sum += children[i].value;
}
sum = sum.toFixed(0);
var c = ' marker-cluster-';
if (sum < 10) {
c += 'small';
} else if (sum < 100) {
c += 'medium';
} else {
c += 'large';
}
return new L.DivIcon({ html: '<div><span>' + sum + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
}
});
以上问题中给出的示例缺少任何样式,因此我从Leaflet.markercluster源复制了implementation of _defaultIconCreateFunction
,并对其进行了修改。
按预期,数字接近原始数字的2.5倍(因为新列是从0到5的随机数)。
marker.icon()
允许您更改各个标记的图标,因此可以使用具有类似样式的DivIcon
来显示数字:
marker.icon(function(d, map) {
return new L.DivIcon({
html: '<div><span>' + d.value.toFixed(0) + '</span></div>',
className: 'marker-cluster-indiv marker-cluster',
iconSize: new L.Point(40, 40) });
});
这引入了一个新的类.marker-cluster-indiv
,以区别于其他类。在new fiddle中,我用
.marker-cluster-indiv {
background-color: #9ecae1;
}
.marker-cluster-indiv div {
background-color: #6baed6;
}
由于单击蓝色圆点会弹出而不是展开,因此交互可能不太清楚。也许应该使用其他图标。
答案 1 :(得分:1)
reduceSum
部分应该可以正常工作,因为这只是一个不同的交叉滤波器功能。
您确定您的数据是否正确读取?您声明它是一个 tsv 文件,并显示看起来像是以制表符分隔的代码,但是您使用d3.csv
来加载它,考虑到它会产生非常糟糕的效果第二个字段中间的逗号。
请在加载数据后尝试console.log(data)
,并验证其是否正确加载。
另外,您没有说明遇到的问题。 &#34;它没有工作&#34;不能帮助我们。