2017-05-17 59 views
2

區我有一個功能,我稱之爲渲染d3js圖表:d3js圖點和更新不及時

var tooltip = tooltipd3(); 
var svg = d3.select("svg#svg-day"), 
    margin = { 
     top: 20, 
     right: 30, 
     bottom: 30, 
     left: 25, 
     padding: 15 
    }, 
    width = 700 - margin.left - margin.right, 
    height = 300 - margin.top - margin.bottom; 

// parse the periodo/time 
var parseTime = d3.timeParse("%Y-%m-%d"); 

// set the ranges 
var x = d3.scaleTime().range([0, width - margin.padding]); 
var y = d3.scaleLinear().range([height, 0]); 

// define the area 
var area = d3.area() 
    .x(function(d) { 
     return x(d.periodo) + (margin.left + margin.padding); 
    }) 
    .y0(height) 
    .y1(function(d) { 
     return y(d.guadagno); 
    }); 

// define the line 
var valueline = d3.line() 
    .x(function(d) { 
     return x(d.periodo) + (margin.left + margin.padding); 
    }) 
    .y(function(d) { 
     return y(d.guadagno); 
    }); 

var div = d3.select("svg#svg-day") 
    .append("div") // declare the tooltip div 
    .attr("class", "tooltip") // apply the 'tooltip' class 
    .style("opacity", 0); 

// get the data 
d3.csv(base_url() + 'graph/getStatementsDaily/', function(error, data) { 
    if (error) throw error; 
    $('.graph-loading').hide(); 
    // format the data 
    data.forEach(function(d) { 
     d.periodo = parseTime(d.periodo) 
     d.guadagno = +d.guadagno; 
    }); 

    // scale the range of the data 
    x.domain(d3.extent(data, function(d) { 
     return d.periodo; 
    })); 
    y.domain([0, d3.max(data, function(d) { 
     return d.guadagno + ((d.guadagno/100) * 10); // 10% in più sulla scala numerica 
    })]); 

    // add the area 
    svg.append("path") 
     .data([data]) 
     .attr("class", "area") 
     .attr("d", area); 

    // add the valueline path. 
    svg.append("path") 
     .data([data]) 
     .attr("class", "line") 
     .attr("d", valueline); 

    // Add the scatterplot 
    svg.selectAll("dot") 
     .data(data) 
     .enter().append("circle") 
     .attr("class", "dot") 
     .attr("r", 3) 
     .attr("cx", function(d) { 
      return x(d.periodo) + (margin.left + margin.padding); 
     }) 
     .attr("cy", function(d) { 
      return y(d.guadagno); 
     }) 
     .on('mouseover', function(d) { 
      var html = '<h5>' + d.guadagno + ' €</h5>'; 
      tooltip.mouseover(html); // pass html content 
     }) 
     .on('mousemove', tooltip.mousemove) 
     .on('mouseout', tooltip.mouseout); 

    // add the X Axis 
    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(" + (margin.left + margin.padding) + "," + (height) + ")") 
     .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m"))) 

    // add the Y Axis 
    svg.append("g") 
     .attr("class", "y axis") 
     .attr("transform", "translate (" + (margin.left + margin.padding) + " 0)") 
     .call(d3.axisLeft(y)); 

}); 

這是結果:enter image description here

側面按鈕,你看到的是改變CSV網址從而使海圖更新上點擊,我這樣做與此:

