2017-03-17 3 views
2

私は最後の数ヶ月間、写本で働いています。私は素晴らしい結果を得ていますが、異なる信号のデータを同じチャートに表示する方法を見つけるためにいくつか問題があります。グラフを使って補間データを表示することはできますか?

異なるセンサから受信したデータは、異なるサンプルのタイムスタンプが同じではないため、x axタイムスタンプのほとんどの点では、私は1つの信号の値しか持っていません。グラフは完全にプロットされていますが、私が指しているx点の残りの信号の補間値を見たいと思います。私は以下のチャートを持っています。 dygraph documentationに読む

enter image description here

私はあなたが独立したシリーズを持っている場合、X斧のその時点でのデータがない信号のために、「未定義」とは、少なくとも値を参照することが可能であることを見てきました。

データをプロットするために使用するcsvを以下に示します。それは文字図書に示されているのと同じ構造をしていますが、私はこの未定義のラベルも取得しません。事前に

TIME,LH_Fuel_Qty,L_Left_Sensor_NP 1488801288048,,1.4411650490795007 1488801288064,0.478965502446834, 1488801288133,,0.6372882768113235 1488801288139,1.131315227899919, 1488801288190,1.847605177130475, 1488801288207,,0.49655791428536067 1488801288258,0.45488168748987334, 1488801288288,,1.3756073145270766 1488801288322,0.5636921255908185, 1488801288358,,1.1193344122758362

感謝。

答えて

1

これは、csvデータにデータを追加せず、マウスを動かしてもすべての列の補間値を提供する手法です。 dygraph内のmousemoveイベントにリスナーを追加し、すべてのデータに最も近い点を補間します。現時点では私は単にグラフの後で、余分なDIVでそれを示しているが、あなたはそれを表示することができますしかし、あなたが好き:

