Как создать функтор для группировки данных

Функтор — это метод, который вызывается для каждого элемента данных и определяет то, как этот элемент будет представлен в хедере группы.

[
    { id:1, title:"The Shawshank Redemption", year:1994, votes:678790},
    { id:2, title:"The Godfather", year:1972, votes:511495},
    { id:3, title:"The Godfather: Part II", year:1994, votes:319352},
    { id:4, title:"The Good, the Bad and the Ugly", year:1972, votes:213030}
]

Например, когда данные сгруппированы по годам, вам может потребоваться узнать общее количество голосов за год или же их мин./макс. значения, и т.д. Для этого и существуют функторы группировки. Они описываются внутри объекта map в функции группировки.

$group:{
    by:"year",
    map:{
        votes:['votes', 'sum']  
    }   // 'sum' — функтор для подсчёта голосов за каждый год 
}

Related sample:  Data Aggregation

Для базовых операций в библиотеке предусмотрены встроенные функторы группировок. Они доступны в классе GroupMethods

Вы также можете создать кастомные функторы.

Как добавить новый функтор

Любая функция может стать функтором группировки, если вы укажите ей уникальное имя, опишете логику и добавите функцию в класс GroupMethods.

Такая функция принимает два параметра:

  • prop - свойство для обработки
  • data - объект с элементами группы.

Давайте создадим функтор для нахождения среднего значения свойств элементов. Назовём функтор median:

webix.GroupMethods.median = function(prop, data){
    if (!data.length) return 0;
        var summ = 0;
    for (var i = data.length - 1; i >= 0; i--) {
        summ += prop(data[i])*1;
    };
    return summ/data.length;
};

А теперь применим новый функтор, обратившись к нему по названию:

$group:{
    by:"year",
    map:{
        votes:["votes", "median"]       }   
}

Related sample:  Custom Aggregation while Grouping

Вы также можете определить функтор, определив кастомную функцию и указав её название в объекте map. Такой способ позволяет обойти определение новых методов в классе GroupMethods.

function getAverage(prop, data){
    // то же, что и для метода "median" выше 
} 
 
$$("mychart").group({
    by:"year",
    map:{
        sales:["sales", getAverage]
    }
});

Related sample:  Grouping

Вы можете не указывать функтор, но указать способ представления критерии группировки:

webix.ui({
    view:"treetable",
    columns:[ // темплейт по умолчанию для несгруппированных элементов
        { id:"title", template:"{common.icon()} #title#" }, 
    ],
    scheme:{
        $group:{
            by:function(obj){ return Math.floor(obj.year/10); }, 
            map:{
                title:[function(obj){ 
                    var min = obj.year - obj.year%10; 
                    return min + " - "+ (min+10) 
                }]
            }
        }
    }       
});

Related sample:  Static Grouping

Наверх