Javascript D3波林格带问题

Javascript D3波林格带问题,javascript,d3.js,Javascript,D3.js,我想用D3库生成布林带。我尝试了以下代码,但不幸的是它抛出了以下错误- VM224 d3.v3.js:670错误:属性d:预期数量, “M0,NaNL890,NaN” 这一错误的原因可能是什么 代码- var margin = { top: 20, right: 20, bottom: 30, left: 50 }, width = 960 - margin.left - margin.right, height = 500 - margin.top

我想用D3库生成布林带。我尝试了以下代码,但不幸的是它抛出了以下错误-

VM224 d3.v3.js:670错误:属性d:预期数量, “M0,NaNL890,NaN”

这一错误的原因可能是什么

代码-

var margin = {
    top: 20,
    right: 20,
    bottom: 30,
    left: 50
  },
  width = 960 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

var n = 20; // n-period of moving average
var k = 2; // k times n-period standard deviation above/below moving average

var parseDate = d3.time.format("%m/%d/%Y").parse;

var x = d3.time.scale()
  .range([0, width]);
var y = d3.scale.linear()
  .range([height, 0]);
var xAxis = d3.svg.axis()
  .scale(x)
  .orient("bottom");
var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left")
  .tickSize(3, 0);
var line = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.close);
  });
var ma = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.ma);
  });
var lowBand = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.low);
  });
var highBand = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.high);
  });
var bandsArea = d3.svg.area()
  .x(function(d) {
    return x(d.date);
  })
  .y0(function(d) {
    return y(d.low);
  })
  .y1(function(d) {
    return y(d.high);
  });

var svg = d3.select("body").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var data = [
  [
    "9/9/2012",
    1000
  ],
  [
    "9/14/2013",
    100
  ]
];

data.forEach(function(d) {
  d.date = parseDate(d[0]);
  d.close = parseInt(d[1]);

  var bandsData = getBollingerBands(n, k, data);

  x.domain(d3.extent(data, function(d) {
    return d.date;
  }));
  y.domain([d3.min(bandsData, function(d) {
      return d.low;
    }),
    d3.max(bandsData, function(d) {
      return d.high;
    })
  ]);

  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

  svg.append("path")
    .datum(bandsData)
    .attr("class", "area bands")
    .attr("d", bandsArea);
  svg.append("path")
    .datum(bandsData)
    .attr("class", "line bands")
    .attr("d", lowBand);
  svg.append("path")
    .datum(bandsData)
    .attr("class", "line bands")
    .attr("d", highBand);
  svg.append("path")
    .datum(bandsData)
    .attr("class", "line ma bands")
    .attr("d", ma);

  svg.append("path")
    .datum(data)
    .attr("class", "line")
    .attr("d", line);
});

function getBollingerBands(n, k, data) {
  var bands = []; //{ ma: 0, low: 0, high: 0 }
  for (var i = n - 1, len = data.length; i < len; i++) {
    var slice = data.slice(i + 1 - n, i);
    var mean = d3.mean(slice, function(d) {
      return d.close;
    });
    var stdDev = Math.sqrt(d3.mean(slice.map(function(d) {
      return Math.pow(d.close - mean, 2);
    })));
    bands.push({
      date: data[i].date,
      ma: mean,
      low: mean - (k * stdDev),
      high: mean + (k * stdDev)
    });
  }
  return bands;
}
var保证金={
前20名,
右:20,,
底数:30,
左:50
},
宽度=960-margin.left-margin.right,
高度=500-margin.top-margin.bottom;
变量n=20;//移动平均线的n周期
变量k=2;//k乘以移动平均线以上/以下的n期标准偏差
var parseDate=d3.time.format(“%m/%d/%Y”).parse;
var x=d3.time.scale()
.范围([0,宽度]);
变量y=d3.scale.linear()
.范围([高度,0]);
var xAxis=d3.svg.axis()
.比例(x)
.东方(“底部”);
var yAxis=d3.svg.axis()
.比例(y)
.东方(“左”)
.尺寸(3,0);
var line=d3.svg.line()
.x(功能(d){
返回x(d.日期);
})
.y(功能(d){
返回y(d.close);
});
var ma=d3.svg.line()
.x(功能(d){
返回x(d.日期);
})
.y(功能(d){
返回y(d.ma);
});
var lowBand=d3.svg.line()
.x(功能(d){
返回x(d.日期);
})
.y(功能(d){
返回y(d.low);
});
var highBand=d3.svg.line()
.x(功能(d){
返回x(d.日期);
})
.y(功能(d){
返回y(d高);
});
var bandsArea=d3.svg.area()
.x(功能(d){
返回x(d.日期);
})
.y0(功能(d){
返回y(d.low);
})
.y1(功能(d){
返回y(d高);
});
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
风险值数据=[
[
"9/9/2012",
1000
],
[
"9/14/2013",
100
]
];
data.forEach(函数(d){
d、 日期=解析日期(d[0]);
d、 close=parseInt(d[1]);
var bandsData=getBollingerBands(n,k,数据);
x、 域(d3)。范围(数据,函数(d){
返回日期;
}));
y、 域([d3.min(带数据,函数(d)){
返回d.low;
}),
d3.最大值(频带数据,函数(d){
返回d.high;
})
]);
svg.append(“g”)
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0)”、“高度+”)
.呼叫(xAxis);
svg.append(“g”)
.attr(“类”、“y轴”)
.呼叫(yAxis);
追加(“路径”)
.基准面(带数据)
.attr(“类”、“区域带”)
.attr(“d”,bandsArea);
追加(“路径”)
.基准面(带数据)
.attr(“类”、“线带”)
.attr(“d”,低频段);
追加(“路径”)
.基准面(带数据)
.attr(“类”、“线带”)
.attr(“d”,高频段);
追加(“路径”)
.基准面(带数据)
.attr(“类”、“行ma带”)
.attr(“d”,ma);
追加(“路径”)
.基准(数据)
.attr(“类”、“行”)
.attr(“d”,行);
});
函数getBollingerBand(n,k,data){
var带=[];/{ma:0,低:0,高:0}
对于(var i=n-1,len=data.length;i

请参见

第一个问题是,这是布林格带,它需要的数据点超过了您提供的2个。当将
n=20
传递到
getBollingerBands()
时,意味着需要从20个连续数据点中提取平均值。因为只有2个,所以它产生了一个空白数组,这反过来导致
NaN
值进入

根据需要,我将该数据数组更新为更长的一整段

另一个问题是,与此相反:

data.forEach(function(d) {
  d.date = parseDate(d[0]);
  d.close = parseInt(d[1]);
})
您将函数传递给了
forEach
并一直向下扩展,以包含所有呈现代码(例如
svg.append(“path”)
),这意味着它将尝试为每个数据点呈现整个内容(即可能数百次)