3
\$\begingroup\$

The code takes in nodes with different start time as input and assigns the position such that they will not overlap. As I have coded with too many loops and conditions. Can anyone review the code and help me to make it efficient? Please do review the algorithm to assign positions to the rectangular blocks.

<html>
  <head>
     <style> 
     </style>
     <script type="text/javascript" src="d3.v3.min.js?n=1"></script>
     <script type="text/javascript" src="jquery-2.0.3.min.js?n=1"></script>
  </head>
  <body>
     <div id= "chart1"></div>
     <div id= "chart2"></div>
     <div id= "chart3"></div>
     <div id= "chart4"></div>
     <script>

     var margin = {top: 50, right: 20, bottom: 20, left: 10},
     w = 400 - margin.left - margin.right,
     h = 200 - margin.top - margin.bottom;

     var nodes = [{"id":0, "start":10 , "stop":40, "total":30},
                  {"id":1, "start":40 , "stop":80, "total":40},
                  {"id":2, "start":100 , "stop":150, "total":50},
                  {"id":3, "start":120 , "stop":150, "total":30},
                  {"id":4, "start":140 , "stop":160, "total":20}];

     var flag_move = 1;

     svg = d3.select("#chart1").append("svg")
      .attr("width", w + margin.left + margin.right)
      .attr("height", h + margin.top + margin.bottom)
     .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

       nodes.forEach(function(d){
           d.y = 30 * d.id;
       });

       svg.append("svg:g")
         .attr("class","nodes")
         .selectAll("rect")
        .data(nodes)
         .enter().append("svg:rect")
         .style("fill", "blue")
         .style("opacity",0.5)
         .attr("width",function(d) { return (d.total); })
         .attr("height", "20")
         .attr("x",function(d) { return (d.start); })
         .attr("y",function(d) { return (d.y); });


     // different approach

      updated_pos_mat = [];

      nodes.forEach(function(d){
         updated_pos_mat.push([d.id]);
    });

   //pass1

      var pass = updated_pos_mat.length - 1;

      while ( pass != 0){

      console.log( "At " + (3-pass) + " pass");

      var removed = 0;

      for( var i=1;i<updated_pos_mat.length;i++){

      temp_ival = updated_pos_mat[i];

      console.log(" Before comaparison, at iteration " + i + " : " + " Updated position matrix is");
      console.log(updated_pos_mat);

      for(var j=0;j<updated_pos_mat.length;j++){
        temp_jval = updated_pos_mat[j];

         if(i != j && i>j && (i-j == 1)){

           if((temp_ival.length == 1) && (temp_jval.length == 1)){

              if(nodes[temp_ival[0]].start > nodes[temp_jval[0]].stop){

                 console.log("Push the node " + nodes[temp_ival[0]].id + " a level above");

                 updated_pos_mat[j].push(nodes[temp_ival[0]].id);

                 console.log("After pushing the data update matrix is:");
                 console.log(updated_pos_mat);

                 break;
              }     
           }

           if((temp_ival.length != 1) && (temp_jval.length == 1)){

              for(var k = 0; k< temp_ival.length; k++){

                 if(nodes[temp_ival[k]].start > nodes[temp_jval[0]].stop){

                    console.log("Push the node " + nodes[temp_ival[k]].id + " a level above");

                    updated_pos_mat[j].push(nodes[temp_ival[k]].id);

                    break;
                 }

              }

            } 

            if((temp_ival.length == 1) && (temp_jval.length != 1)){

              temp_arr = [];

              for(var k = 0; k< temp_jval.length; k++){

                 if(nodes[temp_ival[0]].start > nodes[temp_jval[k]].stop){

                    temp_arr.push(1);

                    //updated_pos_mat[j].push(nodes[temp_ival[0]].id);

                    //break;
                 }

              }

              temp_arr_sum = temp_arr.reduce(function (a, b) {
                  return a + b;
                 }, 0);

                if(temp_arr_sum == temp_jval.length){

                    console.log("Push the node " + nodes[temp_ival[0]].id + " a level above");              

                    updated_pos_mat[j].push(nodes[temp_ival[0]].id);             
                }

            } 

            if((temp_ival.length != 1) && (temp_jval.length != 1)){

              for(var k = 0; k< temp_ival.length; k++){

                 temp_arr = [];

                 for(var l = 0; l< temp_jval.length; l++){

                      if(nodes[temp_ival[k]].start > nodes[temp_jval[l]].stop){

                        //updated_pos_mat[j].push(nodes[temp_ival[k]].id);

                        //break;
                     }

                 }

                temp_arr_sum = temp_arr.reduce(function (a, b) {
                  return a + b;
                 }, 0);

                if(temp_arr_sum == temp_jval.length){

                    console.log("Push the node " + nodes[temp_ival[k]].id + " a level above");

                    updated_pos_mat[j].push(nodes[temp_ival[k]].id);             
                }

              }
            } 

         }
      }

      console.log(" After comparison, at iteration " + i + " : " + " Updated position matrix is");
      console.log(updated_pos_mat);
    }

    for(var u = 1; u<updated_pos_mat.length; u++){

        var temp_val =  updated_pos_mat[u];
        var temp_valp = updated_pos_mat[u-1];

        for(var v = 0; v < temp_val.length; v++){

            for(var s = 0; s < temp_valp.length; s++){

               if( temp_val[v] == temp_valp[s]){

                  updated_pos_mat[u].splice(v,1);

               }

            }
        }

    }

    for(var i = 0; i<updated_pos_mat.length; i++){

         //console.log(updated_pos_mat[i].length);

         if(updated_pos_mat[i].length == 0){

              //console.log("removing the empty array");

              updated_pos_mat.splice(i,1);

         }

    }

    pass--;

    }

    console.log(updated_pos_mat);

    pass1_y = 0;

       updated_pos_mat.forEach(function(d){

          val = d;  

          if(val.length > 1){

             //console.log("reached  if loop");

             for(var i=0;i<val.length;i++){

               //console.log("reached  for loop");

               i_val = val[i];

               nodes[i_val].y = pass1_y;
             }  

          }else {

              //console.log("reached  else  loop");

              nodes[val[0]].y = pass1_y;

          }

          pass1_y = pass1_y + 30;

       })

     console.log(nodes);

     svg_1 = d3.select("#chart2").append("svg")
      .attr("width", w + margin.left + margin.right)
      .attr("height", h + margin.top + margin.bottom)
     .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

       svg_1.append("svg:g")
         .attr("class","nodes")
         .selectAll("rect")
        .data(nodes)
         .enter().append("svg:rect")
         .style("fill", "blue")
         .style("opacity",0.5)
         .attr("width",function(d) { return (d.total); })
         .attr("height", "20")
         .attr("x",function(d) { return (d.start); })
         .attr("y",function(d) { return (d.y); });

     </script>
  </body>
</html> 
\$\endgroup\$
2
\$\begingroup\$

From a once over:

  • console.log() <- Performance killer, at the very least call a custom function that you can uncomment
  • //updated_pos_mat[j].push(nodes[temp_ival[0]].id); <- Remove dead code for easier reading
  • temp_arr.reduce( <- While cool, it is far slower than an old skool loop
  • From a readability perspective, you have too many 1 char variable names, and your indenting is a mess, making it hard to grok your code and find conceptual problems with the code.

Once you remove the log() calls, the reduce() calls , the dead code and renamed the variables, you should definitely repost the code if it is still too slow.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.