2016-08-08 90 views
0

我已經創建了D3條形圖,但我不確定如何更新它。數據本身正在更新,但當我試圖通過運行.enter().exit()的東西時,我會得到不同的錯誤,最常見的是我的.exit()函數不存在。我的觀點是,我不確定更新我的圖表svg的正確方法。D3簡單條形圖不更新

我提供了一個codepen here,但所有相關的代碼如下。

var b_margin = {top: 20, right: 20, bottom: 30, left: 100}, 
     b_width = 450 - b_margin.left - b_margin.right, 
     b_height = 200 - b_margin.top - b_margin.bottom; 

    var x = d3.scale.ordinal() 
     .rangeRoundBands([0, b_width], .1); 

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

    var xAxis = d3.svg.axis() 
     .scale(x) 
     .orient("bottom"); 

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

    var barsvg = d3.select("body").append("svg") 
     .attr("width", b_width + b_margin.left + b_margin.right) 
     .attr("height", b_height + b_margin.top + b_margin.bottom) 
     .append("g") 
     .attr("transform", "translate(" + b_margin.left + "," + b_margin.top + ")"); 

createBarChart = function() 
{ 
    x.domain(bardata.map(function(d) { return d.age; })); 
    y.domain([0, d3.max(bardata, function(d) { return d.population; })]); 

    barsvg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + b_height + ")") 
     .call(xAxis); 

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

    barsvg.selectAll(".bar") 
     .data(bardata) 
    .enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", function(d) { return x(d.age) + 25; }) 
     .attr("width", x.rangeBand() - 50) 
     .attr("y", function(d) { return y(d.population); }) 
     .attr("height", function(d) { return b_height - y(d.population); }); 

    function type(d) { 
    d.population = +d.population; 
    return d; 
    } 
} 

updateBarChart = function() 
{ 
    // Bar chart svg update 
    bardata = [ 
    {age: "title1", population: 50}, 
    {age: "title2", population: 25}, 
    {age: "title3", population: 70} 
    ] 

    barsvg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + b_height + ")") 
     .call(xAxis); 

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

    barsvg.selectAll(".bar") 
     .data(bardata) 
    .enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", function(d) { return x(d.age) + 25; }) 
     .attr("width", x.rangeBand() - 50) 
     .attr("y", function(d) { return y(d.population); }) 
     .attr("height", function(d) { return b_height - y(d.population); }); 

    barsvg.exit().remove(); 

    barsvg.attr("y", function(d) { return y(d.value); }) 
     .attr("height", function(d) { return height - y(d.value); }); 
} 

編輯:我的updateBarData功能如下:

+0

您還沒有定義updateBarData功能 –

+0

啊,我有。數據不是問題。我的信息是從一個更大的文件複製和粘貼。我更想弄清楚如何正確更新給定新數據的svg。我會在一秒鐘內用我的'updateBarData'看起來像添加一個編輯。 –

回答

1

真棒教程here

理念是,首先創建一個空的選擇和數據綁定到它。

var bars = barsvg.selectAll(".bar") 
.data(bardata) // bars is empty but data is binded to it 

現在,我們需要根據附加的數據創建元素。

var newBars = bars.enter(); // creates new elements 
newBars.apped("rect")......... // we do all the manipulation here 

刪除舊的元素,我們使用退出選擇

var obsoletebars = bars.exit(); //contains excess bars 
obsoletebars.remove(); // removes them 

希望這有助於。

\t \t var b_margin = {top: 20, right: 20, bottom: 30, left: 100}, 
 
    b_width = 450 - b_margin.left - b_margin.right, 
 
    b_height = 200 - b_margin.top - b_margin.bottom; 
 

 
var x = d3.scale.ordinal() 
 
.rangeRoundBands([0, b_width], .1); 
 

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

 
var xAxis = d3.svg.axis() 
 
.scale(x) 
 
