Динамическое создание иконок для кластеров
Требуется генерить "на лету" кастомные иконки для кластеров, в которых предполагается отрисовывать данные для кластеризуемых меток (несколько диаграмм; что-то похожее делает layout.PieChart).
Что-то похожее сейчас делаю для меток, засовывая в iconImageHref при создании маркера тело svg в виде data:image/svg+xml;charset=UTF-8,<svg ... />.
Для кластеров пока использую templateLayoutFactory (в поле clusterIconContentLayout кластеризатора) для вывода текста внутрь иконки и подсовываю иконку для значка clusterIcons: [{ href: clusterIconSrc, size: [60, 60], width: [-30, -30] }] (в свойствах для Clusterer).
Решением проблемы была бы возможность, напр., передавать функцию, которая создавала бы url с кастомным svg или полностью весь объект clusterIcons.
Пока способа делать что-то подобное не вижу.
Пробовал добраться до внутренних модулей api, но пока ничего нащупал. Напр., как-то так (по-моему, переопределение вообще не работает; с ym давно не сталкивался, наверное, что-то не так делаю):
modules.define('theme.islands.cluster.layout.Icon', ['theme.islands.cluster.layout.Icon'], override(provide, baseIcon) => {
const overrided = Object.assign({}, baseIcon, {
getShape: function getShape(geometry) { /*...*/ },
})
provide(overrided)
})
Используется:
- ymaps api v2.1.79
- react-yandex-maps v4.6.0
Ответы (1 шт):
Возможное решение: переопределяем метод Clusterer.prototype.createCluster, в котором задаём параметр свойств кластеризатора clusterIcons с динамически создаваемым (в зависимости от кол-ва кластеризуемых объектов и их свойств) свойством href для иконки значка кластера:
// Save original `createCluster` method...
const origCreateCluster = Clusterer.prototype.createCluster
// Override `createCluster` method...
Clusterer.prototype.createCluster = function overrideCreateCluster(center, geoObjects) {
// Fetch clustered objects data...
const objData = geoObjects.map(geoObj => ({ id: geoObj.options.get('id') }))
// Generate `clusterIcons` object with custom icon src...
const iconSrc = getClusterIconSrcByObjData(objData)
const clusterIconsEntry = { ...defaultClusterIconsEntry, href: iconSrc }
this.options.set('clusterIcons', [clusterIconsEntry])
// Get cluster placemark content...
return origCreateCluster.call(this, center, geoObjects)
}
Этот метод работает, за исключением того, что вместо url с data:image/svg+xml;charset=UTF-8,<svg надо использовать url в кодировке base64L data:image/svg+xml;base64,... (с помощью btoa, напр.).
.