Как использовать DCS ReduceSum в leaflet.js
Как я могу использовать функцию limitSum для crossfilter для leaflet.js
В примере dc.leaflet.js Юрукова он использует функцию reduCount для формата файла tsv. Но я хочу использовать сумму данных с помощью ReduSum.
Вот мои данные как ЦВ:
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>
Но это не работает. Как мы можем использовать ReduSum?
Спасибо
1 ответ
Я переписал вопрос, потому что он был очень непонятным. Я согласен с @Kees, что намерение, вероятно, состояло в том, чтобы отобразить сумму в кластерной диаграмме маркеров, а не "reduceSum не работает".
@Kees также указал на проблему Leaflet.markercluster, которая дает основную информацию о том, как отображать сумму внутри кластера маркеров.
Возникает вопрос, как применить эти настройки к 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) });
}
});
В примере, приведенном выше, отсутствовал какой-либо стиль, поэтому я скопировал реализацию_defaultIconCreateFunction
из источников Leaflet.markercluster и модифицировал его.
Как и ожидалось, числа примерно в 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
отличить его от других; на новой скрипке я покрасил их в синий цвет
.marker-cluster-indiv {
background-color: #9ecae1;
}
.marker-cluster-indiv div {
background-color: #6baed6;
}
Взаимодействие, возможно, менее очевидно, поскольку при нажатии синих точек появляется всплывающее окно, а не его расширение. Возможно, следует использовать другой значок.
reduceSum
часть должна работать нормально, так как это просто другая функция перекрестного фильтра.
Вы уверены, что ваши данные читаются правильно? Вы заявляете, что это файл tsv, и показываете код, который выглядит как разделенный табуляцией, но затем вы используете d3.csv
загрузить его, что будет иметь довольно плохие последствия, учитывая, что в середине второго поля есть запятая.
Пожалуйста, попробуй console.log(data)
после того, как ваши данные загружены, и убедитесь, что они загружаются правильно.
Кроме того, вы не указываете, с какой проблемой вы столкнулись. "Это не работает" не помогает нам помочь вам.