12 Replies Latest reply on Dec 28, 2011 3:48 AM by csm_phil

    Selected Object Group row wise or column wise in javascript

    csm_phil Level 4

      Hi Scripter All

       

      I want to group my selected object row/column wise it is possible to achieve this using javascript if yes, please give your input ow? to do? It is possible please see the below snapshots.

       

      This snapshot is my selected object not grouping in row wise.

      ,Picture 2.png

       

      This output is after  grouped in row wise see the below snapshot. this is i m done is manually. But i need to do this in javascript.

       

      Picture 3.png

       

      Please help any one have idea or technical methods i want this output using javascript.

       

      thx

      csm_phil

        • 1. Re: Selected Object Group row wise or column wise in javascript
          John Hawkinson Level 5

          You've got to do it the hard way. Go through your objects, worry about whether they overlap, and find the boundaries the define the sets, and then group them. I think you might find a basic computer graphics textbook helpful here.

          • 2. Re: Selected Object Group row wise or column wise in javascript
            csm_phil Level 4

            Hi John,

             

            First, thanks for looking my problem.

             

             

            Can you please explain brief, how to get the group in row wise,I am not clear, And also you mentioned basic computer graphics textbook helpful here, where i  get this book.

             

            It is possible to achieve my requirement.

             

            Please help me i am waiting for your reply

             

            thx

            csm_phil

            • 3. Re: Selected Object Group row wise or column wise in javascript
              John Hawkinson Level 5

              Can you please explain brief, how to get the group in row wise,I am not clear,

              You have to compare the geometricBounds of each and every box in order to sort them into rows. This is really a pain.

               

              And also you mentioned basic computer graphics textbook helpful here, where i  get this book.

              This is not my area, I can't give you a reference. Try google. You'll have to spend some time at it.

               

              It is possible to achieve my requirement.

              That's a very good question. If you were doing it from scratch I'd suspect it would take you several days-weeks of work. But if you're lucky you can find someone else's algorithm that solves this. (But I may be too pessimistic!)

               

              It's well worth thinking that it is not worth it and just giving up though. We'll see what other people say.

              • 4. Re: Selected Object Group row wise or column wise in javascript
                John Hawkinson Level 5

                This is not my area, I can't give you a reference. Try google. You'll have to spend some time at it.

                See, for instance, Don Wakefield's answer (the 2nd one) at http://stackoverflow.com/questions/289779/calculating-a-boundary-around-several-linked-rec tangles. There is a textbook citation.

                 

                This is not the same question, but is a related problem.

                1 person found this helpful
                • 5. Re: Selected Object Group row wise or column wise in javascript
                  [Jongware] Most Valuable Participant

                  The scanline suggestion in there, using only the vertical position of each vertex, should work just nice. To visualize what the algorithm should do, select *all* of your objects and use "Align Horizontal Centres".

                   

                  (I now realize a *very* brute force approach would be to align the centres by script, add everything up with the pathfinder, and examining the leftovers.)

                  • 6. Re: Selected Object Group row wise or column wise in javascript
                    [Jongware] Most Valuable Participant

                    (After 10 minutes of pondering.) Sort by vertical top position (also store vertical bottom position). Then examine this array for overlaps. Any consecutive run of objects should be in one group.

                     

                    Actual implementation will be left to the OP as an exercise.

                    • 7. Re: Selected Object Group row wise or column wise in javascript
                      absqua Level 4

                      I think I'm missing something. Why do we care about overlaps? I've done a hacky version of this by just sorting the rectangles by their vertical centers then walking through them comparing those centers and starting a new array when the value jumped by more than a set amount. I think that approach would work for the example csm_phil shows. Sorry, some ugly and redundant code here:

                       

                      var doc = app.activeDocument,
                                rectangles = doc.rectangles.everyItem().getElements(),
                                groups = [],
                                diff = 50,
                                center, lastCenter, i, l;
                      
                      rectangles.sort(function(a, b){
                                var aCenter = ((a.geometricBounds[2] - a.geometricBounds[0]) / 2) + a.geometricBounds[0];
                                var bCenter = ((b.geometricBounds[2] - b.geometricBounds[0]) / 2) + b.geometricBounds[0];
                                return aCenter - bCenter;
                      });
                      
                      groups[0] = [rectangles[0]];
                      lastCenter =  ((rectangles[0].geometricBounds[2] - rectangles[0].geometricBounds[0]) / 2) + rectangles[0].geometricBounds[0];
                      
                      for(i = 1, l = rectangles.length; i < l; i++) {
                                center = ((rectangles[i].geometricBounds[2] - rectangles[i].geometricBounds[0]) / 2) + rectangles[i].geometricBounds[0];
                                if((center - lastCenter) > diff){
                                          groups.push([rectangles[i]]);
                                }
                                else{
                                          groups[groups.length - 1].push(rectangles[i]);
                                }
                                lastCenter = center;
                      }
                      
                      for(i = 0, l = groups.length; i < l; i++) {
                                doc.groups.add(groups[i]);
                      }
                      

                       

                      Jeff

                       

                      Edit: Is it just me or did the forum start adding random whitespace when you paste in code with tabs?

                      1 person found this helpful
                      • 8. Re: Selected Object Group row wise or column wise in javascript
                        John Hawkinson Level 5

                        I think I'm missing something. Why do we care about overlaps?

                        Well, I mentioned them because they will frustrate many simple/naive attempts to do this, and it's hard to trust that the input to this script will always be what you expect. If you're willing to ignore them, well, then things are much easier.

                         

                        I've done a hacky version of this by just sorting the rectangles by their vertical centers then walking through them comparing those centers and starting a new array when the value jumped by more than a set amount.

                        Sounds like "cheating" to me :)

                         

                        Edit: Is it just me or did the forum start adding random whitespace when you paste in code with tabs?

                        I don't think this is new. I reduce them to 2-space or 4-space indents anyhow because I very much dislike forcing people to scroll horizontally to read code.

                        • 9. Re: Selected Object Group row wise or column wise in javascript
                          absqua Level 4

                          Sounds like "cheating" to me

                          "The perfect is the enemy of the barely adequate." --Voltaire (my own translation)

                          • 10. Re: Selected Object Group row wise or column wise in javascript
                            csm_phil Level 4

                            Hi All,

                             

                            Thanks for your valuable inputs,

                             

                            Still, my requirement not finish, Please try to solve my problem. I am get the selected object x,y value and sort it after that i can do that part i am struggled.

                             

                            thx

                            csm_phil

                            • 11. Re: Selected Object Group row wise or column wise in javascript
                              [Jongware] Most Valuable Participant

                              I just implemented my idea step by step and I think it totally fullfills your objective.

                               

                              absqua is wrong -- overlaps are important. Here is a before–after screenshot; larger objects may overlap previously defined groups ('buckets'), and if they do they have to be added to that bucket and its information updated. Initially I saved both top and bottom extremas, but after some more consideration that's not even necessary, and I could write it out exactly as I suggested earlier.

                               

                              Screen Shot 2011-12-26 at 1.22.37 AM.png

                               

                              //DESCRIPTION:Group by horizontal extent
                              // A Jongware Script 26-Dec-2011
                              
                              // grab selection
                              elements = app.selection;
                              
                              // sort on tops
                              elements.sort (function(x,y)
                               {
                                  return x.geometricBounds[0] - y.geometricBounds[0];
                               }
                              );
                              
                              // put in simple buckets, saving bottom and contains:array of elements
                              buckets = [ ];
                              
                              for (i=0; i<elements.length; i++)
                              {
                                e_top = elements[i].geometricBounds[0];
                                e_bottom = elements[i].geometricBounds[2];
                                b = 0;
                                while (b < buckets.length && (e_top > buckets[b].bottom) )
                                  b++;
                                // not in an available bucket? add one!
                                if (b == buckets.length)
                                  buckets.push ( {bottom:e_bottom, contains:[ elements[i] ] } );
                                else
                                {
                                  // put in bucket
                                  buckets[b].contains.push ( elements[i] );
                                  // update range
                                  if (e_bottom > buckets[b].bottom)
                                    buckets[b].bottom = e_bottom;
                                  }
                              }
                              
                              // add label for debugging purposes:
                              for (i=0; i<buckets.length; i++)
                              {
                                app.activeDocument.textFrames.add ({geometricBounds:[ buckets[i].contains[0].geometricBounds[0], 0, buckets[i].bottom, 20 ], contents:String(i)+" => "+String(buckets[i].contains.length) } );
                              }
                              
                              // deselect all
                              app.select(null);
                              // convert to groups and re-select
                              for (i=0; i<buckets.length; i++)
                              {
                                if (buckets[i].contains.length > 1)
                                  app.select ([app.activeDocument.groups.add (buckets[i].contains)], SelectionOptions.ADD_TO);
                                else
                                  app.select(buckets[i].contains, SelectionOptions.ADD_TO);
                              }
                              
                              • 12. Re: Selected Object Group row wise or column wise in javascript
                                csm_phil Level 4

                                Hi Jongware,

                                 

                                Thanks its working perferct this what i needed.

                                 

                                Thanks a lot again!

                                 

                                thx

                                csm_phil