title: How add crossfilter function filterRange. Dc.js on server side
body: <p>I moved calculations to the server side, because data is large.</p>
  <p>I want to draw dc.seriesChart, but after specifying date range</p>
  <pre><code>.x(d3.scaleTime().domain([minDate, maxDate]))
  </code></pre>
  <p>an error appears on page load:</p>
  <pre><code>Uncaught TypeError: t.filterRange is not a function.
  </code></pre>
  <p>Please help implement filterRange in script.js, app.js and script.js code is attached.</p>
  <p>I'm using the crossfilter express pattern from <a href="https://github.com/lastlegion/dc.js-server-side-crossfilter" rel="nofollow noreferrer">lastlegion/dc.js-server-side-crossfilter</a>.</p>
  <p>app.js</p>
  <pre><code>var express                         = require('express');
  var path                            = require('path');
  var anyToJSON                       = require('anytojson');
  var crossfilter                     = require('crossfilter');
  var d3                              = require('d3');
  
  var app                             = express();
  app.listen(3000, () =&gt; console.log('Listening at Port 3000'));
  app.use(express.static('public'));
  
  var dimensions                      = {};
  var groups                          = {};
  
  app.get(&quot;/data&quot;, function(req, res, next) {
      
      var results                     = {};
      filter                          = req.param(&quot;filter&quot;) ? JSON.parse(req.param(&quot;filter&quot;)) : {}
  
      console.log(filter);
  
      for (dimension in dimensions) {
          console.log(&quot;Dimension: &quot; + dimension);
          if (filter[dimension]) {
              if ((filter[dimension]).length &gt; 1) {
                  console.log(filter);
                  dimensions[dimension].filterFunction(function (d) {
                      var filters = (filter[dimension]);
                      for (var i = 1; i &lt; filters.length; i++) {
                          var filter = filters[i];
                          if (filter.isFiltered &amp;&amp; filter.isFiltered(d)) {
                              return true;
                          } else if (filter &lt;= d &amp;&amp; filter &gt;= d) {
                              return true;
                          }
                      }
                      return false;
                  });
              }
              else {
                  console.log(filter[dimension]);
                  dimensions[dimension].filter(filter_value(filter[dimension]));
              }
          } else {
              dimensions[dimension].filterAll()
          }
      }
  
      for (dimension in groups) {
      
          console.log(&quot;Group: &quot; + dimension);
      
          var group                   = groups[dimension];
          results[dimension] = {
              values: group.all(),
              top: group.top(1)[0].value
          };
      }
      
      res.writeHead(200, {
          'content-type': 'application/json'
      });
      res.end((JSON.stringify(results)));
  
  });
  
  function filter_value(dir) {
      
      console.log( &quot;dfsk&quot;);
      
      if ((dir).length === 1) {
          return dir[0];
      } else if ((dir).length === 0) {
          return null
      }
  }
  
  anyToJSON.csv({ path: &quot;input/dataset.csv&quot;}, function(records) {
  
      var dateFormat = d3.timeFormat(&quot;%Y-%m-%d %H:%M:%S&quot;);
      var dateFormatParser = d3.timeParse(&quot;%Y-%m-%d %H:%M:%S&quot;);
  
      records.forEach(function(d) {
          d.timestamp = dateFormat(dateFormatParser(d.timestamp));
      });
  
      var ndx = crossfilter(records);
      var all = ndx.groupAll();
  
      console.log(&quot;...&quot;);
  
      var dateDim                     = ndx.dimension(function (d) { return d.timestamp; });
      var datePriorityDim             = ndx.dimension(function (d) { return [d.priority, d.timestamp];});
      var numRecordsByDate            = dateDim.group();
      var datePriorityGroup           = datePriorityDim.group().reduceCount();
      dimensions.dateDim              = dateDim;
      dimensions.datePriorityDim      = datePriorityDim;  
      groups.numRecordsByDate         = numRecordsByDate;
      groups.datePriorityGroup        = datePriorityGroup;
  
  });
  
  module.exports                      = app;
  </code></pre>
  <p>public/js/script.js</p>
  <pre><code>var priorityTimeChart       = new dc.seriesChart(&quot;#priority-timeline&quot;);
  
  var filteredData = {};
  var queryFilter = {};
  
  window.filter = function(filters) {
      filters.forEach(function(d, i) { charts[i].filter(d); });
      renderAll();
  };
  window.reset = function(i) {
      charts[i].filter(null);
      renderAll();
  };
  
  var refresh = function(queryFilter){
      d3.json(&quot;/data?filter=&quot;+JSON.stringify(queryFilter), function(d){
          filteredData = d;
          dc.redrawAll();
      });
  };
  
  var dateDim = {
      filter:function(f){
          if(f){
              queryFilter[&quot;dateDim&quot;]=f;
              refresh(queryFilter);
          }
      },
      filterAll:function(){
      },
      filterRange:function(){
      }
  };
  var numRecordsByDate = {
      all:function(){
          return filteredData[&quot;numRecordsByDate&quot;].values;
      },
      order: function(){
      },
      top:function(){
      }
  };
  
  var datePriorityDim = {
      filter:function(f){
          if(f){
              queryFilter[&quot;datePriorityDim&quot;]=f;
              refresh(queryFilter);
          }
      },
      filterAll:function(){
      }
  };
  var datePriorityGroup = {
      all:function(){
          return filteredData[&quot;datePriorityGroup&quot;].values;
      },
      order: function(){
      },
      top:function(){
      }
  };
  
  
  var minDate = &quot;Fri Mar 13 2020 11:49:35 GMT+0300&quot;;
  var maxDate = &quot;Tue Mar 17 2020 14:50:03 GMT+0300&quot;;
  
  priorityTimeChart
      .height(h_row2)
      .chart(function(c) { return new dc.lineChart(c).curve(d3.curveCardinal).evadeDomainFilter(true); })
      .x(d3.scaleTime().domain([minDate, maxDate]))
      .brushOn(true)
      .yAxisLabel(&quot;Events&quot;)
      .xAxisLabel(&quot;Date&quot;)
      .elasticY(true)
      .dimension(dateDim)
      .group(datePriorityGroup)
      .mouseZoomable(true)
      .colors(d3.scaleOrdinal().domain(['High','Middle','Low']).range([&quot;red&quot;, &quot;green&quot;, &quot;yellow&quot;]))
      .seriesAccessor(function(d) {return &quot;priority: &quot; + d.key[0];})
      .keyAccessor(function(d) {return +d.key[1];})
      .valueAccessor(function(d) {return +d.value;})
      
  
  .legend(dc.legend().x(350).y(350).itemHeight(13).gap(5).horizontal(1).legendWidth(140).itemWidth(70))
          .yAxis().ticks(3);
      priorityTimeChart.yAxis().tickFormat(function(d) {return d3.format(',d')(d);});
      priorityTimeChart.margins().left += 10;
      priorityTimeChart.filterHandler(function(dimension, filters){
          if(filters)
              dimension.filter(filters);
          else
              dimension.filter(null);
          return filters;
      });
  
      function init(){
          d3.json(&quot;/data?filter={}&quot;, function(d){
              filteredData = d;
              dc.renderAll();
          });
      };
      init();
  </code></pre>