Track and filter last month value in dc.js
<p>I have a similar problem as the one described in <a href="https://stackoverflow.com/questions/32472189/dc-js-get-last-month-value-as-filter">DC.JS get last month value as filter</a>.  </p>

<p>That is, I want to display in bar charts the value of stock for the last month (by company and by product type), while simultaneously I show the evolution through time of the stock in a line chart.</p>

<p>In order to do so I need to keep track of the last month selected by brushing the line chart.  See my jsFiddle here: <a href="https://jsfiddle.net/BernG/wo60z64j/12/" rel="nofollow noreferrer">https://jsfiddle.net/BernG/wo60z64j/12/</a></p>

<pre><code>var data = [{date:"201501",company:"A", product: "Prod1", stock:575}
    ,   {date:"201502",company:"A", product: "Prod1", stock:325}
    ,   {date:"201503",company:"A", product: "Prod1", stock:200}
    ,   {date:"201504",company:"A", product: "Prod1", stock:450}
    ,   {date:"201501",company:"A", product: "Prod2", stock:279}
    ,   {date:"201502",company:"A", product: "Prod2", stock:93}
    ,   {date:"201503",company:"A", product: "Prod2", stock:0}
    ,   {date:"201504",company:"A", product: "Prod2", stock:372}    
    ,   {date:"201501",company:"A", product: "Prod3", stock:510}
    ,   {date:"201502",company:"A", product: "Prod3", stock:340}
    ,   {date:"201503",company:"A", product: "Prod3", stock:680}
    ,   {date:"201504",company:"A", product: "Prod3", stock:170}    
    ,   {date:"201501",company:"B",product: "Prod1", stock:1000}
    ,   {date:"201502",company:"B",product: "Prod1", stock:1100}
    ,   {date:"201503",company:"B",product: "Prod1", stock:900}
    ,   {date:"201504",company:"B",product: "Prod1", stock:1200}
    ,   {date:"201501",company:"B",product: "Prod2", stock:1000}
    ,   {date:"201502",company:"B",product: "Prod2", stock:1200}
    ,   {date:"201503",company:"B",product: "Prod2", stock:900}
    ,   {date:"201504",company:"B",product: "Prod2", stock:1200}        
    ,   {date:"201501",company:"B",product: "Prod3", stock:1000}
    ,   {date:"201502",company:"B",product: "Prod3", stock:1100}
    ,   {date:"201503",company:"B",product: "Prod3", stock:900}
    ,   {date:"201504",company:"B",product: "Prod3", stock:600}];


// Reading and formatting values
var dateFormat = d3.time.format('%Y%m');
data.forEach(function (d) {
    d.dd = dateFormat.parse(d.date);
    d.year = d3.time.year(d.dd);
    d.month = d3.time.month(d.dd);
});

// Definition of crossfilter and dimensions
var     ndx = crossfilter(data)
    ,   dimMonth = ndx.dimension(function(d){return d.month})
    ,   dimProduct = ndx.dimension(function(d){return d.product})
    ,   dimCompany = ndx.dimension(function(d){return d.company;});


var     lastStaticDate = dimMonth.top(1)[0].month;      // identify last date in full time domain
var     firstStaticDate = dimMonth.bottom(1)[0].month;  // identify first date in full time domain


// Definition of a function to keep track of the last date value in the brush attached to the chartMonth. 
// If chartMonth object does not exist or its corresponding brush is empty (has not been brushed), then it returns the lastStaticDate 
// otherwise, it returns the last date in the brush selection
var getLastDate = function(){
                    if (typeof chartMonth === "undefined"){   // test if chartMonth is already in the DOM, if not return lastStaticDate
                        return lastStaticDate;
                        }
                    else { 
                        if (chartMonth.brush().empty()) {    // if chartMonth has been created but brush does not have have a selection
                            return lastStaticDate;
                            }   
                        else {
                            return chartMonth.brush().extent()[1];
                            };
                        }
                    };

