2017-02-13 95 views
1

我有一个条形图,它工作正常,除非在updateChart函数中将更新数据传递给它时,酒吧确实过渡正确。d3.js(v3)enter()不能在条形图更新中工作

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

嗯,它看起来像你重现图表在更新功能。这可能会有所帮助[按按钮更新d3.js数据](http://bl.ocks.org/d3noob/7030f35b72de721622b8) – theWhiteFox

+0

我不认为我正在重新创建它 - 在小提琴中,新的数据只是新的条不是“输入” - 为了解释额外的数据点 –

+0

看起来你的更新函数与draw函数非常相似,除了draw函数'xScale = d3之外的差别。 time.scale()。range([leftPadding,width + leftPadding]);'并且在你的更新函数中有'xScale.domain([minDate,maxDate]);' – theWhiteFox

回答

1

这看起来像一个可行的解决方案。我改变了一些东西。

首先,酒吧不知何故被正确添加到图中。所以现在我们直接通过svg添加它。我不认为它是在前面的方法中获得正确的父元素。

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

我也改,你正在进入酒吧,所以它看起来更像是一个transition-

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/

+0

谢谢 - 这是它的工作。我可以看到我用于酒吧的选择器已关闭,并且我没有更新输入选择的attrs。 –