首页 > 解决方案 > 如何添加交叉过滤函数filterRange。服务器端的 Dc.js

问题描述

我将计算移到服务器端,因为数据很大。

我想绘制 dc.seriesChart,但是在指定日期范围之后

.x(d3.scaleTime().domain([minDate, maxDate]))

页面加载时出现错误:

Uncaught TypeError: t.filterRange is not a function.

请帮助在 script.js、app.js 和 script.js 代码中实现 filterRange。

我正在使用lastlegion/dc.js-server-side-crossfilter中的 crossfilter express 模式。

应用程序.js

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, () => console.log('Listening at Port 3000'));
app.use(express.static('public'));

var dimensions                      = {};
var groups                          = {};

app.get("/data", function(req, res, next) {
    
    var results                     = {};
    filter                          = req.param("filter") ? JSON.parse(req.param("filter")) : {}

    console.log(filter);

    for (dimension in dimensions) {
        console.log("Dimension: " + dimension);
        if (filter[dimension]) {
            if ((filter[dimension]).length > 1) {
                console.log(filter);
                dimensions[dimension].filterFunction(function (d) {
                    var filters = (filter[dimension]);
                    for (var i = 1; i < filters.length; i++) {
                        var filter = filters[i];
                        if (filter.isFiltered && filter.isFiltered(d)) {
                            return true;
                        } else if (filter <= d && filter >= 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("Group: " + 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( "dfsk");
    
    if ((dir).length === 1) {
        return dir[0];
    } else if ((dir).length === 0) {
        return null
    }
}

anyToJSON.csv({ path: "input/dataset.csv"}, function(records) {

    var dateFormat = d3.timeFormat("%Y-%m-%d %H:%M:%S");
    var dateFormatParser = d3.timeParse("%Y-%m-%d %H:%M:%S");

    records.forEach(function(d) {
        d.timestamp = dateFormat(dateFormatParser(d.timestamp));
    });

    var ndx = crossfilter(records);
    var all = ndx.groupAll();

    console.log("...");

    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;

公共/js/script.js

var priorityTimeChart       = new dc.seriesChart("#priority-timeline");

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("/data?filter="+JSON.stringify(queryFilter), function(d){
        filteredData = d;
        dc.redrawAll();
    });
};

var dateDim = {
    filter:function(f){
        if(f){
            queryFilter["dateDim"]=f;
            refresh(queryFilter);
        }
    },
    filterAll:function(){
    },
    filterRange:function(){
    }
};
var numRecordsByDate = {
    all:function(){
        return filteredData["numRecordsByDate"].values;
    },
    order: function(){
    },
    top:function(){
    }
};

var datePriorityDim = {
    filter:function(f){
        if(f){
            queryFilter["datePriorityDim"]=f;
            refresh(queryFilter);
        }
    },
    filterAll:function(){
    }
};
var datePriorityGroup = {
    all:function(){
        return filteredData["datePriorityGroup"].values;
    },
    order: function(){
    },
    top:function(){
    }
};


var minDate = "Fri Mar 13 2020 11:49:35 GMT+0300";
var maxDate = "Tue Mar 17 2020 14:50:03 GMT+0300";

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("Events")
    .xAxisLabel("Date")
    .elasticY(true)
    .dimension(dateDim)
    .group(datePriorityGroup)
    .mouseZoomable(true)
    .colors(d3.scaleOrdinal().domain(['High','Middle','Low']).range(["red", "green", "yellow"]))
    .seriesAccessor(function(d) {return "priority: " + 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("/data?filter={}", function(d){
            filteredData = d;
            dc.renderAll();
        });
    };
    init();

标签: dc.jscrossfilter

解决方案


推荐阅读