Сокращение повторяющегося (но длинного) кода

Я просмотрел различные посты по сокращению кода, но мне трудно применить его к моему коду. Я все еще на уровне новичка, и я просто не знаю, как начать.

У меня есть функция, которую нужно будет повторить 40 раз. Я загрузил экран печати из того, что делает моя функция, которая находится в jQuery с плагином jqPlot.

Он отображает два ряда данных, и пользователь может щелкнуть график, чтобы указать, что, по его мнению, станет следующей точкой данных во временном ряду.

Каждый пользователь получит 40 таких графиков. Код, который у меня сейчас есть, представляет собой функцию, которая отображает только график 1. Мне пришлось бы зациклить его, чтобы он отображал все 40 графиков (40 различных временных рядов), но в разном порядке для каждого пользователя (рандомизированный). Моя первая проблема, однако, состоит в том, чтобы заставить это повторяться без использования повторяющегося кода.Пример графика

изменить: на основе реакции супер-Qua у меня есть следующий код:

Я определяю следующие глобальные переменные (на данный момент я ограничил себя тремя рядами данных, сокращенное представление)

var index;
var promo1 = [0,81,102,..];
var s1 = [[0,301.961878917828],[1,287.301563144611],..,[50,285.689751451376]];
var promo2 = [0,184,0,..];
var s2 = [[0,286.723878917828],[1,444.439356046045]..,[50,323.874367563812]];
var promo3 = [0,196,0,..];
var s3 = [[0,250.478609608828],[1,416.973663811716],..,[50,335.79777763802]];

это моя функция "Run"

var Run = function(){
    // create divs
 var graph = $('<div id="GRAPH' +index +'"><h4> Click on the graph to indicate the expected sales numbers for time period 51 and 52 (in that order). </h4></div>');
 var chart = $('<div id="chart' +index +'" style="width:800px;height:450px"></div>');
 var info = $('<div id="info' +index +'"></div>');
 var proceed = $('<div id="proceed'+index+'"><b>To change your forecast</b>, simply click on the graph. </p><p> <b>To save your forecast</b>, click the button below. </p><p> <button type="button" id="save1">Save forecast for time period 51</button> </p><p> <button type="button" id="submit">Submit my forecast</button> </p>');
 // append them to the graph div
 $(chart).appendTo(graph);
 $(info).appendTo(graph);
 $(proceed).appendTo(graph);
 var promo = $(promo+index);
 var s = $(s+index);
 $(plot).appendTo(chart);

 var plot = $.jqplot('chart'+index, [promo[index], s[index]], {
        stackSeries: false,
        series: [
        {label:'Promotions',
            renderer:$.jqplot.BarRenderer,
            rendererOptions: {
                barMargin: 12,
                barPadding: 0
                }
        },
        {label:'Sales', renderer:$.jqplot.LineRenderer, color:'grey', lineWidth: 2},
        ,
    {}
    ],   
            axesDefaults: {
                tickRenderer: $.jqplot.CanvasAxisTickRenderer,
                tickOptions: {
                angle: 0,
                fontSize: '8pt'

                }
                },
            axes: {
            xaxis: {
                tickInterval : 1,

                min: 0,
                max: 55
        },
            yaxis: {
                autoscale: true,
                min: 0
            }
        },
            cursor: {
                show: true,
                followMouse: true
            },
            legend: {
                renderer: $.jqplot.EnhancedLegendRenderer.min , 
                show: true,
                location: 'ne',
                placement: 'outside',
                marginRight: '50px'
            }
        });

 $(chart).bind('jqplotClick', function(event, seriesIndex, pointIndex, data) {
 xax51_s = pointIndex.xaxis; 
 yax51_s = pointIndex.yaxis;
s[index].push([pointIndex.xaxis,pointIndex.yaxis]);
console.log("Seriesnr" +index + xax51_s + " - " + yax51_s);
myDataRef.push("Seriesnr" +index + xax51_s + " - " + yax51_s);
if (Math.round(xax51_s1) === 51) {
    $('#info1').html("Your sales forecast for time period 51 is " + Math.round(yax51_s1) + " units.");
    $('#proceed1').show();
    $('#submit1').hide();
    //add new datapoint and renew dataserie s1
    plot1.series[1].data = [[0,301.961878917828],[1,287.301563144611],[2,333.856817030694],..[50,285.689751451376],[xax51_s1,yax51_s1]];
    //fill in replot/redraw!
    plot1.drawSeries({},1); 
}
//if they click outside of the 51st time period:
else {
   alert("Please click on the correct grid line (period 51)"); 
}
 });

  $(graph).appendTo('body');
};  

