2017-07-18 153 views
0

我想通過單選按鈕選擇一個值時更新我的​​條形圖。此值作爲我的查詢的參數傳遞以獲取相應的JSON數據。如何重新繪製D3條形圖

該代碼工作正常,排除一個方面。當我通過單擊任何單選按鈕來選擇一個值時,條形圖將繪製在現有條形圖的頂部。我希望每次選擇新選項時都要重新繪製圖表。

// set the dimensions of the canvas 
var margin = {top: 20, right: 20, bottom: 70, left: 40}, 
    width = 600 - margin.left - margin.right, 
    height = 300 - margin.top - margin.bottom; 

// set the ranges 
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05); 

var y = d3.scale.linear().range([height, 0]); 

// define the axis 
var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom") 

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .ticks(10); 

var compSvg = d3.select(".company"); 

var companies = []; 
d3.json("http://localhost:8983/solr/techproducts/select?q=popularity:[10%20TO%20*]&wt=json&fl=cat&facet=true&facet.field=cat", function(error, resp) { 

    var results = resp.facet_counts.facet_fields.cat; 
    for (var i = 0; i < 5; i++) { 
     var value = results[i*2]; 
     companies.push(value); 
    } 
}); 


//functions for toggling between data 
function change(value){ 
    update(value); 
} 

function update(comp){ 
    var query = 'cat:"' + comp + '"'; 

    var url = "http://localhost:8983/solr/techproducts/select?q=" + encodeURIComponent(query) + "&rows=10&fl=manu,price&wt=json" 


    // load the data 
    d3.json(url, function(error, resp) { 

      if (error) return console.error(error); 

      resp.response.docs.forEach(function(d) { 
       d.manu = d.manu; 
       d.price = +d.price; 
      }); 

      // scale the range of the data 
      x.domain(resp.response.docs.map(function(d) { return d.manu; })); 
      y.domain([0, d3.max(resp.response.docs, function(d) { return d.price; })]); 

      // add axis 
      compSvg.append("g") 
       .attr("class", "x axis") 
       .attr("transform", "translate(0," + height + ")") 
       .call(xAxis) 
      .selectAll("text") 
       .style("text-anchor", "end") 
       .attr("dx", "-.8em") 
       .attr("dy", "-.55em") 
       .attr("transform", "rotate(-90)"); 

      compSvg.append("g") 
       .attr("class", "y axis") 
       .call(yAxis) 
      .append("text") 
       .attr("transform", "rotate(-90)") 
       .attr("y", 5) 
       .attr("dy", ".71em") 
       .style("text-anchor", "end") 
       .text("Price"); 


      // Add bar chart 
      compSvg.selectAll("bar") 
       .data(resp.response.docs) 
      .enter().append("rect") 
       .attr("class", "bar") 
       .attr("x", function(d) { return x(d.manu); }) 
       .attr("width", x.rangeBand()) 
       .attr("y", function(d) { return y(d.price); }) 
       .attr("height", function(d) { return height - y(d.price); }); 

    }); 

} 
+0

您是否嘗試過'd3.selectAll( 「酒吧」),刪除();'並把它作爲調用的第一個項目。? –

+0

'compSvg.selectAll(「bar」)'總是會給你一個空的選擇,因此在設置數據後,輸入選擇將總是追加新的矩形。嘗試:'compSvg.selectAll(「.bar」) - 您正在將'rect'元素附加到'bar'類,而不是'bar'元素。 –

+0

@AndrewReid這是一個改進,但它沒有什麼區別:OP只有一個「輸入」選擇,沒有更新或退出選擇。這是他/她的問題。 –

回答

2

當加載排行榜的第一次,一切正常:你有一個空的選擇和輸入選擇創建了一個元素用於數據數組中的每個項目。您還附加軸。

當您第二次使用change函數加載圖表時,您首先重複做了哪些操作來創建圖表:由於selectAll("bar")將爲空,並且輸入選項會創建一個新選項元素用於數據數組中的每個項目。您還附加軸。

您需要使用更新並退出選擇正確,使這項工作:

初始數據追加後,您需要使用更新的選擇修改酒吧,一個進入新的酒吧帶來的(如果一個數據集比另一個數據集使用更多條)和退出選擇以退出不需要的條(如果一個數據集使用的條比其他條更少)。網上有很多關於進入,更新,退出流程的信息;請記住,v4和v3之間存在差異。

這看起來像:

var data = [ 
 
    [1,2,3,4,5], 
 
    [6,4,3], 
 
    [5,10,1,7,1,3] 
 
]; 
 

 
var i = 0; 
 

 
var width = 500; 
 
var height = 500; 
 

 
var svg = d3.select("body") 
 
    .append("svg") 
 
    .attr("width",width) 
 
    .attr("height",height); 
 
    
 
var y = d3.scale.linear().range([height, 0]); 
 
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05); 
 

 

 
update(data[0]); 
 
timer(); 
 

 
function update(dataset) { 
 

 
    // update scales 
 
    y.domain([0,d3.max(dataset, function(d) { return d; })]); 
 
    x.domain(dataset.map(function(d,i) { return i; })); 
 
    
 
    // Bind Data 
 
    var bars = svg.selectAll(".bars") 
 
    .data(dataset); 
 
    
 
    // Update existing bars: 
 
    bars.transition() 
 
    .attr("x",function(d,i) { return x(i); }) 
 
    .attr("y",function(d) { return y(d); }) 
 
    .attr("width", x.rangeBand()) 
 
    .attr("height", function(d) { return height - y(d); }) 
 
    .duration(1000); 
 
    
 
    
 
    // New Bars 
 
    bars.enter() 
 
    .append("rect") 
 
    .attr("class","bars") 
 
    .attr("x",function(d,i) { return x(i); }) 
 
    .attr("width", x.rangeBand()) 
 
    .attr("y",height) 
 
    .attr("height",0) 
 
    .transition() 
 
    .attr("y",function(d) { return y(d); }) 
 
    .attr("height", function(d) { return height - y(d); }) 
 
    .duration(1000);; 
 
    
 
    // Un-needed Bars: 
 
    bars.exit() 
 
    .transition() 
 
    .attr("height", 0) 
 
    .duration(1000) 
 
    .remove(); 
 
    
 
} 
 

 
function timer() { 
 
    setTimeout(function() { update(data[i++%3]); timer() } , 1500); 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

+一個用於鏈接S.O.文檔。不幸的是,Docs已經死了...... –

-1

稍加修改可以滿足你的需要:

function change(value){ 
    // erase all contents before update 
    compSvg.html(""); 
    update(value); 
}