Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Selected Object Group row wise or column wise in javascript

Advocate ,
Dec 21, 2011 Dec 21, 2011

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

TOPICS
Scripting
2.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Dec 25, 2011 Dec 25, 2011

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

...
Translate
LEGEND ,
Dec 21, 2011 Dec 21, 2011

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 22, 2011 Dec 22, 2011

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 22, 2011 Dec 22, 2011

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 22, 2011 Dec 22, 2011

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-rectangles. There is a textbook citation.

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 22, 2011 Dec 22, 2011

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.)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 22, 2011 Dec 22, 2011

(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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 22, 2011 Dec 22, 2011

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.geometricBounds[2] - rectangles.geometricBounds[0]) / 2) + rectangles.geometricBounds[0];

          if((center - lastCenter) > diff){

                    groups.push([rectangles]);

          }

          else{

                    groups[groups.length - 1].push(rectangles);

          }

          lastCenter = center;

}

for(i = 0, l = groups.length; i < l; i++) {

          doc.groups.add(groups);

}

Jeff

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 22, 2011 Dec 22, 2011

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 22, 2011 Dec 22, 2011

Sounds like "cheating" to me

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 22, 2011 Dec 22, 2011

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 25, 2011 Dec 25, 2011

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.geometricBounds[0];

  e_bottom = elements.geometricBounds[2];

  b = 0;

  while (b < buckets.length && (e_top > buckets.bottom) )

    b++;

  // not in an available bucket? add one!

  if (b == buckets.length)

    buckets.push ( {bottom:e_bottom, contains:[ elements ] } );

  else

  {

    // put in bucket

    buckets.contains.push ( elements );

    // update range

    if (e_bottom > buckets.bottom)

      buckets.bottom = e_bottom;

    }

}

// add label for debugging purposes:

for (i=0; i<buckets.length; i++)

{

  app.activeDocument.textFrames.add ({geometricBounds:[ buckets.contains[0].geometricBounds[0], 0, buckets.bottom, 20 ], contents:String(i)+" => "+String(buckets.contains.length) } );

}

// deselect all

app.select(null);

// convert to groups and re-select

for (i=0; i<buckets.length; i++)

{

  if (buckets.contains.length > 1)

    app.select ([app.activeDocument.groups.add (buckets.contains)], SelectionOptions.ADD_TO);

  else

    app.select(buckets.contains, SelectionOptions.ADD_TO);

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 28, 2011 Dec 28, 2011
LATEST

Hi Jongware,

Thanks its working perferct this what i needed.

Thanks a lot again!

thx

csm_phil

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines