2014-02-11 4 views
2

Я пытаюсь создать текущую сумму в crossfilter для использования с dc.js. У меня есть набор записей, вроде следующего:Создайте текущую сумму в crossfilter

records = [{"date":"2014-01-01","field1":"value1","field2":"value11","value_field":-20}, 
      {"date":"2014-01-02","field1":"value2","field2":"value12","value_field":100}, 
      {"date":"2014-01-03","field1":"value1","field2":"value11","value_field":-10}, 
      {"date":"2014-01-04","field1":"value2","field2":"value12","value_field":150}, 
      ] 

До сих пор я создал BARGRAPH, который играет хорошо с другими размерами, но я хотел бы быть в состоянии показать линейный график теоретического поля runnning_total (по дате измерения).

Чтобы сделать это в crossfilter, я мог бы затем группировать поля fieldx и легко получить одинаковый общий график, но ограничиваться подгруппой значений с использованием dc.js.

Любая помощь приветствуется.

ответ

4

Поскольку вы группировки по дате (по вашему date dimension), функция reduce() будет использоваться для выполнения агрегирование , сгруппированных по дате, в соответствии с выделенными ячейками в моем примере Микки Маус ниже:

Aggregating across fruits

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

enter image description here

Вы можете агрегировать данные, а затем добавить текущее общее поле следующим образом. Я также включил пример того, как вычислить среднее значение, используя reduce функцию:

records = [{ "date": "2014-01-01", "field1": "value1", "field2": "value11", "value_field": -20 }, 
    { "date": "2014-01-02", "field1": "value2", "field2": "value12", "value_field": 100 }, 
    { "date": "2014-01-03", "field1": "value1", "field2": "value11", "value_field": -10 }, 
    { "date": "2014-01-04", "field1": "value2", "field2": "value12", "value_field": 150 } 
]; 


var cf = crossfilter(records);         

var dimensionDate = cf.dimension(function (d) { 
     return d.date; 
    }); 


function reduceAdd(p, v) { 
    p.total += v.value_field; 
    p.count++; 
    p.average = p.total/p.count; 
    return p; 
} 
function reduceRemove(p, v) { 
    p.total -= v.value_field; 
    p.count--; 
    p.average = p.count ? p.total/p.count : 0; 
    return p; 
} 
function reduceInitial() { 
    return { 
     total: 0, 
     count: 0, 
     average: 0, 
    }; 
} 



var average = dimensionDate.group().reduce(reduceAdd, reduceRemove, reduceInitial).all(); 

var averageWithRunningTotal = appendRuningTotal(average); 

function appendRuningTotal(average) { 
    var len = average.length, 
     runningTotal = 0; 
    for (var i = 0; i < len; i++) { 
     runningTotal += average[i].value.total; 
     average[i].RunningTotal = runningTotal; 
    } 

    return average; 
} 

И это возвращает:

{"key":"2014-01-01","value":{"total":-20,"count":1,"average":-20},"RunningTotal":-20} 
{"key":"2014-01-02","value":{"total":100,"count":1,"average":100},"RunningTotal":80} 
{"key":"2014-01-03","value":{"total":-10,"count":1,"average":-10},"RunningTotal":70} 
{"key":"2014-01-04","value":{"total":150,"count":1,"average":150},"RunningTotal":220} 
+0

Так мне удалось показать начальную нарастающий итог строку с помощью '.valueAccessor'. Но то, чего я до сих пор не хватает, - это возможность автоматического обновления текущей суммы при выборе одной из групп в других бархатах, например. Я бы хотел показать только текущее количество для выбранного значения одного из полей. Вернемся к моему примеру: какова будет общая сумма только для записей 'field1 = value1'? – Chapo

+0

Удалил мой предыдущий комментарий, где я сказал спасибо :) – Chapo

+0

Вы можете просто изменить значение p.total в функциях уменьшения, чтобы посмотреть на поле1. Итак, из этого: 'p.total + = v.value_field;' Для этого: 'p.total + = v.value1;' Если вы хотите получить итоговые значения всех своих полей, то просто создайте для них новые переменные в 'reduceInital 'и назначать им функции' reduceAdd' и 'reduceRemove'. :) – ninjaPixel

2

Ну я знаю, что оп уже построил решение, но после битвы некоторое время я смог взломать его, поэтому отправляю его здесь, если кто-то ищет его.

используя кумулятивный для следующего: https://groups.google.com/forum/#!topic/dc-js-user-group/W9AvkP_dZ0U

Запуск Сумма:

var _group = dim.group().reduceSum(function(d) {return 1;}); 

var group = { 
all:function() { 
var cumulate = 0; 
var g = []; 
_group.all().forEach(function(d,i) { 
    cumulate += d.value; 
    g.push({key:d.key,value:cumulate}) 
}); 
return g; 
} 

};

для расчета месяца Продольных Двенадцать:

var _group = dateDim.group().reduceSum(function(d) {return d.revenue;}); 
var group = { 
all:function() { 
var g = []; 
_group.all().forEach(function(d,i) { 
    var cumulate = 0; 
    var monthcount =0; 
    var dt =new Date(d.key); 
    var ct = new Date(d.key); 
    ct.setFullYear(ct.getUTCFullYear() -1); 
    _group.all().forEach(function(d2,i) { 
     var dt2 = new Date(d2.key); 
     if(dt2 <= dt && dt2 > ct){ 
      cumulate += d2.value; 
      monthcount++; 
     } 
    }) 
    if(monthcount>=11){ 
     console.log(' Dt ' + dt + ' ' + cumulate + ' months ' + monthcount); 
     g.push({key:d.key,value:cumulate}) 
     } 
    }); 
       return g; 
      } 
     }; 
Смежные вопросы