У меня есть большие данные для обработки. Их нужно классифицировать на 4 цвета и отображать в SVG.
Моя функция: (параметр ABC используется для чего-то...)
function mapRender(dataArray,A,B,color1,color2,color3,color4,C){
//......do somthing.......
var colorPlusAry = $.grep(dataArray, function(item,key){
var vote_percentage = parseInt(item.vote_percentage);
var result = vote_percentage>=0 && vote_percentage <50;
return result;
});
//......do somthing.......
}
Я использую grep для генерации нового массива, который имеет тот же цвет, и визуализацию в SVG.
function colorDistrict(colorArray,color){
var village = '';
var fillColor = 'fill:'+color;
for(var item in colorArray) {
village = colorArray[item].village;
$('svg').find('path').each(function(){
var id = $(this).attr('id');
if(village) {
if(id.substring(6) === village){
$(this).attr('style',fillColor);
}
}
});
}
}
colorDistrict(colorPlusAry,color1); //Render 4 array
Он работает успешно, но данные слишком велики и делают рендер медленно, когда я запускаю функцию, требуется несколько секунд, чтобы реагировать... Как я могу оптимизировать эту функцию для рендеринга цвета?
Оптимизация - сложный бизнес без реальных данных и без знания точной структуры DOM. Я могу только дать некоторые намеки на то, что я вижу:
Дорогостоящий процесс взаимодействует с DOM. Глядя на colorDistrict()
, две циклы кажутся независимыми. Тогда было бы целесообразно запустить .each()
только один раз, а цикл над colorArray
как вложенный. Последний содержит только предварительно вычисленные значения и должен работать намного быстрее.
Глядя на то, что эти циклы действительно делают, вы можете написать их гораздо более семантично. Вы сравниваете коллекцию всех путей и colorArray
для пересечения, а затем присваиваете стиль фильтрованному списку путей.
function colorDistrict (colorArray, color){
var fillColor = 'fill:' + color;
// filter the paths to find those mentioned in colorArray
var relevantPaths = $('svg').find('path').filter(function () {
var village = $(this).attr('id').substring(6);
// boolean to indicate the village is part of the colorArray
var included = colorArray.some(function (item) {
return item.village === village;
});
return included;
});
relevantPaths.attr('style', fillColor);
}
Если я правильно понимаю, что вы делаете, colorDistrict()
выполняется несколько раз, один раз для каждого назначаемого вами цвета. Изменены ли элементы <path>
между рендерингом разных цветов? Если нет, вы должны выполнить $('svg').find('path')
только один раз и кэшировать найденные пути для повторного использования внутри этой функции.
var paths = $('svg').find('path');
function colorDistrict (colorArray, color){
var fillColor = 'fill:' + color;
var relevantPaths = paths.filter(function () {
...
});
}
dataArray
иcolorArray
? а как вы называетеcolorDistrict
?