Клуб API Карт

Событие кластеризатора

nolan23
14 октября 2016, 14:20

Добрый день!
Делаю карту с кластеризатором.
Иконка кластера должна менять цвет (типа тепловой карты) в зависимости от одного из свойств входящих в него меток ('total')

То есть после того, как клстеры пересчитались, необходимо посчитать сумму total у входящих в каждый кластер меток, а затем, пробежаться по всем кластерам и найти min и max. После этого сам кластер будет иметь цвет от зеленого до красного.

есть функция recalcClusters которая все это выполняет:

_recalcClusters = function () {
            var clusters = clusterer.getClusters(),
                min = 100000000,
                max = 0,
                clusterProps = [],
                i;

            for (i = 0; i < clusters.length; i++) {
                var total = 0,
                    geoObjects = clusters[i].getGeoObjects();
                for (var j = 0; j < geoObjects.length; j++) {
                    total += parseInt(geoObjects[j].properties.get('total', 0));
                }
                clusterProps[i] = total;
                min = Math.min(min, total);
                max = Math.max(max, total);
            }
            var clusterNums = clusterer.options.get('clusterNumbers'),
                props = {};
            for (i = 0; i < clusters.length; i++) {
                if (clusterProps[i] > clusterNums[1]) {
                    props['className'] = 'big';
                } else if (clusterProps[i] > clusterNums[0]) {
                    props['className'] = 'medium';
                } else {
                    props['className'] = 'small';
                }
                clusterColor = '#'
                    + ("00" + Math.floor(255 * (clusterProps[i] -min ) / (max - min) ).toString(16)).substr(-2)
                    + ("00" + Math.floor(255 * (1 - ((clusterProps[i] - min) / (max - min) ))).toString(16)).substr(-2)
                    + '00';
                props['hintContent'] = clusterProps[i];
                props['total'] =  clusterProps[i];
                props['color'] = clusterColor;
                clusters[i].properties.set(props);
            }
        },

есть макет кластера и ccs для разных размеров:

 clusterIconLayout: ymaps.templateLayoutFactory.createClass(
                '<div class="cluster {{ properties.className }}"><div  style="background-color:{{ properties.color }}">' +
                '{{ properties.total }}</div></div>'
            ),

Прошу помощь клуба:

1. На какое событие повесить такой обработчик

2. Как задать иконкам область клика 

Заранее спасибо

7 комментариев
Подписаться на комментарии к посту
я бы делал это все в макете иконки кластера. Логика будет сильно проще, минус один цикл и не нужно никакие события слушать.
Область можно задать в опциях или  определить метод макета getShape
Можно посмотреть как сделан модуль пайчарт
https://github.com/yandex/ymaps-pie-chart-clusterer/tree/layout
dimik,
Спасибо за ответ.
Но тут немного другая логика. надо показать тепловую карту по ВСЕМ показываемым кластерам. то есть при перестройке кластеров меняется их цвет в зависимости от выбранной области. В макете кластера по идее можно сделать - при формировании первого макета обсчитать min и max а для следующих вызовов уже использовать готовые величины. вот только как узнать что это первый вызов? обнулять значения min и max по boundschange ? уж больно коряво, но должно работать. нет больше идей?
nolan23,
Что значит в зависимости от выбранной области? Судя по коду он меняется в зависимости от данных объектов в кластере 
dimik,
все правильно. но сумма кластера собирается из суммы объектов, затем, считается min и max по уже обсчитанным кластерам и считается цвет. Так как кластеры постоянно пересчитываются в зависимости от зума и области видимости, то и суммы кластеров будут все время разными, ведь сумма собирается из входящих в кластер точек. То есть для видимой области у нас всегда будет хотя бы один зеленый и один красный кластер.
nolan23,
Я бы считал в первом вызове макета и сохранял куда-нибудь в поле кластеризатора (если значение еще не задано)
При "boundschange" можно удалять это поле.