var lastDate = d3.time.month.ceil(getLastDate());   // lastDate is snapped to return a date where we have data in the x-domain 


dateBal.innerHTML = lastDate;       


var     grpMonth = dimMonth.group().reduceSum(function(d){return d.stock;});    // the line chart displays all values in the x-axis to show stock evolution

// Definition of custom reduce functions                    
function reduceAdd(p,v) {   
    if (p.month===lastDate){                                
        p.stock += v.stock;
        return p;
        }
    else {return p;}
};

function reduceRemove(p,v) {
    if (p.month!== lastDate){                               
        p.stock -= v.stock;
        return p;}
    else {return p;}
};

function reduceInitial() { 
    return {stock: 0}
};

// Application of reduce functions

var     grpCompany = dimCompany
                    .group()
                    .reduce(reduceAdd, reduceRemove, reduceInitial);

var     grpProduct = dimProduct
                    .group()
                    .reduce(reduceAdd, reduceRemove, reduceInitial);


var chartCompany = dc.barChart('#chartCompany');
var chartProduct = dc.barChart("#chartProduct");
var chartMonth = dc.lineChart('#chartMonth');

chartCompany
    .width(400)
    .height(400)
    .margins({top: 50, right: 50, bottom: 50, left: 50})
    .dimension(dimCompany)
    .group(grpCompany)
    .x(d3.scale.ordinal())
    .xUnits(dc.units.ordinal)
    .elasticY(true);

chartProduct
    .width(400)
    .height(400)
    .margins({top: 50, right: 50, bottom: 50, left: 50})
    .dimension(dimProduct)
    .group(grpProduct)
    .x(d3.scale.ordinal())
    .xUnits(dc.units.ordinal)
    .elasticY(true);


chartMonth
    .width(400)
    .height(400)
    .margins({top: 50, right: 50, bottom: 50, left: 50})
    .renderlet(function (chart) {
        // rotate x-axis labels
        chart.selectAll('g.x text')
        .attr('transform', 'translate(-10,10) rotate(315)');
        })
    .dimension(dimMonth)
    .group(grpMonth)
    .x(d3.time.scale().domain([firstStaticDate, lastStaticDate]))
    .xUnits(d3.time.months)
    .elasticX(true);

dc.renderAll(); 
</code></pre>

<p>The solution I tried is based on the only answer to the above question (which, by the way,  was not marked as accepted) and follows this logic:</p>

<p>1)  First, I try to identify the last date in the crossfiltered data set. Upon initialization it would be the last date of my time dimension before the brush is moved in the line chart. Otherwise, it returns the date from the second element in the brush extent. To this date I apply the ceiling function to make sure that the date it returns exists as exact date in my time dimension.</p>

<p>2)  I apply custom reduce functions excluding data from months different than the current selection.</p>

<p>My specific questions are:</p>

<ul>
<li><p>How can I make the variable (lastDate) reactive? The following works well in the console:  d3.time.month.ceil(getLastDate()).    However, it does not react to an interactive brushing event.</p></li>
<li><p>What changes need to be done in my custom reduce functions to accumulate only the values that correspond to the lastDate and excludes all others? For some reason the customer reduce functions as they are currently defined do not accumulate stock values correctly. For instance, upon initialization, if I inspect the object where grpCompany resides, it shows the value of the stock as 0.
<a href="https://i.stack.imgur.com/VP5K6.png" rel="nofollow noreferrer">grpCompany.all() in console</a></p>

<p>Finally, before you vote to mark this question as duplicate please consider the following:</p></li>
<li>Original post does not seem to have an accepted answer. </li>
<li>There was an offer to help if OP provided a working jsFiddle, but none was provided.  </li>
<li>I wanted to make a follow up comment in the original post asking for clarification but it was not possible to do so, because I do not have yet the required reputation to post a comment.</li>
</ul>