我有一组图表可视化我的一堆数据(here),基于csv,大约有25,000行数据,每行有12个参数。但是,进行任何交互(例如在任何图形上使用画笔选择范围)都是缓慢且难以处理的,完全不同于the dc.js demo found here,它同时处理数千条记录但保持平滑的动画,或{{3它的记录(航班)数量是我的10倍。
我知道主要的资源生猪是两个折线图,因为他们每15分钟有一个数据点,大约8个月。删除其中任何一个都会使图表再次响应,但它们是可视化的主要特征,那么有什么方法可以让它们显示不那么精细的数据?
两个折线图的代码具体如下:
var lineZoomGraph = dc.lineChart("#chart-line-zoom")
.width(1100)
.height(60)
.margins({top: 0, right: 50, bottom: 20, left: 40})
.dimension(dateDim)
.group(tempGroup)
.x(d3.time.scale().domain([minDate,maxDate]));
var tempLineGraph = dc.lineChart("#chart-line-tempPer15Min")
.width(1100).height(240)
.dimension(dateDim)
.group(tempGroup)
.mouseZoomable(true)
.rangeChart(lineZoomGraph)
.brushOn(false)
.x(d3.time.scale().domain([minDate,maxDate]));
单独但相关的问题;如何修改折线图上的y轴?默认情况下,它们不包含数据集中找到的最高值和最低值,这看起来很奇怪。
编辑:我写的一些代码试图解决问题:
var graphWidth = 1100;
var dataPerPixel = data.length / graphWidth;
var tempGroup = dateDim.group().reduceSum(function(d) {
if (d.pointNumber % Math.ceil(dataPerPixel) === 0) {
return d.warmth;
}
});
d.pointNumber是每个数据点的唯一点ID,累计从0到22,000 ish。但是现在线图显示为空白。我使用tempGroup.all()检查了组的数据,现在每个21个数据点都有一个温度值,但所有其他数据点都有NaN。我根本没有成功减少团体规模;它仍然在22,000左右。我想知道这是否是正确的做法......
编辑2:发现了一种不同的方法。我正常创建了tempGroup,但后来又创建了一个过滤现有tempGroup的组。
var tempGroup = dateDim.group().reduceSum(function(d) { return d.warmth; });
var filteredTempGroup = {
all: function () {
return tempGroup.top(Infinity).filter( function (d) {
if (d.pointNumber % Math.ceil(dataPerPixel) === 0) return d.value;
} );
}
};
我在这里遇到的问题是d.pointNumber不可访问,所以我无法判断它是否是第N个数据点(或者是其中的一个)。如果我将它分配给一个var,它只是一个固定值,所以我不知道如何解决这个问题...
答案 0 :(得分:4)
在处理基于d3的图表的性能问题时,通常的罪魁祸首是DOM元素的数量,而不是数据的大小。请注意,crossfilter演示有很多行数据,但只有几百个。
看起来您可能正在尝试绘制所有点而不是聚合它们。我想因为你正在做一个时间序列,聚合点可能是不直观的,但考虑到你的情节只能显示1100点(宽度),所以过度工作SVG引擎绘制25,000是毫无意义的。
我建议把它降到100-1000箱之间,例如平均每一天:
var daysDim = data.dimension(function(d) { return d3.time.day(d.time); });
function reduceAddAvg(attr) {
return function(p,v) {
if (_.isLegitNumber(v[attr])) {
++p.count
p.sums += v[attr];
p.averages = (p.count === 0) ? 0 : p.sums/p.count; // gaurd against dividing by zero
}
return p;
};
}
function reduceRemoveAvg(attr) {
return function(p,v) {
if (_.isLegitNumber(v[attr])) {
--p.count
p.sums -= v[attr];
p.averages = (p.count === 0) ? 0 : p.sums/p.count;
}
return p;
};
}
function reduceInitAvg() {
return {count:0, sums:0, averages:0};
}
...
// average a parameter (column) named "param"
var daysGroup = dim.group().reduce(reduceAddAvg('param'), reduceRemoveAvg('param'), reduceInitAvg);
(可重复使用的平均减少函数from the FAQ)
然后指定要匹配的xUnits
,并使用elasticY
自动计算y轴:
chart.xUnits(d3.time.days)
.elasticY(true)