初めてのポスターで、JavaScript/jQuery/Raphael の初心者をわずかに上回っています。違反を許してください。:)
それで、私は自分の質問に対する答えを高低を調べて、いくつかの有望な手がかりを見つけましたが、私のプログラミングスキルはあまりにも環境に優しく、すべてをまとめることができません. 私は Raphael と一緒にインタラクティブな米国の地図を作成し、さまざまな基準に基づいて最終的に州を強調表示する 13 個のチェック ボックスのセットをユーザーに提供しています。各チェック ボックスは、約 3 ~ 15 の状態 (もちろんすべてのパス) に関連付けられています。ユーザーがいくつかのチェック ボックスを選択すると、配列の交点を見つけて、それらの状態のみを強調表示する必要があります。例えば:
<input id="a1" value="arr1" type="checkbox" />
<input id="a2" value="arr2" type="checkbox" />
<input id="a3" value="arr3" type="checkbox" />
<input id="a4" value="arr4" type="checkbox" />
<input id="a5" value="arr5" type="checkbox" />
arr1 = [a,b,c];
arr2 = [b,c,d];
arr3 = [b,c,e];
arr4 = [a,e];
arr5 = [a,b];
たとえば、ユーザーが a1、a2、および a3 を選択した場合、交点用に別の配列を作成し (たとえば intArr = [b,c])、適切な Raphael の塗りつぶしの色を変更します。パス。
ここで見つけた巧妙な交差関数のおかげで、力ずくでこれを解決することができました。しかし、より洗練されたソリューションでは、文字通り約 100 行のコードを節約できます。ユーザーの選択に基づいて配列 (またはオブジェクト?) の配列を作成し、それを反復して最初の配列を比較する必要があると思います。マスター配列内のその他。問題があります。配列をすべて Raphael 要素変数にする必要があると思います。(各要素に id を与え、後で fill 属性を変更するためにそれらをターゲットにする必要がある場合を除きますか?)
これが私がそれを機能させる方法です:
var selectedStates = new Array();
var arr1 = new Array(stArr1,stArr2,stArr3,stArr4,stArr5,stArr6);
var arr2 = new Array(stArr2,stArr3,stArr7,stArr9);
// etc.
var arr1Sel = false;
var arr2Sel = false;
// etc.
$('#selecttools input').click(function(){
// reset all global variables for each feature
arr1Sel = false;
arr2Sel = false;
// etc.
// find checked boxes and set appropriate globals to true
$('#selecttools').find(":checked").each(function() {
if ($(this).val() == 'arr1') { arr1Sel = true; }
if ($(this).val() == 'arr2') { arr2Sel = true; }
//etc.
// now run selectTheStates
selectTheStates();
});
function selectTheStates() {
// first reset selectedStates with the default fill color
for (var i = 0; i < selectedStates.length; i++) {
selectedStates[i].attr({fill: "#CCB2E5"});
}
// setup the intersect filter
// thank so much, love this one http://jsfiddle.net/i_like_robots/KpCt2/
$.arrayIntersect = function(a, b) {
return $.grep(a, function(i) {
return $.inArray(i, b) > -1;
});
}
// first make a list of selected arrays
var ourFinalList = new Array();
// now, the real brute force...nested if statements that have to go!
if (arr1Sel == true) {
ourFinalList = arr1;
if (arr2Sel == true) { ourFinalList = $.arrayIntersect(ourFinalList,arr2) }
if (arr3Sel == true) { ourFinalList = $.arrayIntersect(ourFinalList,arr3) }
// etc.
} else if (arr2Sel == true) {
ourFinalList = arr2;
if (arr3Sel == true) { ourFinalList = $.arrayIntersect(ourFinalList,arr3) }
// etc. lots of nesting here, yuck!
} else if (arr13Sel == true) {
ourFinalList = arr13;
}
// now paint all the states in our final list with Raphael
for (var i = 0; i < ourFinalList.length; i++) {
ourFinalList[i].attr({fill: "#B38CD8"});
}
// last step is reset selectedStates
selectedStates = ourFinalList;
// end selectTheStates
}
信じられないかもしれませんが、これは機能します。しかし、コードは非常に肥大化しており、非常に素人っぽく見えるため、ここに投稿することさえ恥ずかしく思います。しかし、私は本当にこれを行う方法を学びたいです! 助けてください。
配列の配列を作成し、その配列の最初の配列を見つけて、配列内にある他の配列と比較/交差する必要があると思います。ただし、これを実行しようとすると、いくつかの問題に遭遇しました。1.実際には配列である変数の配列を作成しようとしているため、配列の値 (配列のプレースホルダーではなく) をマスター配列にプッシュしているように見えます。たぶん、これを行うにはオブジェクトが必要ですか?
あなたが提供できる助けをありがとう!
アップデート
デビッドに感謝します。私はついにそれを働かせました。私が理解しなければならなかった1つのトリック:
デビッドは私が次のことをすることを提案しました:
var selectedStates = selected.map(function() { return stateArrays[this]; });
いくつかの調査が必要でしたが、戻り値を二重にラップする必要があることがわかりました。そうしないと、配列全体が連結としてプッシュされます。したがって、これは機能しました:
var selectedStates = selected.map(function() { return [stateArrays[this]]; });
その後、彼が提案したように、配列の配列を反復処理する必要がありました。ただし、 pop(); を取得したことはありません。なぜか働くこと。そのため、交差ツールの最初の配列として selectedStates[0] を使用しました。
どうもありがとう、デビッド!
更新を終了