1

Websocket を介してサーバーからより多くのデータを受信すると、バーの高さが増加するように、受信したデータでグラフを更新しようとしています。しかし、私のコードはブラウザでグラフをレンダリングせず、データ ポイントをプロットしません。コードに問題はありません。ここで本当に助けが必要です。

  ws = new WebSocket("ws://localhost:8888/dh");

  var useData = []
  //var chart;

  var chart = d3.select("body")
     .append("svg:svg")
     .attr("class", "chart")
     .attr("width", 420)
     .attr("height", 200);


  ws.onmessage = function(evt)
  {  
    var distances = JSON.parse(evt.data);
    data  = distances.miles;
    console.log(data);

    if(useData.length <= 10){
      useData.push(data)
    }
    else
    {

       var draw = function(data){        
       // Set the width relative to max data value
       var x = d3.scale.linear()
        .domain([0, d3.max(useData)])
        .range([0, 420]);

       var y = d3.scale.ordinal()
        .domain(useData)
        .rangeBands([0, 120]);

       var rect = chart.selectAll("rect")
        .data(useData)

        // enter rect
        rect.enter().append("svg:rect")
            .attr("y", y)
            .attr("width", x)
            .attr("height", y.rangeBand());

        // update rect            
        rect
            .attr("y", y)
            .attr("width", x)
            .attr("height", y.rangeBand());

       var text = chart.selectAll("text")
            .data(useData)

       // enter text
       text.enter().append("svg:text")
            .attr("x", x)
            .attr("y", function (d) { return y(d) + y.rangeBand() / 2; })
            .attr("dx", -3) // padding-right
            .attr("dy", ".35em") // vertical-align: middle
            .attr("text-anchor", "end") // text-align: right
            .text(String);

        // update text
        text
            .data(useData)
            .attr("x", x)
            .text(String);
    }
draw();
useData.length = 0;
   }          
}                 

ありがとう

編集:

ただし、現在の問題は、既存のバーに新しいデータを追加するようには見えず、代わりに古い値が置き換えられることです。新しい値を既存のバーの値に追加する方法を教えてください。たとえば、バー「A」の値が 7 の場合、バー「A」の値が 9 の新しいデータが来ると、バーは 9 ではなく 16 になるはずです。 /

4

1 に答える 1

2

前回の反復からの古いデータで新しいデータを集計する式はないようです。useData.length = 0既存のデータを完全に消去しuseData.push(data)、単一の要素のみを空のuseData配列にプッシュします。これは、プロットに必要な形式のデータを生成しないと推測しています。

draw()また、ここで何かが欠けている可能性がありますが、関数がws.onmessageハンドラー内にある理由はないようです。ハンドラーの外側で定義することにより、起動するdraw()たびに再定義されるのではなく、一度定義されws.onmessageます。

私が正しければ、コードを少し再配置するだけで済みます。さらに、大幅に削減されたws.onmessageハンドラーに小さなループを追加して、新しいマイルを古いものと集計する必要があります。

var ws = new WebSocket("ws://localhost:8888/dh");
var useData = [12,45,48,45,654,12,465,5,12,45];
var chart = d3.select("body").append("svg:svg").attr("class", "chart").attr("width", 420).attr("height", 200);

function draw() {
    // Set the width relative to max data value
    var x = d3.scale.linear().domain([0, d3.max(useData)]).range([0, 420]);
    var y = d3.scale.ordinal().domain(useData).rangeBands([0, 120]);
    var rect = chart.selectAll("rect").data(useData);
    // enter rect
    rect.enter().append("svg:rect").attr("y", y).attr("width", x).attr("height", y.rangeBand());
    // update rect            
    rect.attr("y", y).attr("width", x).attr("height", y.rangeBand());
    var text = chart.selectAll("text").data(useData);
    // enter text
    text.enter().append("svg:text").attr("x", x).attr("y", function(d) {
        return y(d) + y.rangeBand() / 2;
    }).attr("dx", -3) // padding-right
      .attr("dy", ".35em") // vertical-align: middle
      .attr("text-anchor", "end") // text-align: right
      .text(String);
    // update text
    text.data(useData).attr("x", x).text(String);
};

draw();//initialise with hard-coded useData

//Now, aggregate additional miles when ws.onmessage fires and redraw the graph.
ws.onmessage = function(evt) {
    var distances = JSON.parse(evt.data);
    for(var i=0; i<useData.length; i++) {
        if(useData[i] && distances.miles[i]) {//safety
            useData[i] += distances.miles[i];//add the new miles to the total from previous iteration
        }
    }
    draw();//redraw the graph
}

注: - 私は d3 に詳しくないので、draw()機能を検証しようとはしていません。- いろいろ推測したので、まだやるべきことがあるかもしれません。

于 2012-12-09T01:51:39.680 に答える