2015-03-17 3 views
2

У меня есть следующие данные, и я пытаюсь построить 2 гистограмм:Crossfilter измерения и группы, чтобы отфильтровать данные ниже определенного порога

  • Всего единиц данного типа
  • Агрегаты типа меньше чем версия 2.0

Где ось х в обеих диаграммах является типом устройства.

Таблицы в порядке. Проблема заключается в следующем:

Когда я выбираю планку на 2-й диаграмме, я ожидаю увидеть только единицы с версией < 2.0 в таблице данных и 1-й диаграмме, то есть одну запись в этом случае. Но я получаю все единицы этого конкретного типа (это то, что я ожидаю, если я нажму на панель в первом графике), т. Е. 3 записи.

См http://jsfiddle.net/y1o52tk4/6/

Проблема я думаю, это с тем, как я группа для версии карты:

var versionGroup = type1Dim.group().reduceSum(dc.pluck('version_count')); 

данных:

var data = [{ 
     "version": 1.0, 
     "serial": '1A', 
     "type": "a" 
},{ 
     "version": 2.0, 
     "serial": '2A', 
     "type": "a" 
},{ 
     "version": 2.0, 
     "serial": '2AA', 
     "type": "a" 
},{ 
     "version": 2.0, 
     "serial": '2B', 
     "type": "b" 
},{ 
     "version": 2.5, 
     "serial": '25B', 
     "type": "b" 
},{ 
     "version": 1.0, 
     "serial": '1B', 
     "type": "b" 
}]; 
+0

Я думаю, что более правильным, полным способом сделать это было бы создание измерения, которое имеет составной ключ как версии, так и типа, затем [предварительно фильтровать данные динамически] (https: // github. com/dc-js/dc.js/wiki/FAQ # filter-the-data-before-its-charted), чтобы удалить все с помощью versi on> = 2.0. Это какая-то работа, хотя, может быть, стоит того, если у вас много таких дел. – Gordon

+0

Спасибо за ответ, но я не думаю, что этот подход будет работать. С составным ключом и фильтрующей версией <2.0 будет сформировано что-то вроде следующей пары пар ключей: '{[1.0, a]: 5, [1.1, a]: 4, [1.3, a]: 1, [1.0, b ]: 2, [1.8, b]: 1} '. Затем нам нужно было бы создать еще одну группу из этого с помощью пары ключевых значений типа: total units и которая вернет нас к исходной проблеме. – ghostcoder

+0

Вы можете создавать ключи, как хотите, поэтому вы можете получить '{[1. *, a]: 5, [1. *, b]: 17, [2. *, a]: 3, [2. * , b]: 32} '. Функция генерации ключа измерения является общей, какой вы хотите. – Gordon

ответ

3

Как описано в комментариях выше, но давайте объясним это и проясним пару вещей.

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

Дело в том, что ключи от crossfilter, однако, состоят в том, что он всегда будет принуждать их к значениям. Поэтому, если вам нужен составной ключ, лучше всего просто построить его как строку самостоятельно, потому что если вы передадите его как массив, crossfilter будет принуждать его к строке и дать вам соединение с , - которое можно заставить работать , и я знаю, что диаграмма dc.js-рассеянности делает это, но я не рекомендую ее. Он менее эффективен, чем создание строк самостоятельно (потому что вы будете делать это только один раз, а не в том, чтобы это происходило внутри внутренних фильтров CrossFilter), и потому что у вас намного больше контроля.

Вот длинная дискуссия с Джейсоном Дэвисом, который убедил меня: https://github.com/square/crossfilter/pull/48

Так вот версия составного ключа конкатенации вашей скрипки.

Сначала составной ключ:

var type1Dim = ndx.dimension(function(d){ 
          if(d.version<2.0) 
           return '1.' + d.type; 
          else 
           return '2.' + d.type;}); 

(. Самый надежный сепаратор будет '\x0' но '.' прекрасно работает здесь)

Далее, простой ключ сбруя:

.keyAccessor(function(d) {return d.key;}) 

И мы также даем dc.js также область ординальной шкалы:

.x(d3.scale.ordinal()); 

И это работает, но теперь у тиков есть уродливый составной ключ. Чтобы исправить это:

versionChart.xAxis().tickFormat(function(d) { 
     return d.split('.')[1]; 
    }); 

Моей вилка: http://jsfiddle.net/gordonwoodhull/y09cok1z/4/

EDIT: Я забыл обновить генератор поддельных групп, что бывает не важно здесь, но для общности, он должен разделить ключ, а также:

function removeVersion2(source_group) { 
    return { 
     all:function() { 
      return source_group.all().filter(function(d) { 
       return d.key.split('.')[0] != 2; 
      }); 
     } 
    }; 
} 
+0

Большое спасибо за удивительное объяснение и решение! – ghostcoder

3

Проблема здесь состоит в том, что вы создали собственный подсчет версии менее 2 и построили это на вашей гистограмме. Crossfilter понятия не имеет, что это значит в обратном направлении. Таким образом, при щелчке по второму графику в области «b» crossfilter применяется. Filter («b») к этому измерению, а затем к объекту перекрестного фильтра. Таким образом, ваш результат правильный. Для того, чтобы делать то, что вы хотите сделать, я бы рекомендовал добавить новое измерение

var versionDim = ndx.dimension(function(d) {return d.version}); 

, а затем добавить onfiltered слушателя в свой второй диаграмме Этот слушатель проверяет, если вы пытались фильтровать вторую диаграмму, и если да прикладывает фильтр на новом измерении i, созданном выше.

.on("filtered", function(chart){ 
    if(typeDim.top(ndx.size()).length) < ndx.size()) 
    { 
     versionDim.filter(1); 
    }else{ 
     versionDim.filterAll(); 
    } 
}) 
+0

Это отличное решение и намного проще, чем предлагаемое выше составное ключевое решение. Но что такое 'filter_is_applied' и' filter_is_removed'? – Gordon

+0

Gordon-I очистил прослушиватель событий, изначально я собирался использовать эти переменные для сравнения фильтров, но потом понял, что мы действительно заботились о том, был ли вообще отфильтрован второй график, и поэтому он просто проверял, установлен ли фильтр. –