【问题标题】:how to zoom d3.js chart and reload data with greater granularity (in AJAX)如何缩放 d3.js 图表并以更大的粒度重新加载数据(在 AJAX 中)
【发布时间】:2013-08-02 06:21:45
【问题描述】:

当我缩放图表时,我需要用新的数据块(AJAX 查询)替换一些数据。

但我无法与没有旧点和更新行路径

的原始数据合并

Zoom chart on JSFiddle

// Replace or add part of data
function zoom(g) {
   var data2add=[      // get new data by ajax query
      {"date":"2013-05-02T20:00","speed":0.878,"angle":269,"x":-0.725,"y":-0.018},
      ...
   ];
   console.log("data", data, "data2add", data2add);

data2add = data2add.map(function(d, i) {
                  return {
                      date:meanDate.call(data, d, i),
                      Speed:Speed.call(data, d, i),
                      angle:angle.call(data, d, i),
                      xSpeed:xSpeed.call(data, d, i),
                      ySpeed:ySpeed.call(data, d, i)
                  };
              });

 data = data.filter(function(element, index, array){
                    return (element.date<data2add[0].date || element.date > data2add[data2add.length-1].date);
                })
             .sort(function (a, b) {
                  return a.date - b.date;
                })
             .concat(data2add);       console.log("newData", data);


   d3.selectAll("path.line").data(data).enter();

   g.selectAll('circle').data(data).enter().append("circle")
     .attr("class", "dot");
   g.updateCurve()
    .drawAxis ();
}

【问题讨论】:

  • 如果我已经加载了所有数据。有没有一种简单的方法可以在查看器缩放之前只显示数据的缩减样本。更具体地说,任何时候只能智能地显示 X 个数据点。问题是当我绘制所有数据点时,图表变得无响应。

标签: javascript arrays merge d3.js zooming


【解决方案1】:

问题在于您使用了.concat()。它合并数组而不取出任何点。相反,您应该做什么取决于您要对数据做什么。如果你想摆脱所有旧点,你可以用data2add覆盖data

如果您想添加新数据,然后保留一定范围的旧数据,您可以在旧数组上使用.filter().concat()。只需创建一个过滤函数来检查元素是否在您的范围内并且不等于另一个数组中的任何内容。如下所示:

function filterFunction(value, i, thisArray){
    //Check to see if point is in range
    if(value < maxRange && value > minRange){

        //Note that you might have to change this depending on how 'equal' 
        //your elements are. You could also iterate through and check the dates, for
        //example.

        return (newDataArray.indexOf(value) > -1 ? 0 : 1)
    }

    return 0;
}

【讨论】:

  • 可以过滤,jsfiddle.net/albanlopez/Egd2q/23,但是你有想法用新值更新折线图吗?
  • 我建议使用日期作为数据键并使用标准 d3 进入/退出/更新模式来移动内容。我一般会应用尺度来设置 cx、cy 等,然后过渡到新的位置。
【解决方案2】:

用于缩放和更新折线图,包含缩放数据exemple here

  1. 过滤旧数据不包括重复区域
  2. 将过滤后的数据与缩放数据相结合
  3. 排序新的数据数组 dy 日期
  4. 重建点系列
  5. 重绘曲线点和轴,但曲线需要像this.select("path.line").attr("d", line(data));而不是this.select("path.line").attr("d", line);

用于绘制和重绘线和点的属性

 g.updateCurve = function(_){
    // Update the line path.
    this.select("path.line")
    .attr("d", line(_));

    // add each point
    this.selectAll('circle.dot')
    .attr("cx", function(d) {return xScale (d.date); })
    .attr("cy", function(d) {return yScale (d.ySpeed); })
    .attr("r", function(d) {return rScale (d.xSpeed)*2; });

    return this;
};

用于绘制和重绘轴

g.drawAxis = function(){
    // Update the x-axis.
    g.select(".x.axis")
        .attr("transform", "translate(0," + xPos + ")")
        .call(xAxis);
    g.select(".y.axis")
        .attr("transform", "translate(0,0)")
        .call(yAxis);
    return this;
};

用于缩放和替换部分数据

function zoom(g) {
   var data2add=[
      {"date":"2013-05-02T20:00","speed":0.878,"angle":269,"x":-0.725,"y":-0.018},
      ...
  ];

  data2add = data2add.map(function(d, i) {
                  return {
                      date:meanDate.call(data, d, i),
                      Speed:Speed.call(data, d, i),
                      angle:angle.call(data, d, i),
                      xSpeed:xSpeed.call(data, d, i),
                      ySpeed:ySpeed.call(data, d, i)
                  };
              });

  mergedata = data.filter(function(element, index, array){
      return (element.date<data2add[0].date || element.date>data2add[data2add.length-1].date);
  })
  .concat(data2add)
  .sort(function (a, b) {
      return a.date-b.date;
  });
  // .sortBy( function(){ return this.date } ); // http://phrogz.net/JS/Array.prototype.sortBy.js

  var newDots = g.selectAll('circle')
                 // define new [data]
                 .data(mergedata, function(d) { return d.date; });
  newDots.exit().remove(); // exit() content the deprecated points, remove it
  newDots.enter().append("circle")// enter() content the new points, draw it
   .attr("class", "dot");

    g.updateCurve()
     .drawAxis ();
}

【讨论】:

  • 提醒一下example 有问题,因为线路跳来跳去。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 2021-11-18
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多