function findNextValueIndex(data, column, start) { 
 
    var rows = data.length; 
 

 
    for (var i = start; i < rows; i++) { 
 
    if (data[i][column] != null) return (i); 
 
    } 
 
    return (-1); 
 
} 
 

 
function findPrevValueIndex(data, column, start) { 
 

 
    for (var i = start; i >= 0; i--) { 
 
    if (data[i][column] != null) return (i); 
 
    } 
 
    return (-1); 
 
} 
 

 
function interpolate(t0, t1, tmid, v0, v1) { 
 
    return (v0 + (tmid - t0)/(t1 - t0) * (v1 - v0)); 
 
} 
 

 
function showValues(headers, colors, vals) { 
 
    var el = document.getElementById("info"); 
 
    var str = ""; 
 
    for (j = 1; j < headers.length; j++) { 
 
    str += '<p style="color:' + colors[j] + '";>' + headers[j] + ": " + vals[j] + "</p>"; 
 
    } 
 
    el.innerHTML = str; 
 
    document.getElementById("hiddenDiv").style.display = "none"; 
 
} 
 

 
function movecustom(event, dygraph, point) { 
 
    var time = dygraph.lastx_; 
 
    var row = dygraph.lastRow_; 
 
    var vals = []; 
 
    var headers = []; 
 
    var colors = []; 
 
    var cols = dygraph.rawData_[0].length; 
 
    
 
    // draw a line on the chart showing the selected location 
 
    var canvas = dygraph.canvas_; 
 
    var ctx = canvas.getContext("2d"); 
 

 
    ctx.beginPath(); 
 
    ctx.lineWidth = 1; 
 
    ctx.strokeStyle = "rgba(0,200,200,0.1)"; 
 
    ctx.moveTo(dygraph.selPoints_[0].canvasx, 0); 
 
    ctx.lineTo(dygraph.selPoints_[0].canvasx, 1000); 
 
    ctx.stroke(); 
 
    
 
    
 
    for (var j = 1; j < cols; j++) { 
 
    colors[j] = dygraph.colors_[j - 1]; 
 
    if (dygraph.rawData_[row][j] == null) { 
 
     var prev = findPrevValueIndex(dygraph.rawData_, j, row - 1); 
 
     var next = findNextValueIndex(dygraph.rawData_, j, row + 1); 
 
     if (prev < 0) 
 
     vals[j] = dygraph.rawData_[next][j]; 
 
     else if (next < 0) 
 
     vals[j] = dygraph.rawData_[prev][j]; 
 
     else { 
 
     vals[j] = interpolate(dygraph.rawData_[prev][0], dygraph.rawData_[next][0], time, dygraph.rawData_[prev][j], dygraph.rawData_[next][j]); 
 
     } 
 
    } else { 
 
     vals[j] = dygraph.rawData_[row][j]; 
 
    } 
 
    } 
 

 
    headers = Object.keys(dygraph.setIndexByName_); 
 

 
    showValues(headers, colors, vals); 
 
} 
 

 
window.onload = function() { 
 

 
    new Dygraph(
 
    document.getElementById('graph'), document.getElementById('csvdata').innerHTML, { 
 
     connectSeparatedPoints: true, 
 
     drawPoints: true, 
 
     labelsDiv: "hiddenDiv", 
 
     interactionModel: { 
 
     'mousemove': movecustom 
 
     } 
 
    } 
 
); 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.0.0/dygraph.js"></script> 
 

 
<div id="graph" style="height:120px;"></div> 
 

 
<div id="info"></div> 
 
<div id="hiddenDiv" style="display:none"></div> 
 

 
<pre id="csvdata" style="display:none"> 
 
TIME,LH_Fuel_Qty,L_Left_Sensor_NP 
 
1488801288048,,1.4411650490795007 
 
1488801288064,0.478965502446834, 
 
1488801288133,,0.6372882768113235 
 
1488801288139,1.131315227899919, 
 
1488801288190,1.847605177130475, 
 
1488801288207,,0.49655791428536067 
 
1488801288258,0.45488168748987334, 
 
1488801288288,,1.3756073145270766 
 
1488801288322,0.5636921255908185, 
 
1488801288358,,1.1193344122758362 
 
</pre>

+0

ありがとう@fmacdee、本当にあなたの助けに感謝します。今私はプロジェクトの別の部分で非常に忙しいですが、私はあなたの答えをできるだけ早く試してみましょう、私の意見を知って、それが私のために働く場合の有効な答えを教えてください;) –

1

これを行う最良の方法は、データをダイグラフ呼び出しに送信する前にマッサージすることです。これは以下のステップを意味します: 1)csvファイルを配列の配列に解析します。 2)孔が 3である場合見つけるために、アレイの各ラインを通過する)は、それらの孔 4を充填するために補間)dygraph 5で表示されるように構成配列を変更する)コールdygraph

は、最も魅力的なコードしかし、動作しているようです...

