[Javascript] Есть ли способ сказать crossfilter рассматривать элементы массива как отдельные записи, а не рассматривать весь массив как один ключ?


Answers

Приведенный выше пример - отличный подход. Вы можете сделать это еще на один шаг. В вышеприведенном решении он будет фильтроваться только в соответствии с первым выбранным вами выбором. Любые последующие выборы игнорируются.

Если вы хотите, чтобы он отвечал на все выборы, вы должны создать filterHandler следующим образом:

 barChart.filterHandler (function (dimension, filters) {
   dimension.filter(null);   
    if (filters.length === 0)
        dimension.filter(null);
    else
        dimension.filterFunction(function (d) {
            for (var i=0; i < d.length; i++) {
                if (filters.indexOf(d[i]) >= 0) return true;
            }
            return false; 
        });
  return filters; 
  }
);

Рабочий образец здесь: http://jsfiddle.net/jeffsteinmetz/cwShL/

Question

У меня есть набор данных, где некоторые из значений полей являются массивами, и я хотел бы использовать crossfilter и d3.js или dc.js для отображения гистограммы того, сколько раз каждое из этих значений присутствовало в наборе данных.

Вот пример:

var data = [
    {"key":"KEY-1","tags":["tag1", "tag2"]},
    {"key":"KEY-2","tags":["tag2"]},
    {"key":"KEY-3","tags":["tag3", "tag1"]}];

var cf = crossfilter(data);

var tags = cf.dimension(function(d){ return d.tags;});
var tagsGroup = tags.group();


dc.rowChart("#chart")
    .renderLabel(true)
    .dimension(tags)
    .group(tagsGroup)
    .xAxis().ticks(3);

dc.renderAll();

И JSFiddle http://jsfiddle.net/uhXf5/2/

Когда я запускаю этот код, он создает граф следующим образом:

Но я хочу что-то вроде этого:

Чтобы сделать вещи еще более сложными, было бы замечательно иметь возможность щелкнуть по любой из строк и фильтровать набор данных с помощью тега, который был нажат.

У кого-нибудь есть идеи, как это достичь?

Спасибо, Костя




Ответ Джеффа работает, но нет необходимости отслеживать «найденную» переменную или продолжать цикл, если элемент был найден. Если X находится в [X, Y, Z], это уже сократило количество итераций в 1/3.

else
    dimension.filterFunction(function (d) {
        for (var i=0; i < d.length; i++) {
            if (filters.indexOf(d[i]) >= 0) return true;
        }
        return false; 
    });

Кроме того, вы можете исправить метод dc.js filterFunction, который будет обрабатывать все случаи.