Остальная часть jquery остается простой и включает цикл:

$('div').hide();
   $("#INTRO").show();
   $("#Start").click(function(){
       $("#INTRO").hide();
       for(var index=0; index<4; index++){
         Run(index);

У меня сейчас проблема в том, что он ничего не делает. Я получаю пустую страницу, указывающую, что div не работают. Я должен увидеть заголовок, созданный для div "GRAPH", но он не отображается. Я также получаю сообщение от jqplot о том, что цель графика не указана, хотя это указано как "график". Возможно, это также потому, что div не создаются.

2 ответа

Решение

Захват и обновление ответа Super-Qua.

var promo = [], s = [];
for (i = 1; i < 41; i++) { //assuming that promo# and s# are both global variables.
    promo[i] = window["promo"+i];
    s[i] = window["s"+i];
}
var Run = function(index){
 // create your divs
 var graph = $('<div id="GRAPH' +index +'"><h4> Click on the graph to indicate the expected sales numbers for time period 51 and 52 (in that order). </h4></div>');
 var chart = $('<div id="chart' +index +'" style="width:800px;height:450px"></div>');
 var info = $('<div id="info' +index +'"></div>');

 // append them to the graph div
 $(chart).appendTo(graph);
 $(info).appendTo(graph);
 // add your proceed div the same way

 var plot = $.jqplot('chart' +index, [promo[index], s[index]], {
 //(I have taken out all the settings here for the series so it doesn't get too messy) 

 $(chart).bind('jqplotClick', function(event, seriesIndex, pointIndex, data) {
 xax51_s = pointIndex.xaxis; // if you need to store the information for later use an array as well with xax51_s.push(pointIndex.xaxis)
 yax51_s = pointIndex.yaxis;

  // ... the rest of your code goes here

  // finally append the graph div to your DOM
  $(graph).appendTo('body') // replace body with whatever your element container is
}

Я могу только сказать, что если.jqplot нужно, чтобы div-ы уже отображались на странице, это не сработает, если только вы не визуализируете все divs/charts/info в одном и том же цикле, но скрываете их иначе.

Есть много возможностей для достижения этой цели. Я бы пошел с функцией, которая принимает индекс в качестве параметра, создает для вас div и добавляет его в dom. Если вы можете, вы должны использовать массивы для ваших данных, как promo а также s,

Это может выглядеть примерно так (не проверено - и просто для того, чтобы дать вам представление. Поэтому я оставлю некоторые вещи):

var Run = function(index){
     // create your divs
     var graph = $('<div id="GRAPH' +index +'"><h4> Click on the graph to indicate the expected sales numbers for time period 51 and 52 (in that order). </h4></div>');
     var chart = $('<div id="chart' +index +'" style="width:800px;height:450px"></div>');
     var info = $('<div id="info' +index +'"></div>');

     // append them to the graph div
     $(chart).appendTo(graph);
     $(info).appendTo(graph);
     // add your proceed div the same way

     // finally append the graph div to your DOM
     $(graph).appendTo('body') // replace body with whatever your element container is

     var plot = $.jqplot('chart' +index, [promo[index], s[index]], {
     //(I have taken out all the settings here for the series so it doesn't get too messy) 

     $(chart).bind('jqplotClick', function(event, seriesIndex, pointIndex, data) {
     xax51_s = pointIndex.xaxis; // if you need to store the information for later use an array as well with xax51_s.push(pointIndex.xaxis)
     yax51_s = pointIndex.yaxis;

      // ... the rest of your code goes here

Вы можете запустить это 40 раз в простой цикл. Например

for(var i=0; i<40; i++){
   Run(i);
}

Примечание: я не знаю о jqplot, но вам может понадобиться добавить график перед созданием графика.

Надеюсь это поможет.

ОБНОВИТЬ:

Как обновлено выше, переместите $(graph).appendTo('body') перед $.jqplot линия

Вот как должны выглядеть ваши массивы

  var promo = [[0,81,102], [0,184,0], [0,196,0]];
  var s = [[[0,301.961878917828],[1,287.301563144611],[50,285.689751451376]], [[0,286.723878917828],[1,444.439356046045],[50,323.874367563812]], [[0,250.478609608828],[1,416.973663811716],[50,335.79777763802]]];

Затем я заметил еще две вещи:

  • У вас слишком много запятой после строки {label:'Sales', renderer:$.jqplot.LineRenderer, color:'grey', lineWidth: 2},
  • Избавиться от var promo = $(promo+index); - потому что у вас уже есть промо
Другие вопросы по тегам