第一次发布海报,仅略高于 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 并稍后以某种方式定位它们以更改填充属性?)
这是我如何让它工作的:
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. 因为我试图创建一个实际上是数组的变量数组,所以我似乎将数组的值(而不是数组的占位符)推送到主数组中。也许我需要对象来做到这一点?
非常感谢您提供的任何帮助!
更新
特别感谢大卫。我终于让它工作了。我必须弄清楚的一个技巧:
大卫建议我做以下事情:
var selectedStates = selected.map(function() { return stateArrays[this]; });
花了一些研究,但我发现我需要双重包装我的返回值,否则整个数组将作为一个 concat 推送。所以,这行得通:
var selectedStates = selected.map(function() { return [stateArrays[this]]; });
之后,我只需要按照他的建议遍历数组数组。虽然,我从来没有得到 pop(); 出于某种原因工作。所以,我只是使用 selectedStates[0] 作为交集工具的第一个数组。
再次感谢大卫!
结束更新