$('.input-number__increase, .input-number__decrease').on('click', function() { 
    var where_at = $('#scroll-statement-day').val(); 
    $('.graph-loading').show(); 
    $('#svg').css({ 'opacity': 0.4 }); 

    var display_where_at = (where_at - 7) + '-' + where_at; 
    if (parseInt(where_at) === 7) { 
     display_where_at = where_at; 
    } 

    $('#data-days').html(display_where_at); 

    var tooltip = tooltipd3(); 
    var svg = d3.select("svg#svg-day"), 
     margin = { 
      top: 20, 
      right: 30, 
      bottom: 30, 
      left: 25, 
      padding: 15 
     }, 
     width = 700 - margin.left - margin.right, 
     height = 300 - margin.top - margin.bottom; 

    // parse the periodo/time 
    var parseTime = d3.timeParse("%Y-%m-%d"); 

    // set the ranges 
    var x = d3.scaleTime().range([0, width - margin.padding]); 
    var y = d3.scaleLinear().range([height, 0]); 

    // define the area 
    var area = d3.area() 
     .x(function(d) { 
      return x(d.periodo) + (margin.left + margin.padding); 
     }) 
     .y0(height) 
     .y1(function(d) { 
      return y(d.guadagno); 
     }); 

    // define the line 
    var valueline = d3.line() 
     .x(function(d) { 
      return x(d.periodo) + (margin.left + margin.padding); 
     }) 
     .y(function(d) { 
      return y(d.guadagno); 
     }); 

    var div = d3.select("svg#svg-day") 
     .append("div") // declare the tooltip div 
     .attr("class", "tooltip") // apply the 'tooltip' class 
     .style("opacity", 0); 

    var speed = 750; 

    d3.csv(base_url() + 'graph/getStatementsDaily/' + where_at, function(error, data) { 
     if (error) throw error; 
     $('.graph-loading').hide(); 
     $('#svg').css({ 'opacity': 1 }); 
     // format the data 
     data.forEach(function(d) { 
      d.periodo = parseTime(d.periodo) 
      d.guadagno = +d.guadagno; 
     }); 

     // Scale the range of the data again 
     x.domain(d3.extent(data, function(d) { 
      return d.periodo; 
     })); 
     y.domain([0, d3.max(data, function(d) { 
      return d.guadagno + ((d.guadagno/100) * 10); // 10% in più sulla scala numerica 
     })]); 

     // Select the section we want to apply our changes to 
     var svg = d3.select("body").transition(); 

     // Make the changes 
     svg.select(".line") // change the line 
      .duration(speed) 
      .attr("d", valueline(data)); 
     svg.selectAll("g.x.axis") // change the x axis 
      .duration(speed) 
      .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m"))); 
     svg.selectAll("g.y.axis") // change the y axis 
      .duration(speed) 
      .call(d3.axisLeft(y)); 

     svg.select("path") 
      .duration(speed) 
      .attr("d", area); 

     svg.select("circle") 
      .duration(speed) 
      .attr("r", 3) 
      .attr("cx", function(d) { 
       return x(d.periodo) + (margin.left + margin.padding); 
      }) 
      .attr("cy", function(d) { 
       return y(d.guadagno); 
      }) 

    }); 
}); 

這隻能部分地,我得到這樣的結果:enter image description here

我試圖找出原因,但我無法得到它..任何想法?

回答

2

當你這樣做:

svg.select("circle") 

你只選擇第一圈(如果有的話)的頁面。根據API,select ...

選擇指定的選擇字符串匹配的第一元素。 (強調我的)

這就是說,你需要selectAll在這裏。但是單靠這一點無法解決問題:您必須重新綁定數據。由於我不知道你的數據結構,默認的方法通過索引綁定。

總之,它應該是:

svg.selectAll("circle") 
    .data(data) 
    //etc... 

由於這些圈子中有類名爲dot,你能避免使用選擇其他圈子:

svg.selectAll(".dot") 
    .data(data) 
    //etc... 

關於線路和區域,做相同:首先綁定數據,然後更改其屬性d屬性:

svg.select(".area") 
    .data([data]) 
    .attr("d", area); 

svg.select(".line") 
    .data([data]) 
    .attr("d", valueline); 

而且,由於你重新綁定數據,你就必須改變這一點:

var svg = d3.select("body").transition(); 

因爲svg.selectAll將是這樣說的過渡selection.That,設置重新綁定數據之後過渡到每一個人的選擇,將其從svg選擇中刪除。

+0

謝謝!當執行'svg.selectAll(「。dot」).data(data)'時,它會給出這個:'svg.selectAll(...).spag不是一個函數'..'svg.select(「.small 「) .data([data])'。怎麼來的? –

+0

可能因爲你有'duration()'而沒有'transition()'。 –

+0

我有'var svg = d3.select(「svg#svg-day」)。transition();'就像上面的代碼一樣。 –