2015-03-01 1 views
2

Я ищу, как создать rowchart в dc.js для отображения и фильтрации элементов с несколькими тегами. Я подытожил несколько ответов, полученных при переполнении стека, и теперь у вас есть рабочий код.Обновление нескольких тегов rowchart в dc.js

var data = [ 
{id:1, tags: [1,2,3]}, 
{id:2, tags: [3]}, 
{id:3, tags: [1]}, 
{id:4, tags: [2,3]}, 
{id:5, tags: [3]}, 
{id:6, tags: [1,2,3]}, 
{id:7, tags: [1,2]}]; 

    var content=crossfilter(data); 

    var idDimension = content.dimension(function (d) { return d.id; }); 
    var grid = dc.dataTable("#idgrid"); 
    grid 
      .dimension(idDimension) 
      .group(function(d){ return "ITEMS" }) 
      .columns([ 
       function(d){return d.id+" : "; }, 
     function(d){return d.tags;}, 
    ]) 

    function reduceAdd(p, v) { 
     v.tags.forEach (function(val, idx) { 
      p[val] = (p[val] || 0) + 1; //increment counts 
     }); 
     return p; 
    } 

    function reduceRemove(p, v) { 
     v.tags.forEach (function(val, idx) { 
      p[val] = (p[val] || 0) - 1; //decrement counts 
     }); 
     return p; 
    } 

    function reduceInitial() { 
     return {}; 
    } 


    var tags = content.dimension(function (d) { return d.tags }); 
    var groupall = tags.groupAll(); 
    var tagsGroup = groupall.reduce(reduceAdd, reduceRemove, reduceInitial).value(); 
    tagsGroup.all = function() { 
     var newObject = []; 
     for (var key in this) { 
      if (this.hasOwnProperty(key) && key != "") { 
       newObject.push({ 
        key: key, 
        value: this[key] 
       }); 
      } 
     } 
     return newObject; 
    } 

    var tagsChart = dc.rowChart("#idtags") 
    tagsChart 
     .width(400) 
     .height(200) 
     .renderLabel(true) 
     .labelOffsetY(10) 
     .gap(2) 
     .group(tagsGroup) 
     .dimension(tags) 
     .elasticX(true) 
     .transitionDuration(1000) 
     .colors(d3.scale.category10()) 
     .label(function (d) { return d.key }) 
     .filterHandler (function (dimension, filters) { 
      var fm = filters.map(Number) 
      dimension.filter(null); 
      if (fm.length === 0) 
       dimension.filter(null); 
      else 
       dimension.filterFunction(function (d) { 
        for (var i=0; i < fm.length; i++) { 
         if (d.indexOf(fm[i]) <0) return false; 
        } 
        return true; 
       }); 

      return filters; 
     } 
    ) 
    .xAxis().ticks(5); 

Это можно увидеть на http://jsfiddle.net/ewm76uru/24/

Тем не менее, rowchart не обновляется, когда фильтр по одной метке. Например, на jsfiddle, если вы выберете тег '1', он будет фильтровать элементы 1,3,6 и 7. Хорошо. Но rowchart не обновляется ... Мне нужно, чтобы метка «3» подсчитала, например, до 2.

Есть ли способ, чтобы количество ярлыков строк было обновлено каждый раз, когда я фильтрую по тэгам?

Спасибо.

ответ

2

После долгой борьбы, я думаю, что, наконец, я собрал рабочее решение.

Как сказал на crossfilter документации: «группировка пересекает текущие фильтры в crossfilter, за фильтр ассоциированной размерности, за исключением»

Таким образом, размер метки не фильтруются, когда выбор тега изменяется, и нет флага или для принудительного сброса. Тем не менее, есть временное решение (приведено здесь: https://github.com/square/crossfilter/issues/146).

Идея заключается в том, чтобы дублировать измерение «тегов», и использовать его в качестве отфильтрованного измерения:

var tags = content.dimension(function (d) { return d.tags }); 
// duplicate the dimension 
var tags2 = content.dimension(function (d) { return d.tags }); 
var groupall = tags.groupAll(); 
... 
tagsChart 
    .group(tagsGroup) 
    .dimension(tags2) // and use this duplicated dimension 

, как это можно было увидеть здесь: http://jsfiddle.net/ewm76uru/30/

Я надеюсь, что это поможет.

 Смежные вопросы

  • Нет связанных вопросов^_^