function findNextValueIndex(data, column, start) { 
 
    var rows = data.length; 
 

 
    for(var i=start;i<rows;i++) { 
 
     if(data[i][column].length>0) return(i); 
 
    } 
 
    return(-1); 
 
} 
 

 
function interpolate(t0, t1, tmid, v0, v1) { 
 
    return((v0 + (tmid-t0)/(t1-t0) * (v1-v0)).toString()); 
 
} 
 

 
function parseCSV(string) { 
 

 
    var data = []; 
 

 
    // first get the number of lines: 
 

 
    var lines = string.split('\n'); 
 

 
    // now split the first line to retrieve the headings 
 

 
    var headings = lines[0].split(","); 
 
    var cols = headings.length; 
 

 
    // now get the data 
 

 
    var rows=0; 
 
    for(var i=1;i<lines.length;i++) { 
 
     if(lines[i].length>0) { 
 
      data[rows] = lines[i].split(","); 
 
      rows++; 
 
     } 
 
    } 
 

 
    // now, fill in the blanks - start by finding the first value for each column of data 
 

 
    var vals = []; 
 
    var times = []; 
 

 
    for(var j=1;j<cols;j++) { 
 
     var index = findNextValueIndex(data,j,0); 
 
     vals[j] = parseFloat(data[index][j]); 
 
    } 
 

 
    // now put those start values at the beginning of the array 
 
    // there is no way to calculate the previous value of the sensor missing from the first sample 
 
    // so we use the first reading and duplicate it 
 
    for(var j=1;j<cols;j++) { 
 
     data[0][j] = vals[j].toString(); 
 
     times[j] = parseInt(data[0][0]); 
 
    } 
 

 
    // now step through the rows and interpolate the missing values 
 
    for(var i=1;i<rows;i++) { 
 
     for(var j=1;j<cols;j++) { 
 
      if(data[i][j].length>0) { 
 
       vals[j] = parseFloat(data[i][j]); 
 
       times[j] = parseInt(data[i][0]); 
 
      } 
 
      else { 
 
       var index = findNextValueIndex(data,j,i); 
 
       if(index<0) // no more data in this column 
 
        data[i][j] = vals[j].toString(); 
 
       else 
 
        data[i][j] = interpolate(times[j],parseInt(data[index][0]),parseInt(data[i][0]),vals[j],data[index][j]); 
 
      } 
 
     }   
 
    } 
 
    // now convert from strings to integers and floats so dygraph can handle it 
 
    // I've also changed the time value so that it is relative to the first element 
 
    // it will be shown in milliseconds 
 
    var time0 = parseInt(data[0][0]); 
 
    for(var i=0;i<rows;i++) { 
 
     data[i][0] = parseInt(data[i][0]) - time0; 
 
     for(var j=1;j<cols;j++) { 
 
      data[i][j] = parseFloat(data[i][j]);   
 
     } 
 
    } 
 
    var obj = { 
 
     labels: headings, 
 
     data: data 
 
    } 
 

 
    return(obj); 
 
} 
 

 
window.onload = function() { 
 

 
    var data_obj = parseCSV(document.getElementById('csvdata').innerHTML); 
 

 

 
     new Dygraph(
 
     document.getElementById('graph'), data_obj.data, 
 
     { 
 
      labels: data_obj.labels, 
 
      connectSeparatedPoints: true, 
 
      drawPoints: true 
 
     } 
 
    ); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.0.0/dygraph.js"></script> 
 
<div id="graph" style="height:200px;"></div> 
 

 
<pre id="csvdata" style="display:none"> 
 
TIME,LH_Fuel_Qty,L_Left_Sensor_NP 
 
1488801288048,,1.4411650490795007 
 
1488801288064,0.478965502446834, 
 
1488801288133,,0.6372882768113235 
 
1488801288139,1.131315227899919, 
 
1488801288190,1.847605177130475, 
 
1488801288207,,0.49655791428536067 
 
1488801288258,0.45488168748987334, 
 
1488801288288,,1.3756073145270766 
 
1488801288322,0.5636921255908185, 
 
1488801288358,,1.1193344122758362 
 
</pre>

+0

本当にありがとうございましたが、@fmacdee。主な問題は、私は、それぞれが何百万というデータ値を持つ信号を持っているということです。 5つの信号があり、異なる信号の値の大部分がタイムスタンプを共有していないとすると、各信号にx5値のデータを挿入しなければならず、5つの新しい信号にそれぞれ5百万のデータ値があります。これは、チャートとブラウザの大きなオーバーロードを意味します。私は、特定の瞬間に選択されたタイムスタンプ上の補間しか計算できないアドホックな解を見つけようとしています。 –

+0

最初のグラフへのウィンドウである2番目のグラフを生成することを検討しますか?それはあなたが拡大された領域にあるポイントのサブセットについてのみ補間することができます... – fmacdee

+0

また、プラグインを使用してこれを一般的に作成することもできます。https://rstudio.github.io/dygraphs/gallery-plugins.html – fmacdee

0

をい10

必要なものはありませんか?

+0

ありがとう@Nick。私は実際にその設定を使用しています。実際には、グラフとcsvをチェックすると、信号値にギャップがありますが、グラフにはギャップがなくグラフが表示されます。私が直面している問題(補間とは別に)は、値がないときに未定義のラベルが表示されていないということです。 –

関連する問題