dc.js - 如何添加交叉过滤函数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();
解决方案
推荐阅读
- apache-spark - 过滤嵌套数组列并创建新的嵌套数组列
- spring - 在 SpringMVC Thymeleaf 中获取 null 而不是 ArrayList
- amazon-web-services - 涉及负载均衡器的 IoT 设备 SSL 问题
- excel - 尝试断开工作簿中的外部链接时出现运行时错误 91
- sql-server - 查询 SQL Server 数据库时出现 System.InvalidOperationException
- java - 更新查询不更新数据库?
- machine-learning - 无法理解准确率和召回率之间的区别
- python - 在 python 中使用 if-else 条件语句进行绘图
- python - Python将数据框附加到现有的Excel工作表
- operating-system - 操作系统如何处理分叉炸弹?