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

Auto-arrange per Y value (position)

Community Beginner ,
Aug 03, 2018 Aug 03, 2018

Hi! I have a question:

I wonder if there's a way to select a group of objects (in the same layer) and auto-arrange them based on each object's Y value (vertical position on the page).

This would be helpful in creating basic perspectives.

Perhaps a script?

Thanks!

TOPICS
Scripting
4.3K
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 , Aug 03, 2018 Aug 03, 2018

not the prettiest thing int he world, but it does the trick. give this a shot:

function test()

{

    if(!app.documents.length)

    {

        alert("You must have a document open.");

        return;

    }

    var docRef = app.activeDocument;

    var sel = docRef.selection;

    if(!sel.length)

    {

        alert("You must make a selection.");

        return;

    }

    function sortVertically(items)

    {

        var topMost,curY,delIndex,curItem,tempItems = [];

        for(var x=0,len=items.length;x<len;x++)

      

...
Translate
Adobe
Community Expert ,
Aug 03, 2018 Aug 03, 2018

not the prettiest thing int he world, but it does the trick. give this a shot:

function test()

{

    if(!app.documents.length)

    {

        alert("You must have a document open.");

        return;

    }

    var docRef = app.activeDocument;

    var sel = docRef.selection;

    if(!sel.length)

    {

        alert("You must make a selection.");

        return;

    }

    function sortVertically(items)

    {

        var topMost,curY,delIndex,curItem,tempItems = [];

        for(var x=0,len=items.length;x<len;x++)

        {

            tempItems.push(items);

        }

        while(tempItems.length)

        {

            topMost = tempItems[0];

            curY = topMost.top;

            delIndex = 0;

            for(var x=1, len = tempItems.length;x<len;x++)

            {

                curItem = tempItems;

                if(curItem.top > curY)

                {

                    topMost = curItem;

                    curY = curItem.top;

                    delIndex = x;

                }

            }

            topMost.zOrder(ZOrderMethod.BRINGTOFRONT);

            tempItems.splice(delIndex,1);

        }

    }

    sortVertically(sel);

   

}

test();

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 Beginner ,
Aug 03, 2018 Aug 03, 2018

Thank you very, very much!

Worked like a charm!

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 ,
Aug 05, 2018 Aug 05, 2018

Salut !

Je me permet de proposer une autre façon plus souple.

I allow myself to propose another more flexible way.

// JavaScript Document

function test() {

    if (!selection.length) return;

    var reverse = false;

    var sel = selection;

      function sortVertically(items,zd) {

        var tab = [];

          for(var n = 0; n < items.length; n++) {

            tab = [];

            tab[0]= items.top;

            tab[1]= items;

          }

        tab.sort();

          if (zd) tab.reverse();

          for (n = 0; n < sel.length; n++) {

            tab[1].zOrder(ZOrderMethod.BRINGTOFRONT);

          }

      }

    sortVertically(sel,reverse);

}

if (app.documents.length) {test();}

de LR

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
New Here ,
Sep 05, 2020 Sep 05, 2020

I need to reorder objects by y position and it looks like this script will do exactly what I need, but I get an error when I try to run it...

Screen Shot 2020-09-05 at 4.46.42 PM.pngexpand image

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
Explorer ,
Dec 07, 2018 Dec 07, 2018

Can you help me? I need to order objects by the row (if possible I need to round y position of objects (to group them to row) for some value that I can enter in a script manually) from right down corner of airboard and each row sort by decreasing x position.

Bars 1_cut.jpg

From top to down order in the layer should be 1,2,3,4,5,6 and etc.

thanks in advance

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 08, 2018 Dec 08, 2018

I'm not sure i follow exactly what you mean. you just want to take any items that exist at the same Y position (plus or minus some buffer) and group them together, then take the resulting groups and sort them in descending order from top to bottom?

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
Explorer ,
Dec 09, 2018 Dec 09, 2018

For example

autosave_CUT.jpg

I want to sort this objects from bottom to top by rounded Y for simplify sorting process. Rounding will create virtual rows highest value goes first (Top in the layers list). Then each row I want to sort by X, from right to the left (so high value goes first - revers order)

This is like sorting 2 dimensional array in revers order:

X,Y array

myobjlist= [[124,2],[23,2],[60,1],[150,1],[12,2],[20,0],[50,1],[40,0],[70,0]]

sorted(myobjlist)

will create next array[[124, 2] [23, 2] [12, 2] [150, 1] [60, 1] [50, 1] [70, 0] [40, 0] [20, 0]]

Object with [124, 2] coordinates will be first in layers list and [20, 0] - last

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 10, 2018 Dec 10, 2018

Salut,

Une approche si cela peut aider (si j'ai bien compris ?) :

// JavaScript Document for Illustrator
var dec = 20;

if (app.documents.length > 0) {
  var docRef = app.activeDocument;
  var selectedItems = selection;
  var nbObjSelect = selectedItems.length;
    if (nbObjSelect) {
      var rep, iObj, newtop;
      var TabTop = [];
          rep = prompt("Tolérance ?", dec);
          dec= rep*1;
            for (var i = 0; i < nbObjSelect; i++) {
              iObj = selectedItems;
              TabTop.push([iObj.top,i])
            }
          TabTop.sort();
          TabTop.reverse(); //alert(TabTop.join("\r"));
          newtop =  TabTop[0][0];
          docRef.layers.add();
          nbLayers = docRef.layers.length;
            for(i = 0, k = nbLayers-1; i < nbObjSelect; i++) {
              if (newtop > TabTop[0]-dec && newtop < TabTop[0]+dec) {
                iObj = selectedItems[TabTop[1]];
                iObj.move(docRef.layers[0],ElementPlacement.PLACEATEND);
                docRef.layers[0].name = "Rang "+k;
              }
              else {
                newtop = TabTop[0]; k++; i--;
                docRef.layers.add();
              }
            }
      var layerAct, nbObjLayer, n, nObj, j, jObj;
      var TabLeft = [];
          for(i = 0; i < k; i++) {
            layerAct = docRef.layers;
            nbObjLayer = layerAct.pageItems.length;
              for(n = 0; n < nbObjLayer; n++) {
                nObj = layerAct.pageItems;
                TabLeft.push([nObj.left,nObj]);
              }
            TabLeft.sort(); //TabLeft.revers(); alert(TabLeft.join("\r"));
              for(j = 0; j < nbObjLayer; j++) {
                jObj = TabLeft[1];
                jObj.zOrder(ZOrderMethod.SENDTOBACK);
              }
            TabLeft = [];
          }
    }
    else alert("Vous n'avez rien sélectionné !","De Elleere");
}
else alert("Pour l'exécution de ce sript un document doit être ouvert !","Script Alerte de Elleere !");


//-------------------------------------------------------------

de LR elleere

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
Explorer ,
Dec 10, 2018 Dec 10, 2018

Thank you, your script seems doing that I need. Tolerance value I think is fine. But there is some problems:

  1. It creates last layer (virtual row) in top of the list.
  2. Each object in the row should be sorted from right to left
  3. it creates layers with objects. In finale will be good if all sorted objects will be in one layer

see pic below

Test1-Simple.jpg

Here some test ai files.

[link removed by moderator]

You can test by your self. I will be glad if you can fix this problem for me!

Thanks in advance!

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 11, 2018 Dec 11, 2018

Bonjour Dever,

The link is infected attention !!

Me contacter par mail (exemple enregistré sous  Illustrator Version CS6).

LR

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
Explorer ,
Dec 11, 2018 Dec 11, 2018

Hello LR

Zippyshare injects some ads and it can be infected, sorry about it

here is Wetransfer link with CS6 files to test

https://we.tl/t-OXgD7GfrDw

Thanks,

Alex

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
Explorer ,
Jan 09, 2019 Jan 09, 2019

Hello Rene,

Still did not get an Email from you. Can you post working script here?

Thanks

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
New Here ,
Sep 05, 2020 Sep 05, 2020

This script looks like exactly what I need but it also gives me an error... am I doing somthing wrong?Screen Shot 2020-09-05 at 4.51.00 PM.pngexpand image

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
Guide ,
Sep 05, 2020 Sep 05, 2020

I cannot see why the above two scripts are not working.  You could try the snippet below, but it's for all pageItems in the document, not selected items.  It doesn't work for selected items and again I'm unsure why.  (I would be grateful if someone could advise on why it works on the "pageItems" or "pathItems" collection but not on the "selection" collection.)

 

var items = app.activeDocument.pageItems;
for (var i = 0; i < items.length - 1; i++) {
  for (var j = 0; j < items.length - i - 1; j++) {
    if (items[j].top > items[j + 1].top) {
      items[j].moveAfter(items[j+1]);
    }
  }
}

 

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
Explorer ,
Jun 21, 2021 Jun 21, 2021

Thanks!

Unfortunately,...

 

topMost.zOrder is not a function

 

(Maybe changes in the API in the meanwhile?)

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
Guide ,
Jun 21, 2021 Jun 21, 2021
function test() {
    if (!app.documents.length) {
        alert("You must have a document open.");
        return;
    }
    var docRef = app.activeDocument;
    var sel = docRef.selection;
    if (!sel.length) {
        alert("You must make a selection.");
        return;
    }
    function sortVertically(items) {
        var topMost,curY,delIndex,curItem,tempItems = [];
        for (var x = 0, len = items.length; x < len; x++) {
            tempItems.push(items[x]);
        }
        while (tempItems.length) {
            topMost = tempItems[0];
            curY = topMost.top;
            delIndex = 0;
            for (var x = 1, len = tempItems.length; x < len; x++) {
                curItem = tempItems[x];
                if (curItem.top > curY) {
                    topMost = curItem;
                    curY = curItem.top;
                    delIndex = x;
                }
            }
            topMost.zOrder(ZOrderMethod.BRINGTOFRONT);
            tempItems.splice(delIndex, 1);
        }
    }
    sortVertically(sel);
}
test();
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
Explorer ,
Jun 21, 2021 Jun 21, 2021

Thanks, @femkeblanco (et al, of course): this works!

And thanks for posting it as pre-formatted text, that makes it a lot easier to read, copy and paste.
Comparing your script witht the original, I'm surprised the original worked at all for anybody.

I notice the same kind of change in two locations:

tempItems.push(items); →→→ tempItems.push(items[x]); 

and

curItem = tempItems;   →→→   curItem = tempItems[x]; 

 

Would the original have worked accidentally with grouped items?

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
Explorer ,
Jun 21, 2021 Jun 21, 2021

Based on the work by @Disposition_Dev and @femkeblanco, I wrote a more verbosely commented script and added the possibility to sort by any property. For sake of legibility, I used the JavaScript 'sort' function. I hope this helps.

function main() {
  // Check if there is an open document with a selection
  if (!app.documents.length) {
    alert("You must have a document open.");
    return;
  }

  var docRef = app.activeDocument;
  var sel = docRef.selection;

  if (!sel.length) {
    alert("You must make a selection.");
    return;
  }

  // Prompt the user for the sorting criterion
  var criterion = prompt("What property do you want to sort by? E.g. top, left, width, height, opacity, name:", "top");

  // If the property has a minus sign, the user wants to sort in reverse order. (*1)
  var sortOrder = 1;
  if (criterion[0] === "-") {
    sortOrder = -1;
    criterion = criterion.substr(1);
  }

  //  Make a copy of the array containing the selection:
  var items = [];
  for (var i = 0; i < sel.length; i++) {
    items.push(sel[i]);
  }

  // Sort the array by the criterion
  items = items.sort(dynamicSort(criterion));

  // iterate the array in reverse order while moving every element to the top:
  for (var i = items.length - 1; i >= 0; i--) {
    if (sortOrder === 1) {
      items[i].zOrder(ZOrderMethod.BRINGTOFRONT);
    } else {
      items[i].zOrder(ZOrderMethod.SENDTOBACK);
    }
  }
}

// Sorting function
function dynamicSort(property) {
  // Adapted from: https://stackoverflow.com/a/4760279/960592 (Credit: Ege Özcan)
  // (Adobe's Javascript doesn't seem to like double ternary operator)

  return function (a, b) {
    if (a[property] < b[property]) {
      return -1;
    }

    if (a[property] > b[property]) {
      return 1;
    }

    return 0;
  }
}


main();

/* 
Note: It *should* be possible to just reverse the array (items.reverse() ) or to change the sorting order in
the sorting function, but I couldn't get either method to work. This is a work-around.
*/
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
Guide ,
Jun 22, 2021 Jun 22, 2021

I should have made it clear that the above was @Disposition_Dev 's script, I just updated it. It is my understanding that migrating to the present forum in late 2019 impaired scripts, including causing loss of indices of elements. The script was evidently working up until that point.

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
Explorer ,
Jun 22, 2021 Jun 22, 2021

Is that also the reason that there is no formatting on code in older posts?

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
Guide ,
Jun 22, 2021 Jun 22, 2021

That is what I presume. 

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
New Here ,
Feb 15, 2023 Feb 15, 2023
LATEST

Thanks so much for this! I've been using illustrator for a bit of CNC vector work and some of the linework I've been generating has been totally random. This can add a ton of time to the CNC operations as the tool head is sent to polar opposite ends of the material between cuts. This script allows my CAM software to order the operations based on layers. Its saving me a ton of time.

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