2015-02-14 1 views
2

С, например, данныеdc.js Graphing Метки

var data = [ 
    {Name: 'Mr A', Spent: 40, Year: 2011, tags: ['a', 'b', 'c']}, 
    {Name: 'Mr B', Spent: 10, Year: 2011, tags: ['c']}, 
    {Name: 'Mr C', Spent: 40, Year: 2011, tags: ['a']}, 
    {Name: 'Mr A', Spent: 70, Year: 2012, tags: ['c', 'b']}, 
    {Name: 'Mr B', Spent: 20, Year: 2012, tags: ['b']}, 
    {Name: 'Mr B', Spent: 50, Year: 2013, tags: ['a', 'b', 'c']}, 
    {Name: 'Mr C', Spent: 30, Year: 2013, tags: ['a', 'b']} 
]; 

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

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

function reduceRemove(p, v) { 
    v.tags.forEach (function(val, idx) { 
    p[val] -= v.Spent; 
    }); 
    return p; 
} 

function reduceInitial() { 
    return {}; 
} 
var tagsDim = ndx.dimension(function(d) {return d.tags; }); 
tagsGroup = tagsDim.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial); 
console.log(tagsGroup.value()) 
'{ a: 160, b: 210, c: 170 }' 

Это дает уменьшенные суммы правильно. Но, поскольку это объект groupAll, dc.js не может его отобразить, поэтому я не совсем уверен, куда идти отсюда. Возможно ли даже dc.js получить доступ к тегам в массиве. Было бы лучше рассчитать суммы по-другому?

+0

Вы будете в конечном итоге с не непересекающихся групп таким образом, - так как строка может принадлежать как много групп, есть теги, строки будут посчитаны несколько раз , Также любая другая диаграмма, которая выполняет обычные суммы по строкам, получит другую сумму. Это то, что вы хотите? – Gordon

+0

Довольно уверенный кроссфильтр не поддерживает это, поэтому вам придется реализовать его самостоятельно. Достаточно легко адаптировать группы, которые вы получаете как [поддельную группу] (https://github.com/dc-js/dc.js/wiki/FAQ#filter-the-data-before-its-charted); сложная часть будет писать функцию [фильтр] (https://github.com/square/crossfilter/wiki/API-Reference#dimension_filterFunction). – Gordon

+0

Спасибо @ Gordon, я попробую это. –

ответ

1

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

Вы можете попробовать здесь: http://jsfiddle.net/ewm76uru/30/

var data = [ 
{id:1, author:'foo', tags: ['tag1','tag2','tag3']}, 
{id:2, author:'foo', tags: ['tag3']}, 
{id:3, author:'foo', tags: ['tag1']}, 
{id:4, author:'bar', tags: ['tag2','tag3']}, 
{id:5, author:'bar', tags: ['tag3']}, 
{id:6, author:'bar', tags: ['tag2','tag3']}, 
{id:7, author:'bar', tags: ['tag1','tag2']} 
]; 

    var content=crossfilter(data); 

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

    // author chart 
    var authorDimension = content.dimension(function (d) { return d.author; }); 
    var authorgroup = authorDimension.group().reduceSum(function(d) { return 1; }) 
    authorChart = dc.rowChart('#idauthor'); 
    authorChart 
     .width(300) 
     .renderLabel(true) 
     .gap(2) 
     .margins({top: 10, left: 10, right: 20, bottom: 40}) 
     .group(authorgroup) 
     .dimension(authorDimension) 
     .elasticX(true) 
     .transitionDuration(1000) 
     .colors(d3.scale.category10()) 
     .label(function (d) { return d.key }) 
     .xAxis().ticks(5); 

    // tags chart 
    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 tags2 = 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[key] && key != "all") { 
       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(tags2) 
     .elasticX(true) 
     .transitionDuration(1000) 
     .colors(d3.scale.category10()) 
     .label(function (d) { return d.key }) 
     .on("filtered", function(c,f) { 
      //tags2.filter(f) 
     }) 
     .filterHandler (function (dimension, filters) { 
      dimension.filter(null); 
      dimension.filterFunction(function (d) { 
       for (var i=0; i < filters.length; i++) { 
        if (d.indexOf(filters[i]) <0) return false; 
       } 
       return true; 
      }); 



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

    dc.renderAll(); 
+0

Я отредактировал свой ответ, чтобы объяснить, как фильтровать по нескольким тегам, с обновленным фильтром тегов –