Javascript 如何在我的数据之间使用流体动画向左移动多个路径

Javascript 如何在我的数据之间使用流体动画向左移动多个路径,javascript,d3.js,Javascript,D3.js,如果你能帮我修改代码,我将不胜感激 我的代码基本上由14个传感器组成。每个传感器都有一些我绘制的数据。在我的实际项目中,我每秒使用一个web服务,答案是一个包含128个元素的.JSON。我在超时的帮助下模拟web服务,在本例中,我正在读取3.JSON文件,每一个文件都在一秒钟后模拟我正在使用3个web服务。这些数据是传感器提供信息的数据 setTimeout(function(){ $.getJSON("data.json", function(data) { appendDa

如果你能帮我修改代码,我将不胜感激

我的代码基本上由14个传感器组成。每个传感器都有一些我绘制的数据。在我的实际项目中,我每秒使用一个web服务,答案是一个包含128个元素的
.JSON
。我在超时的帮助下模拟web服务,在本例中,我正在读取
3.JSON
文件,每一个文件都在一秒钟后模拟我正在使用
3个web服务
。这些数据是传感器提供信息的数据

 setTimeout(function(){
  $.getJSON("data.json", function(data) {  
    appendData(data);
    })
  },1000)

  setTimeout(function(){
    $.getJSON("data1.json", function(data) {  
     appendData(data);
    })
  },2000)
每台机器都被称为my object.JSON的键。总共有14台机器。.JSON具有以下结构:(每个
.JSON包含128个元素

每一行代表一个传感器,每一行我都移动到不同的空间,以便更好地看到它们

我正试着在这张照片里有这样的东西。但在我的例子中,我希望通过为每个请求显示一秒钟来实现类似的效果(我制作gif的程序显示的动画不太流畅)

每次收到.JSON请求时,我都试图在图形上绘制。然后每秒钟我都在绘制128个数据。但我想生成一个更平滑的动画来移动我接收到的所有数据中的线条。 目前,我的动画有些突然,正如您在图像中看到的那样

我怎么做

这是我的代码:

*信号特征
*采样率:每秒128个样本。每个样品的周期:7.8125 mS
*分辨率:14位(0-16383),LSB是0.51uV的变化
*动态范围:0uV至8.355,33uV。
* * * */
var采样周期=7.8125//毫秒
var采样率=每秒128//个样本
//从JSON读取
变量aData=[];
//绘图参数
var timeToShow=3;//秒
var limit=timeToShow*采样率;//缓冲区图
//x轴变量
var持续时间=限制*采样周期;//每个数据的采样周期
setTimeout(函数(){
$.getJSON(“data.json”,函数(数据){
附加数据(数据);
})
},1000)
setTimeout(函数(){
$.getJSON(“data1.json”,函数(数据){
附加数据(数据);
})
},2000)
setTimeout(函数(){
$.getJSON(“data2.json”,函数(数据){
附加数据(数据);
})
},3000)
//帆布尺寸
变量宽度=250,高度=490
//情感通道
变量组={
AF3:{
值:0,
颜色:“#FFB6C1”,
数据:d3.range(limit).map(function(){
返回0
})
},
F7:{
值:0,
颜色:“#3afff”,
数据:d3.range(limit).map(function(){
返回0
})
},
F3:{
值:0,
颜色:“#FF0000”,
数据:d3.range(limit).map(function(){
返回0
})
},
FC5:{
值:0,
颜色:“#212529”,
数据:d3.range(limit).map(function(){
返回0
})
},
T7:{
值:0,
颜色:“#FF8C00”,
数据:d3.range(limit).map(function(){
返回0
})
},
P7:{
值:0,
颜色:“#0000FF”,
数据:d3.range(limit).map(function(){
返回0
})
},
O1:{
值:0,
颜色:“#B22BEC”,
数据:d3.range(limit).map(function(){
返回0
})
},
氧气:{
值:0,
颜色:“#A52A2A”,
数据:d3.range(limit).map(function(){
返回0
})
},
第8页:{
值:0,
颜色:“#7FFF00”,
数据:d3.range(limit).map(function(){
返回0
})
},
T8:{
值:0,
颜色:“#FF6347”,
数据:d3.range(limit).map(function(){
返回0
})
},
FC6:{
值:0,
颜色:“#2E8B57”,
数据:d3.range(limit).map(function(){
返回0
})
},
F4:{
值:0,
颜色:“#3ACAFF”,
数据:d3.range(limit).map(function(){
返回0
})
},
F8:{
值:0,
颜色:'#FFA500',
数据:d3.range(limit).map(function(){
返回0
})
},
AF4:{
值:0,
颜色:“#008000”,
数据:d3.range(limit).map(function(){
返回0
})
}
}
var x=d3.scale.linear()
.domain([0,限制-1])
.范围([0,宽度]);
//函数在Y轴上映射值
var y=d3.scale.linear()//具有域[0,1]和范围[0,1]的线性轴。http://alignedleft.com/tutorials/d3/scales
.domain([0,8355.33])//动态范围始终在[0-8355.33]之间
.range([height/14,0])//映射到一个绘图的高度
//通道名称的容器
变量ID=[]
for(组中的变量名称){
id.push(名称)
}
//函数在画布的高度生成条带,每个通道一条
var band=d3.scale.ordinal()
.domain(ids)
.范围带([0,高度])
//函数生成一行
var line=d3.svg.line()
.interpolate('basis')//使用直线进行插值。。。使用B样条曲线的“基础”
.x(函数(d,i){返回x(i);})
.y(函数(d,i){返回y(d);});
/////////在HTML中创建对象
var svg=d3.select('.graph').append('svg'))
.attr('class','chart\u sensores')
.attr('width',width)
.attr('高度',(高度+50))
//为每个数据通道添加行
var path=svg.append('g')
for(组中的变量名称){
变量组=组[名称];
设g=path.append(“g”)
.attr(“转换”,函数(d,i){
返回“translate(0)”+(band(name))+”;//将组移动到相应通道的频带
});
//添加具有“组”中定义的颜色和样式的行
group.path=g.append('path'))
.data([group.data])
.attr('类',名称+'组')
.style('stroke',group.color)
}
//周期函数,每次绘制一个样本。
函数追加数据(数据){
新手
[{  
 "AF3":3605.1496928113393,
 "AF4":-6000.4375230516,
 "F3":1700.3827875419374,
 "F4":4822.544985821321,
 "F7":4903.330735023786,
 "F8":824.4048714773611,
 "FC5":3259.4071092472655,
 "FC6":4248.067359141752,
 "O1":3714.5106599153364,
 "O2":697.2904723891061,
 "P7":522.7300768483767,
 "P8":4050.79490288753,
 "T7":2939.896657485737,
 "T8":9.551935316881588
}]
  * SIGNAL FEATURES
  * Sampling rate: 128 samples per second. Period of each sample: 7.8125 mS
  * Resolution: 14 bits (0 - 16383), LSB is a change in 0.51uV
  * Dynamic Range: 0uV to 8.355,33uV.
  * * * */

  var SAMPLING_PERIOD = 7.8125 // milliseconds
  var SAMPLING_RATE = 128      // Samples per second

  // Read from JSON
  var aData = [];

  // Plot parameters
  var timeToShow = 3; // seconds
  var limit = timeToShow * SAMPLING_RATE;   // Buffer graph

  // Variable for x-axis
  var duration = limit * SAMPLING_PERIOD;  // Sampling period of each data

  setTimeout(function(){
  $.getJSON("data.json", function(data) {  
    appendData(data);
    })
  },1000)

  setTimeout(function(){
    $.getJSON("data1.json", function(data) {  
     appendData(data);
    })
  },2000)

  setTimeout(function(){
    $.getJSON("data2.json", function(data) {  
     appendData(data);
    })
  },3000)


  // Canvas size
  var width = 250, height = 490
  // Emotiv Channels
  var groups = {
    AF3: {
      value: 0,
      color: '#FFB6C1',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    F7: {
      value: 0,
      color: '#3AFFFF',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    F3: {
      value: 0,
      color: '#FF0000',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    FC5: {
      value: 0,
      color: '#212529',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    T7: {
      value: 0,
      color: '#FF8C00',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    P7: {
      value: 0,
      color: '#0000FF',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    O1: {
      value: 0,
      color: '#B22BEC',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    O2: {
      value: 0,
      color: '#A52A2A',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    P8: {
      value: 0,
      color: '#7FFF00',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    T8: {
      value: 0,
      color: '#FF6347',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    FC6: {
      value: 0,
      color: '#2E8B57',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    F4: {
      value: 0,
      color: '#3ACAFF',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    F8: {
      value: 0,
      color: '#FFA500',
      data: d3.range(limit).map(function() {
        return 0
      })
    },
    AF4: {
      value: 0,
      color: '#008000',
      data: d3.range(limit).map(function() {
        return 0
      })
    }
  }

  var x = d3.scale.linear()
    .domain([0, limit - 1])
    .range([0, width]);   


  // Function to map values on Y-axis
  var y = d3.scale.linear() // Linear axis with domain [0,1] and range [0,1]. http://alignedleft.com/tutorials/d3/scales
    .domain([0, 8355.33])      // Dynamic range will always be between [0-8355.33]
    .range([height / 14, 0]) // Map to height of one plot

  // Container for Channel names
  var ids = []
  for (var name in groups) {
    ids.push(name)
  }

  // Function to generate bands bands in the height of the canvas, one for each channel
  var band = d3.scale.ordinal()
    .domain(ids)
    .rangeBands([0, height])   

  // Function to generate a line
  var line = d3.svg.line()
    .interpolate('basis')     // Interpolation with a line... Use 'basis' for B-Spline
    .x(function(d, i) { return x(i); })
    .y(function(d, i) { return y(d); });

  ///////// CREATE OBJECTS IN HTML
  var svg = d3.select('.graph').append('svg')
    .attr('class', 'chart_sensores')
    .attr('width', width)
    .attr('height', (height + 50))

  // Add lines for each data channel
  var paths = svg.append('g')
  for (var name in groups) {
    var group = groups[name];

    let g = paths.append("g")
          .attr("transform", function(d, i) {
            return "translate(0, " + (band(name)) + ")";  // Move the group to the band of the corresponding channel
          });

    // Add the line with the color and style defined in "groups"
    group.path = g.append('path')
      .data([group.data])
      .attr('class', name + ' group')
      .style('stroke', group.color)
  }

  // Periodic function to plot one sample each time.
  function appendData(data) {
    newBlockSize=data.length;

    // Append block of data
    for (var name in groups) {
      var group = groups[name]    // Take one channel
      for (var i=0; i<newBlockSize; i++){
        group.data.push(data[ i][name])
      }
      group.path.attr('d', line)    // Draw the line with the data array
    }


    /////// MOVEMENT OF THE TIME-SERIES PLOT
    var t = paths.attr('transform',null)
      .transition()
      .ease('linear')
      //.duration()
      t.attr('transform', 'translate(' + x(-newBlockSize) + ')')

    // Remove oldest data block from each group
    for (var name in groups) {
      var group = groups[name]
      for (var i=0; i<newBlockSize; i++){
         group.data.shift()
      }
    }
  }//end append function
      group.data.splice(0, newBlockSize);
      for (var i=0; i<newBlockSize; i++) {
         group.data.shift()
      }
1. Wait for dataset C
    - stop time between B and C
    - transition between A and B
2. Transition A-B finished OR dataset C received (whatever happens earlier)
    - if C not received: Plot nothing, continue waiting
    - if transition A-B is still running: save C
3. Transition A-B AND dataset C received
    - wait for dataset D
    - stop time between C and D
    - calculate average of timespan A-B, B-C, etc. (e.g. the 10 last timespans)
        - transition between B and C with average timespan