d3.js(v3)输入()无法在条形图更新中使用

时间:2017-02-13 14:57:16

标签: javascript d3.js

我有一个条形图工作正常,除非在updateChart函数中将更长的数据更新传递给它时,尽管现有的条形图正确转换,但不会创建新的条形图。

jsFiddle

    var initialData = [
    {Date: '2017-01-01', Volume: 56},
    {Date: '2017-01-02', Volume: 98},
    {Date: '2017-01-03', Volume: 45},
    {Date: '2017-01-04', Volume: 21},
    {Date: '2017-01-05', Volume: 40}
  ];
  var updatedData = [
    {Date: '2016-12-27', Volume: 89},
    {Date: '2016-12-28', Volume: 81},
    {Date: '2016-12-29', Volume: 75},
    {Date: '2016-12-30', Volume: 160},
    {Date: '2016-12-31', Volume: 65},
    {Date: '2017-01-01', Volume: 56},
    {Date: '2017-01-02', Volume: 98},
    {Date: '2017-01-03', Volume: 120},
    {Date: '2017-01-04', Volume: 21},
    {Date: '2017-01-05', Volume: 40}
];


var bottomPadding = 20;
var leftPadding = 30;
var topPadding = 0;
var rightPadding = 40;
var width = 375 - leftPadding-rightPadding;
var height = width * .75;
var xScale,volScale; 
var xAxis,volAxis,volAxisGroup;

drawChart();

function drawChart() {

  var gData = initialData;

  var minDate = getDate(gData[0]);
  var maxDate = getDate(gData[gData.length - 1]);
  var maxVol = d3.max(gData, function (d) { return +d.Volume });

  xScale = d3.time.scale()
  .range([leftPadding, width + leftPadding]);

  volScale = d3.scale.linear()
  .rangeRound([height, (topPadding+10)]);

  //set up canvas
  var stockLineCht = d3.select("#chart")
  .append("svg:svg")
  .attr("width", width + leftPadding + rightPadding)
  .attr("height", height + bottomPadding + topPadding);

  //add x-axis
  xAxis = d3.svg.axis()
  .scale(xScale)
  .orient("bottom")
  .ticks(5);

  //add r-axis
  volAxis = d3.svg.axis()
  .scale(volScale)
  .orient("right")
  .tickFormat(d3.format("s"))
  .ticks(5);

  volAxisGroup = stockLineCht.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + (leftPadding + width) + ",0)");

  xScale.domain([minDate, maxDate]);
  volScale.domain([0, maxVol]);

  //VOLUME bars
  var y1Bars = stockLineCht.selectAll("bars")
    .data(gData)
    .enter()
    .append("svg:rect")
    .attr("class", "bar");

  y1Bars.attr("x", function (d) { return xScale(getDate(d)) - (width/(gData.length * 1.5)) ; })
    .attr("y", function (d) { return volScale(d.Volume); })
    .attr("height", function (d) { return height - volScale(d.Volume); })
    .attr("width", function (d) {return width/(gData.length * 1.5);});

  volAxisGroup
    .attr("class", "r axis")
    .call(volAxis);

  stockLineCht.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
}

window.updateChart = function() {
    console.log('update called');
  var newData = updatedData;
  console.log(newData);

  var minDate = getDate(newData[0]);
  var maxDate = getDate(newData[newData.length - 1]);
  var maxVol = d3.max(newData, function (d) { return +d.Volume });

  xScale.domain([minDate, maxDate]);
  volScale.domain([0, maxVol]);

  var stockLineCht = d3.select("#chart");

  var y1Bars = stockLineCht.selectAll(".bar")
  .data(newData);

  y1Bars.enter()
  //.append("g")
  .append("svg:rect")
  .attr("class", "bar");
  //.append("svg:rect");

  y1Bars.transition()
  .duration(750)
  .attr("x", function (d) { return xScale(getDate(d)) - (width/(newData.length * 1.5)) ; })
  .attr("y", function (d) { return volScale(d.Volume); })
  .attr("height", function (d) { return height - volScale(d.Volume); })
  .attr("width", function (d) { return width/(newData.length * 1.5); });

  y1Bars.exit().transition().duration(750)
      .selectAll("rect")
      .attr("height", 0)
      .remove();

  stockLineCht.select(".x.axis") // change the x axis
  .transition()
  .duration(750)
  .call(xAxis);

  stockLineCht.select(".r.axis") // change the r axis
  .transition()
  .duration(750)
  .call(volAxis);
}

  // helper function
  function getDate(d) {
    return new Date(d.Date);
  }

1 个答案:

答案 0 :(得分:1)

这看起来像一个有效的解决方案。我改变了一些事情。

首先,条形图以某种方式未正确添加到图形中。因此,我们现在直接通过svg添加它。我不认为它在前一个方法中获得了正确的父元素。

  var y1Bars = d3.select("svg").selectAll(".bar")
    .data(newData);

我也改变了你进入酒吧的部分,所以看起来更像是过渡 -

  y1Bars.enter()
    //.append("g")
    .append("rect")
    .attr("class", "bar")
    .attr("x", width)
    .attr("y", function(d) {
      return height - volScale(d.Volume);
    })
    .attr("width", (width / (newData.length * 1.5)))
    .attr("height", function(d) {
      return volScale(d.Volume);
    });

此处的解决方案 - https://jsfiddle.net/w7eaf3o5/6/