2016-08-05 7 views
3

2次元ヒートマップを作成しています。これは、ピクセルをクリックすると機能があります。これは、すべてのピクセル(、隣接ピクセルを含む)のインデックスに関連付けられたデータを取得し、それをプロットします。これは、現在、次のようになります。私は、左または右のエッジ画素をクリックしたときに、隣接する画素からのデータをつかむため、私が遭遇してるJavascriptで1次元配列のエッジケースを特定する

enter image description here

問題は、ある、それは反対側からデータを取り出すことができますグラフはすべて1次元配列内にあるためです。私は、クリックされたピクセルが端の場合であるかどうかをチェックし、拡大されたグラフをメイングラフの反対側からの点を表示しないように構成する条件を作成しようとしています。私は2次元配列を持っていたかのように同じ結果を取得しようとし、単一のアレイ内の隣接する値が定義されていない時に発見しています

// pushes all dataMagnified arrays left and right of i to magMainStore 
var dataGrabber = function(indexGrabbed, arrayPushed) { 

    // iterates through all 5 pixels being selected 
    for (var b = -2; b <= 2; b++) { 

    var divValue = toString(i/cropLength + b); 

    // checks if selected index exists, and if it is not in the prior row, or if it is equal to zero 
    if (dataMagnified[indexGrabbed + b] != undefined && (& divValue.indexOf(".")!=-1)) { 
     dataMagnified[indexGrabbed + b].forEach(function(z) { 
     arrayPushed.push(z); 
     }) 
    } 
    } 
}; 

:これは私がこれまで持っているコードです。これは私がその条件を作成している行です。

if (dataMagnified[indexGrabbed + b] != undefined && (& divValue.indexOf(".")!=-1)) { 

これまでの2番目の条件はこれを理解しようとしています。 5回繰り返すforループや、これに対して複数の条件を作成しなければならない場合でも、これを行うことができるのかどうかは不明です。また、ここで私が何をしようとしている画像表示です:

enter image description here

ありがとうございました!

+0

を[ここで全体のコードベースがあります](https://github.com/AstroBoogie/BL-files/blob/master/BL_waterfall /js/backup.js)変数が不明な場合。 – AstroBoogie

+0

320x200x256グラフィックスの1d arryを使用すると、画面の左端にあるピクセルのインデックスは0,320,640,960です。つまり、右側のピクセルは幅1、(2 *幅)-1、したがって、[width-1..width]のインデックスには注意が必要です。ループ・アンローリングは、コンパイラが(しばしば)適用する最適化です。彼らは速く(同じまたはほぼ同じコードを繰り返す)コードを実行するためのコード(ループ)を読み書きするように素早く切り替わります。 – enhzflep

+0

@enhzflepだから私は自分の考えを[擬似コードとして]整理したと思うが(http://pastebin.com/cDriBUb5)、残りのforループでどのように実装するのか分からない。すべてのために個別のif文を作成するか、それを行うより良い方法がありますか?また、私はループアンローリングが何であるかは分かりません。ループアンローリングを実装すべきか、それともJSが単独で行うのですか? – AstroBoogie

答えて

1

あなたのアプローチは非常に複雑に見え、やや遅く実行されます。たとえば、数値を文字列に変換して、.indexOf()を使用して整数値をチェックするために小数点を見つけることは正しくないと思われます。

はるかに簡単でよりエレガントな解決策は、行の制限によって囲まれた選択範囲戻ります次の関数である可能性があります可能な限り柔軟に保つために、ここで

function getBoundedSelection(indexGrabbed, selectionWidth) { 
    return dataMagnified.slice(
    Math.max(Math.floor(indexGrabbed/cropLength) * cropLength, indexGrabbed - selectionWidth), 
    Math.min(rowStartIndex + cropLength, indexGrabbed + selectionWidth) 
); 
} 

selectionWidthを判定する選択した範囲の幅をindexGrabbedのいずれかの側に設定します。あなたの場合はになります。これは、私はそれを壊れていないものの説明として

function getBoundedSelection(indexGrabbed, selectionWidth) { 
    // Calculate the row indexGrabbed is on. 
    var row = Math.floor(indexGrabbed/cropLength); 

    // Determine the first index on that row. 
    var rowStartIndex = row * cropLength; 

    // Get the start index of the selection range or the start of the row, 
    // whatever is larger. 
    var selStartIndex = Math.max(rowStartIndex, indexGrabbed - selectionWidth); 

    // Determine the last index on that row 
    var rowEndIndex = rowStartIndex + cropLength; 

    // Get the end index of the selection range or the end of the row, 
    //whatever is smaller. 
    var selEndIndex = Math.min(rowEndIndex, indexGrabbed + selectionWidth); 

    // Return the slice bounded by the row's limits. 
    return dataMagnified.slice(selStartIndex, selEndIndex); 
} 
+0

エレガントなソリューション!私はそれを考えなかっただろう。どうもありがとうございました。 – AstroBoogie

1

だから私は、クリックした位置の結果がためのループで変数の開始と終了位置を作成しますので、次のように、これを行うための唯一の方法だったことを発見:

私は同じことを始めました。すべてのコードは、1つの関数にネストされている:

var dataGrabber = function(indexGrabbed, arrayPushed) { 

私は、引数として始点と終点をとる第2の機能を作成し、その後、ループのための出発点と終了条件としてそれらを渡します。

var magnifyCondition = function (start, end) { 
    for (var b = start; b <= end; b++) { 
     if (dataMagnified[indexGrabbed + b] != undefined) { 
      dataMagnified[indexGrabbed + b].forEach(function (z) { 
       arrayPushed.push(z); 
      }) 
     } 
    } 
}; 

はその後、私は開始から5つの独立した条件文を作成し、エンドポイントを簡単に反復処理することはできません。

if (((indexGrabbed - 1)/cropLength).toString().indexOf(".") == -1) { 
     magnifyCondition(-1, 2); 
    } 
    else if ((indexGrabbed/cropLength).toString().indexOf(".") == -1) { 
     magnifyCondition(0, 2); 
    } 
    else if (((indexGrabbed + 1)/cropLength).toString().indexOf(".") == -1) { 
     magnifyCondition(-2, 0); 
    } 
    else if (((indexGrabbed + 2)/cropLength).toString().indexOf(".") == -1) { 
     magnifyCondition(-2, 1); 
    } 
    else { 
     magnifyCondition(-2, 2); 
    } 
}; 

最後に、私は私のclicクリック上の(インデックスはつかんで合格しますked関数)と、値が格納される任意の配列。代わりに、if文のより良い方法がある場合

dataGrabber(i, magMainStore); 

は、私に知らせてくださいと私は将来的に、より良い、それを整理させていただきます!

関連する問題