2017-02-13 2 views
1

Ich habe ein Balkendiagramm, das gut funktioniert, außer wenn ein Update mit längeren Daten an es in der Funktion updateChart übergeben wird neue Balken nicht erstellt, obwohl die vorhandenen Balken werden korrekt umgewandelt.d3.js (v3) enter() funktioniert nicht in Balkendiagramm aktualisieren

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

hmm, es sieht aus wie Sie die neu erstellen Diagramm in der Update-Funktion. Dies kann hilfreich sein [Aktualisieren Sie die d3.js-Daten mit einem Tastendruck] (http://bl.ocks.org/d3noob/7030f35b72de721622b8) – theWhiteFox

+0

Ich glaube nicht, dass ich es neu erfinde - in der Fidel, zu der die Bars übergehen die neuen Daten es ist nur, dass neue Balken nicht "Enter" -ing für die zusätzlichen Datenpunkte –

+0

Sieht aus wie Ihre Update-Funktion ist ziemlich genau das gleiche wie Ihre Zeichenfunktion mit Ausnahme von Unterschieden wie in der Zeichenfunktion 'xScale = d3. time.scale(). range ([leftPadding, width + leftPadding]); 'und in deiner Update-Funktion hast du' xScale.domain ([minDate, maxDate]); ' – theWhiteFox

Antwort

1

Dies sieht aus wie eine funktionierende Lösung. Ich habe ein paar Dinge geändert.

Zuerst wurden die Balken irgendwie nicht korrekt zum Graphen hinzugefügt. Also fügen wir es jetzt direkt über die svg hinzu. Ich glaube nicht, dass es das korrekte Elternelement in der vorherigen Methode bekommen hat.

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

Ich habe auch den Teil, wo Sie die Bars Eingabe sind, so dass es eher wie ein Übergangs- sieht

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

Lösung hier - https://jsfiddle.net/w7eaf3o5/6/

+0

Danke - das funktioniert. Ich kann sehen, dass der Selektor, den ich für die Bars verwendet habe, ausgeschaltet war und dass ich die Attras der Enter-Auswahl nicht aktualisiert habe. –

Verwandte Themen