簡體   English   中英

d3.js (v3) enter() 在條形圖更新中不起作用

[英]d3.js (v3) enter() not working in bar chart update

我有一個條形圖,它工作正常,除非在 updateChart 函數中將具有更長數據的更新傳遞給它時,盡管現有條形正確轉換,但不會創建新條形圖。

js小提琴

    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);
  }

這看起來像是一個有效的解決方案。 我改變了一些東西。

首先,條形以某種方式沒有正確添加到圖表中。 因此,我們現在直接通過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/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM