4

私はd3.jsを使用して棒グラフに取り組んでいます。棒は新しい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) は実際には 2312 である wdthnew(1411) からの値を返し、範囲外です..

誰かがこの問題を解決するのを手伝ってくれますか? または、私が間違っているところを指摘してください。私はd3.jsとjavascriptが初めてです。文法が悪くてすみません。英語は私の母国語ではありません。

jsFiddle はこちら: http://jsfiddle.net/saido/5mREA/

4

2 に答える 2

3

問題はfunction makebar(): この行にあり、新しいデータを添付することになっていることがわかりました。

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

これで、console.logに適切な値が表示され、計算されます。

申し訳ありませんが、技術的な問題をより詳細に説明する方法がわかりません。

于 2012-05-02T12:35:55.030 に答える
1

おそらく、データを使用する前にデータを格納するバッファ配列/オブジェクトを作成します...次に、新しいデータが到着する前に更新されない更新間隔を作成します。

更新:これは例です

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);
于 2012-04-25T23:26:21.170 に答える