.orient("bottom"); 
 

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

 
var barsvg = d3.select("body").append("svg") 
 
.attr("width", b_width + b_margin.left + b_margin.right) 
 
.attr("height", b_height + b_margin.top + b_margin.bottom) 
 
.append("g") 
 
.attr("transform", "translate(" + b_margin.left + "," + b_margin.top + ")"); 
 

 
var bardata = [ 
 
    { age: "Public", population: 50 }, 
 
    { age: "Private, for-profit", population: 100 }, 
 
    { age: "Nonprofit", population: 25 } 
 
]; 
 

 
createBarChart(); 
 

 
$('#btn').click(function() { 
 
    updateBarChart(); 
 
}); 
 

 
function createBarChart() 
 
{ 
 
    x.domain(bardata.map(function(d) { return d.age; })); 
 
    y.domain([0, d3.max(bardata, function(d) { return d.population; })]); 
 

 
    barsvg.append("g") 
 
    .attr("class", "x axis") 
 
    .attr("transform", "translate(0," + b_height + ")") 
 
    .call(xAxis); 
 

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

 
    barsvg.selectAll(".bar") 
 
    .data(bardata) 
 
    .enter().append("rect") 
 
    .attr("class", "bar") 
 
    .attr("x", function(d) { return x(d.age) + 25; }) 
 
    .attr("width", x.rangeBand() - 50) 
 
    .attr("y", function(d) { return y(d.population); }) 
 
    .attr("height", function(d) { return b_height - y(d.population); }); 
 

 
    function type(d) { 
 
    d.population = +d.population; 
 
    return d; 
 
    } 
 
} 
 

 
function updateBarChart() 
 
{ 
 
\t 
 
var random = function() { return Math.floor(Math.random() * 70) + 30 }; \t 
 
    // Bar chart svg update 
 
    bardata = [ 
 
    { age: "Public", population: random() }, 
 
    { age: "Private, for-profit", population: random() }, 
 
    { age: "Nonprofit", population: random() } 
 
]; 
 

 
    barsvg.append("g") 
 
    .attr("class", "x axis") 
 
    .attr("transform", "translate(0," + b_height + ")") 
 
    .call(xAxis); 
 

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

 
    var bars = barsvg.selectAll(".bar") 
 
    .data(bardata); 
 
\t 
 
    bars.enter().append("rect") 
 
    .attr("class", "bar") 
 
    .attr("x", function(d) { return x(d.age) + 25; }) 
 
    .attr("width", x.rangeBand() - 50) 
 
    .attr("y", function(d) { return y(d.population); }) 
 
    .attr("height", function(d) { return b_height - y(d.population); }); 
 

 
    bars.exit().remove(); \t 
 
\t 
 
    bars.attr("y", function(d) { 
 
\t return y(d.population); }) 
 
    .attr("height", function(d) { return b_height - y(d.population); }); 
 
}
#btn { 
 
    border: 2px solid #212121; 
 
    width: 150px; 
 
    text-align: center; 
 
    padding: 15px; 
 
    cursor: pointer; 
 
}
<script src="https://d3js.org/d3.v3.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
 
<div id='btn'>Update</div> \t

+0

非常感謝你的視頻。這非常有幫助。 –

1

D3不需要重寫新的吧。只是以下的更新:

updateBarChart = function() 
 
{ 
 
    // Bar chart svg update 
 
    bardata = [ 
 
    {age: "title1", population: 50}, 
 
    {age: "title2", population: 25}, 
 
    {age: "title3", population: 70} 
 
    ] 
 

 
    barsvg.selectAll(".bar") 
 
     .data(bardata) 
 
     .attr("x", function(d) { return x(d.age) + 25; }) 
 
     .attr("width", x.rangeBand() - 50) 
 
     .attr("y", function(d) { return y(d.population); }) 
 
     .attr("height", function(d) { return b_height - y(d.population); }); 
 
}