2012-04-25 5 views
4

Я работаю на гистограмме, используя d3.js, панель shoud сможет соответствовать новым данным json.D3.js update bar chart from json

var m = [30, 5, 5, 5], 
    w = 375 - m[1] - m[3], 
    h = 260 - m[0] - m[2]; 

var format = d3.format(",.0f"); 

var wdthnew = d3.scale.linear().range([0, w]), 
    wdth = d3.scale.linear().range([0, w]).domain([0, 25000]), 
    hght = d3.scale.ordinal().rangeRoundBands([0, h], .1); 

var svg = d3.select("body").append("svg") 
    .attr("width", w + m[1] + m[3]) 
    .attr("height", h + m[0] + m[2]) 
    .append("g") 
    .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); 

d3.json("barchartjson.php", function(data) { 

    data.sort(function(a, b) { return b.value - a.value; }); 
    hght.domain(data.map(function(d) { return d.orientation; })); 

    var bar = svg.selectAll("g.bar") 
     .data(data) 
    .enter().append("g") 
     .attr("class", "bar") 
     .attr("transform", function(d) { return "translate(0," + hght(d.orientation) + ")"; }); 

    bar.append("rect") 
     .attr("id", "activebar") 
     .attr("width", 0) 
     .attr("height", hght.rangeBand()) 
    .transition() 
    .delay(100) 
    .duration(1000)  
     .attr("width", function(d) { return wdth(d.value); });  
}); 

function makebar(date1, date2) { 
var barchartjson = "barchartjson.php?df="+date1+"&dl="+date2; 

d3.json(barchartjson , function(datanew) { 

    datanew.sort(function(a, b) { return b.jumlah - a.jumlah; }); 

    wdthnew.domain([0, d3.sum(datanew, function(d) { return d.value; })]); 

    console.log("SUM datanew: "+ d3.sum(datanew, function(d) { return d.value; })); 
    console.log("Array datanew: "); 
    console.log(datanew); 
    var updatebar = svg.selectAll("#activebar"); 

    updatebar.transition().duration(1000) 
     .attr("width", function(a) { console.log("update width: wdthnew("+a.value+") = "+wdthnew(a.value)); 
     return wdthnew(a.value); }); 
}); 
} 

Вот от barchartjson.php JSON используется в первый раз:

[{"orientation":"negatif","value":"15964"},{"orientation":"netral","value":"2788"},{"orientation":"positif","value":"9701"}] 

бар показывает правильно в первый раз. Проблема заключается в том, когда вызывается makebar(), обновляя ширину полосы с новыми данными json. Каждая ширина полосы обновляется, но в некоторых случаях они выходят за допустимые пределы. Вот выход из console.log:

SUM datanew: 2520 
Array datanew: 
[Object 
value: "1411" 
orientation: "negatif" 
__proto__: Object 
, 
Object 
value: "846" 
orientation: "positif" 
__proto__: Object 
, 
Object 
value: "263" 
orientation: "netral" 
__proto__: Object 
] 
update width: wdthnew(15964) = 2312.246031746032 
update width: wdthnew(9701) = 1405.1051587301588 
update width: wdthnew(2788) = 403.81746031746036 

новый успешно называется JSON, но журнал, показывающий, что wdthnew будет держать масштабирование старый JSON.

updatebar.transition().duration(1000) 
     .attr("width", function(a) { console.log("update width: wdthnew("+a.value+") = "+wdthnew(a.value)); 
     return wdthnew(a.value); }); 

в результате:

update width: wdthnew(15964) = 2312.246031746032 

несмотря 15694 от старого JSON, wdthnew (d.value) фактически возвращает значение из wdthnew (1411) является 2312 которым и находится вне диапазон.

Может кто-нибудь помочь мне решить эту проблему? Или указать, где я делаю неправильно? Я новичок в d3.js и javascript. Прошу прощения за плохую грамматику. Английский не мой родной язык.

jsFiddle здесь: http://jsfiddle.net/saido/5mREA/

ответ

1

Возможно создать буфер массив/объект, который будет хранить данные перед использованием его ... Затем создайте интервал обновления, который не будет обновляться до поступления новых данных.

Update: Вот пример

var data = [{x: 1, y: 3}, 
      {x: 2, y: 4}, 
      {x: 3, y: 5}, 
      ... 
      ]; 

var incomingData = []; 

/* incoming data gets .pushed(...) in every 1 or 
    2 seconds, depending on network traffic */ 

var updateDelay = 3000; 

setInterval(function() { 
     for (var index = 0; index < data.length; index++) { 
      seriesData.shift(); 
      seriesData.push(incomingData.shift()); 
      redrawGraph(); 
     } 
    }, updateDelay); 
+0

Благодарим вас за ответ, Август. Не могли бы вы уточнить, как создать интервал обновления? – Frendhi

+0

Я обновил свой ответ на примере. Надеюсь это поможет! – August

+1

Я нашел проблему! Еще раз спасибо, Августум. – Frendhi

3

Оказывается, проблема была в function makebar(): на этой линии я должен приложить новые данные:

var updatebar = svg.selectAll("#activebar").data(datanew); 

Теперь console.log показ и вычисление правильных значений.

Прошу прощения, я не знаю, как объяснить техническую проблему более подробно.