Javascript 优化一组dc.js线图

Javascript 优化一组dc.js线图,javascript,optimization,d3.js,dc.js,crossfilter,Javascript,Optimization,D3.js,Dc.js,Crossfilter,我有一组图形,为我可视化了一组数据(),基于一个csv,大约有25000行数据,每个都有12个参数。但是,进行任何交互(例如在任何图形上使用画笔选择一个范围)都是缓慢而笨拙的,这与处理数千条记录但保持平滑动画或记录(飞行)数量是我的10倍完全不同 我知道最主要的资源是两个折线图,因为它们在整整8个月内每15分钟就有一个数据点。删除它们中的任何一个都会使图表再次响应,但它们是可视化的主要功能,所以有什么方法可以让它们显示不太细粒度的数据吗 两个直线图的代码具体如下: var lin

我有一组图形,为我可视化了一组数据(),基于一个csv,大约有25000行数据,每个都有12个参数。但是,进行任何交互(例如在任何图形上使用画笔选择一个范围)都是缓慢而笨拙的,这与处理数千条记录但保持平滑动画或记录(飞行)数量是我的10倍完全不同

我知道最主要的资源是两个折线图,因为它们在整整8个月内每15分钟就有一个数据点。删除它们中的任何一个都会使图表再次响应,但它们是可视化的主要功能,所以有什么方法可以让它们显示不太细粒度的数据吗

两个直线图的代码具体如下:

        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累积到22000。然而,现在直线图显示为空白。我使用tempGroup.all()检查了组的数据,现在每个21个数据点都有一个温度值,但所有其他数据点都有NaN。我根本没有成功地减少团队规模;现在仍然是2.2万左右。我想知道这是否是正确的方法

编辑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,它将只是一个固定值,因此我不确定如何解决这个问题…

在处理基于d3的图表的性能问题时,通常的罪魁祸首是DOM元素的数量,而不是数据的大小。请注意,crossfilter演示有很多行数据,但只有几百条

看起来您可能正在尝试绘制所有点,而不是将其聚合。我猜既然你在做一个时间序列,聚集这些点可能是不直观的,但是考虑到你的情节只能显示1100个点(宽度),所以过度工作SVG引擎绘制25000是毫无意义的。 我建议将其降低到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);
(可重用的平均reduce函数)

然后指定要匹配的
xUnits
,并使用
elasticY
自动计算y轴:

chart.xUnits(d3.time.days)
   .elasticY(true)

谢谢你的建议。。。我在d3中搜索了其他使用线图重采样函数的人,但是没有具体的例子,我觉得很奇怪,因为一定有人在某个时候遇到了我的问题。。。我试着自己用一个函数来解决这个问题,我在原始答案中加入了一个编辑,但问题是它并没有去除原始数据,只会使每N个数据点都有一个值,其余的都是NaN。你使用了Gordon建议的reduce函数吗?采样实际上是一种数据技术,而不是一种图表技术,如果这有助于你的谷歌搜索。你的尝试在我看来还行,但我还没试过。就我个人而言,为了不丢失数据,我会坚持使用平均值,因为在JavaScription中,这个数据量应该很好。在您的第二次编辑中,“伪组”方法似乎是合理的。由于您的数据可能是按日期顺序排列的(?),因此索引应该与
点编号
几乎相同,因此向过滤器回调函数添加一个参数应该会为您提供一个可以使用的索引:
.filter(函数(d,i){return(i%Math.ceil(dataPerPixel)==0);}
。还要注意,过滤器回调函数应该返回一个布尔值,而不是一个值。我得到了一个更易于管理的1071个结果,但结果也不符合顺序,这让我很困惑。如果你现在看看直播网站,你就会明白我的意思。该组的对象从最初的几个数据点正确开始,然后向前跳几天,然后向后跳。。。所以这些点很好,只是有些混乱。嗯,是的,你可能想使用
.all()
而不是
.top(Infinity)
,原因很明显。错过了。这就成功了,太棒了:)这背后的确切原因是什么?此外,我想改变分辨率以适应缩放级别,因为现在当我放大时,没有足够的点,而且看起来有点块状。。。有没有办法知道在任何时间/缩放级别,图形中当前显示了多少数据点?
.all()
按键排序,而
.top()
按值排序。您自己正在定义dc.js看到的数据点的数量,但是您可以使用
chart.x().range()
和每单位时间的观察次数来计算有多少数据点需要采样。