2016-05-06 6 views
0
を更新

イム現在、私は起こるしたい何d3.js D3.jsマルチLinegraphパスに追加し、軸

で私linegraphパスと軸の更新で問題が発生している持つ、新しいデータが入力されると(好ましくはウェブソケットを介して行うが、簡単なボタンクリックで分単位で)、グラフの新しい点まで線が延び、必要に応じて軸が調整されて新しい販売値を容易にする。

次のように私はこれを試して使用していたテストデータは次のとおりです。

クライアント:XYZ 売上高:400 時間:午前17時00

ウェブ上で、それぞれのフィールドに入力する必要があります形。

私はいくつかの方法を試しましたが、まだd3.jsにはまだ新しく、正しい方法でデータを選択したりバインドしているかどうかわかりませんどちらかを更新してください。

このコードをグラフ上のすべての行に対して同時に実行することをお勧めします。したがって、Webフォームがデータベースとペア設定されている場合、設定された間隔ですべての行を同時に更新します。

提案がありますか?大変感謝しています。現在のビルドの

jsfiddle:ボタンのクリックイベントのためhttps://jsfiddle.net/2bqzuue3/1/

コード:

d3.select("button") 
     .attr("id","submit") 
     .on("click", function(d){ 
      var newClient = document.getElementById("client").value; 
      var newSale = document.getElementById("sale").value; 
      var newtime = document.getElementById("time").value; 



      var update = { 
       "Client" : newClient, 
       "sale": newSale, 
       "time": newtime 
      }; 

      data.push(update); 

      dataGroup = d3.nest() 
        .key(function(d){ 
         return d.Client; //Decides which property (i.e key) to sort your data with 
             //Useful for multiple lines on one graph 
        }) 
        .entries(data); 

      xScale = d3.time.scale() 
        .domain([d3.min(data, function(d){return parseTime(d.time);}),d3.max(data, function(d){return parseTime(d.time);})]) 

      yScale = d3.scale.linear() 
        .domain([d3.min(data, function(d){return d.sale;}) , d3.max(data, function(d){return d.sale;})]); 

      vis.select(".x.axis") 
       .transition() 
       .duration(1000) 
       .call(xAxis); 

      vis.select(".y.axis") 
       .transition() 
       .duration(1000) 
       .call(yAxis); 

      lineGen = d3.svg.line() 
       .x(function(d){ 
        return xScale(parseTime(d.time)); 
       }) 
       .y(function(d){ 
        return yScale(d.sale); 
       }) 
       .interpolate("monotone"); 

      vis.selectAll("path") 
       .data(dataGroup) 
       .enter() 
       .append("svg:path") 
       .attr("d", lineGen(dataGroup.values)) 
       .transition() 
       .duration(1000); 




    }); 

*注:jsfiddleにテストデータを入力するテキストフィールドを表示するには、スクロールダウンする必要があります。

答えて

1

コードに2つの問題があります。どちらのコードを単独で修正しても目立つ効果がないため、修正するのが難しくなります。両方を一緒に修正する必要があります。

まず、あなたのコードにある簡単なもの。最後のセクションでは、次のようになります。

var paths = vis.selectAll("path") 
    .data(dataGroup); 
paths.enter() 
    .append("svg:path"); 
paths.transition() 
    .duration(1000) 
    .attr("d", lineGen(dataGroup.values)); 

あなたはコードが唯一のデータバインドによって作成された新しい要素のために実行することを意味し.enter()選択のオフのすべてを、チェーン化されました。これを分割することによって、d attrが既存の要素と新しい要素の両方に設定されていることを確認できます。このコンセプトの詳細な説明はhereです。

あなたの2番目の問題はもう少し複雑で、上のコードではなく、あなたのjsfiddleです。それはあなたのdataGroup.forEach()ループで起こります。まず最初に、このようなループを使用すると、実際にはd3データバインドを使用してスキップされますが、この方法ではいくつかのメリットを逃してしまいます。あなたは私のjsfiddleを代わりにこれを書く方法の提案と一緒に見ることができます。あなたが持っている実際の問題は、長さを計算するために3つの隠されたパスを作成し、次に実際に表示するために3つのパスを作成することです。これはDOM内に6つのパスがあることを意味します。したがって、データをボタンクリックでバインドすると、データは表示されている3つの隠しパスにバインドされます。あなたは、このような総経路長を取得するために隠されたパスを使用して周りに取得することができます:私はグループのために作成し、すべてがあなたのボタンのonClick関数のスケールを固定のように、右の作業を取得するカップルの他の小さな変更を加え

path.attr("stroke-dasharray", function() { 
    return this.getTotalLength() + " " + this.getTotalLength(); 
}) 
.attr("stroke-dashoffset", function() { 
    return this.getTotalLength(); 
}) 

パスを指定して、ストロークダッシュアレイを更新します。jsfiddleの詳細を参照してください。今後

https://jsfiddle.net/9kkf6abw/

、私は最初のドローならびに任意のアップデートの両方を扱うことができる新しい描画機能を作成することをお勧めします。あなたがその関数を作成すると削除される可能性がある繰り返しコードがたくさんあります。これらの変更を加えれば、ほぼそこにあります。

+0

情報とアドバイスをありがとうございました!とても有難い! –