combine group inside data

Explorer ,
Mar 29, 2022 Mar 29, 2022

Copy link to clipboard

Copied

hello
I have a lot of red frames with more than 31 pages, and inside the frames is data I need a script to make each red frame inside the data group each getter one by one
my goal is the highlighted number 3
please I want that necessary

TOPICS
How to , Scripting

Views

392

Likes

Translate

Translate

Report

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 2 Correct answers

Enthusiast , Mar 30, 2022 Mar 30, 2022

Try this:

 

/**
 * Collects any pageItems contained within selected rectangles and groups 
 * them with their container, with groups inheriting container name.
 */

Number.prototype.isBetween = function (min, max) {
  return arguments.length < 2
    ? false
    : this >= min && this <= max;
};
Array.prototype.filter = function (callback) {
  var filtered = [];
  for (var i = 0; i < this.length; i++)
    if (callback(this[i], i, this)) filtered.push(this[i]);
  return filtered;
};
Array.prototype.f
...

Likes

Translate

Translate
Enthusiast , Mar 31, 2022 Mar 31, 2022

The issue you point out via DM is likely caused by the script retrieving Group > CompoundPath > PathItems as individual items in the list, which is easy to filter out so the parent CompoundPath is still counted in the list but it's own children are not:

 

/**
 * FrameInside.jsx
 *
 * See before/after screenshots here:
 * https://github.com/Inventsable/Frame-Inside#readme
 *
 * Collects any pageItems contained within selected rectangles and groups them with their container, with groups inheriting c
...

Likes

Translate

Translate
Community Expert ,
Mar 29, 2022 Mar 29, 2022

Copy link to clipboard

Copied

Can you share a sample Illustrator file (.ai)?

 

This can possibly be done with a simple action or a graphic style.

 

Likes

Translate

Translate

Report

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 ,
Mar 29, 2022 Mar 29, 2022

Copy link to clipboard

Copied

sure Kurt Gold
here is an attach

Likes

Translate

Translate

Report

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 ,
Mar 29, 2022 Mar 29, 2022

Copy link to clipboard

Copied

Thanks for the sample file.

 

I'm afraid that I misunderstood your request. I thought the labels were already grouped and you just wanted to get the blue rectangles surrounding the labels. But obviously nothing is grouped at all and you want to make separate groups for each label.

 

To create an automated way for this task is way more difficult. I have to think about it.

 

In the meantime, perhaps someone else may chime in with an appropriate approach.

 

Likes

Translate

Translate

Report

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 ,
Mar 30, 2022 Mar 30, 2022

Copy link to clipboard

Copied

you are welcome Kurt Gold
take your time while I wait for your resolution I will work manual on this file
I hope you are fit and healthy and see you fix this problem as soon as possible.

Likes

Translate

Translate

Report

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 ,
Mar 30, 2022 Mar 30, 2022

Copy link to clipboard

Copied

It can be done with an action on a per artboard basis or even for all artboards in one go, but the latter would be pretty longwinded. I have a prototype that works, but it has to be enhanced.

 

However, there is at least one downer: It would be required to convert all (open) stroked paths to outlined paths.

 

In case that is acceptable for you, I would refine the prototype in the upcoming days.

 

Likes

Translate

Translate

Report

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 ,
Mar 30, 2022 Mar 30, 2022

Copy link to clipboard

Copied

many thanks, Kurt Gold
yes, I don't mind converting all strokes and fonts outline, that is better than making it manual.
when you are finished please send me the way step by step to make it 
appreciate your help
many thanks.

Likes

Translate

Translate

Report

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 ,
Mar 30, 2022 Mar 30, 2022

Copy link to clipboard

Copied

you could do this with a script.. here's some pseudo-code:

 

create a new layer

locate all "red" strokes

loop through all red stroke paths

    group any paths that overlap (this will group the small circle with the big rectangle)

    move group to the new layer

for each resulting "red stroke" groups on the new layer

        loop each pageItem in the original layer to find any items that are contained within the parent group's geometric bounds

            if an item is found inside the bounds of the current group

                add it to the current group (this removes it from the original layer and makes subsequent loops more optimized)

 

and that's it. now every item in the document should reside within one of the main "parent groups". 

Likes

Translate

Translate

Report

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 ,
Mar 30, 2022 Mar 30, 2022

Copy link to clipboard

Copied

Try this:

 

/**
 * Collects any pageItems contained within selected rectangles and groups 
 * them with their container, with groups inheriting container name.
 */

Number.prototype.isBetween = function (min, max) {
  return arguments.length < 2
    ? false
    : this >= min && this <= max;
};
Array.prototype.filter = function (callback) {
  var filtered = [];
  for (var i = 0; i < this.length; i++)
    if (callback(this[i], i, this)) filtered.push(this[i]);
  return filtered;
};
Array.prototype.forEach = function (callback) {
  for (var i = 0; i < this.length; i++) callback(this[i], i, this);
};
function get(type, parent) {
  if (arguments.length == 1 || !parent) parent = app.activeDocument;
  var result = [];
  if (!parent[type]) return [];
  for (var i = 0; i < parent[type].length; i++) result.push(parent[type][i]);
  return result;
}

function main() {
  if (!app.selection.length)
    return alert("Must select at least one frame to group art inside");
  get("selection").forEach(function (item) {
    function compareBounds(parent, child) {
      var pB = parent.geometricBounds,
        cB = child.geometricBounds;
      return (
        cB[0].isBetween(pB[0], pB[2]) &&
        cB[2].isBetween(pB[0], pB[2]) &&
        cB[1].isBetween(pB[3], pB[1]) &&
        cB[3].isBetween(pB[3], pB[1])
      );
    }
    var list = get("pageItems").filter(function (i) {
      return (
        !i.selected &&
        !/group/i.test(i.parent.typename) &&
        compareBounds(item, i)
      );
    });
    if (list.length) {
      var group = app.activeDocument.groupItems.add();
      group.name = item.name;
      list.forEach(function (i) {
        i.move(group, ElementPlacement.INSIDE);
      });
      item.move(group, ElementPlacement.INSIDE);
    }
  });
}
main();

 

 

Before running the script:

before.png

After selecting the rectangle frames and running the script:

after.png

Likes

Translate

Translate

Report

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 ,
Mar 31, 2022 Mar 31, 2022

Copy link to clipboard

Copied

Wonderful it works perfect 100%
I'm very thank you for resolving this problem
Actually, this day is special for me with this resolve I'm very happy 
I appreciate your help.
Many thanks.

Likes

Translate

Translate

Report

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 ,
Mar 31, 2022 Mar 31, 2022

Copy link to clipboard

Copied

The issue you point out via DM is likely caused by the script retrieving Group > CompoundPath > PathItems as individual items in the list, which is easy to filter out so the parent CompoundPath is still counted in the list but it's own children are not:

 

/**
 * FrameInside.jsx
 *
 * See before/after screenshots here:
 * https://github.com/Inventsable/Frame-Inside#readme
 *
 * Collects any pageItems contained within selected rectangles and groups them with their container, with groups inheriting container / frame / rectangle name.
 *
 * This is a very basic version and does not do proper hitbox detection -- it can work with a circle container but technically uses the bounding box (the rectangle you'd see while having that circle selected) instead of properly parsing out whether coordinates fit into a given surface area.
 */

Number.prototype.isBetween = function (min, max) {
  return arguments.length < 2 ? false : this >= min && this <= max;
};
Array.prototype.filter = function (callback) {
  var filtered = [];
  for (var i = 0; i < this.length; i++)
    if (callback(this[i], i, this)) filtered.push(this[i]);
  return filtered;
};
Array.prototype.forEach = function (callback) {
  for (var i = 0; i < this.length; i++) callback(this[i], i, this);
};
function get(type, parent) {
  if (arguments.length == 1 || !parent) parent = app.activeDocument;
  var result = [];
  if (!parent[type]) return [];
  for (var i = 0; i < parent[type].length; i++) result.push(parent[type][i]);
  return result;
}

function main() {
  if (!app.selection.length)
    return alert("Must select at least one frame to group art inside");
  get("selection").forEach(function (item) {
    function compareBounds(parent, child) {
      var pB = parent.geometricBounds,
        cB = child.geometricBounds;
      return (
        cB[0].isBetween(pB[0], pB[2]) &&
        cB[2].isBetween(pB[0], pB[2]) &&
        cB[1].isBetween(pB[3], pB[1]) &&
        cB[3].isBetween(pB[3], pB[1])
      );
    }
    var list = get("pageItems").filter(function (i) {
      return (
        !i.selected &&
        !/group/i.test(i.parent.typename) &&
        compareBounds(item, i)
      );
    });
    if (list.length) {
      var group = app.activeDocument.groupItems.add();
      group.name = item.name;
      list
        .filter(function (i) {
          // Filter out compoundPath children otherwise outlined text can distort
          return !/compound/i.test(i.parent.typename);
        })
        .forEach(function (i) {
          i.move(group, ElementPlacement.INSIDE);
        });
      item.move(group, ElementPlacement.INSIDE);
    }
  });
}
main();

 

If you have any other issues or questions it's best to leave them here instead of through DM because this is public and a few months from now, others may stumble onto this post searching for the same thing. Also, if this solves your issue, feel free to mark it as Correct Answer so that any one searching will know there is a solution and are more likely to have their problems solved as well!

Likes

Translate

Translate

Report

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 ,
Mar 31, 2022 Mar 31, 2022

Copy link to clipboard

Copied

actually, I'm very shy with myself because I say it works perfectly and I faced another problem, but you are true and I understand exactly what you mean.
right now I tested it with many causes and it works perfectly
and thank you again for the fast response and for fixing the problem
other thanks when you mention to me how I click for ( correct answer)
thank god to give us ( adobe community ❤ )

Likes

Translate

Translate

Report

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 ,
Mar 31, 2022 Mar 31, 2022

Copy link to clipboard

Copied

That's a very good approach, Inventsable.

 

I tested the script (second version) with the sample file Ahmad provided above. As far as as I can see, it already works well in conjunction with plain filled or stroked paths, but I guess that you would rather agree that it has some serious issues when processing compound contructions. At its current state it may then cause a lot of damage. At least this is what I see with the labels in the sample file.

 

But as you already stated, your script is a prototype with some room for improvements.

 

My action prototype does work pretty well so far, but it also has some issues that I'm trying to enhance. For example, currently it is bound to exactly 10 labels per artboard at fixed positions (as provided in Ahmad's sample file). That is, of course, a bit dumb and should be improved with another action approach.

 

But while it is a bit dumb at the moment, it is pretty fast. I compared the execution time of both your script and the bumpy action on my machine (again using Ahmad's sample file with one artboard and 10 labels):

 

Script: about 90 seconds

 

Action: about 25 seconds

 

Doing it manually would probably not take more than about 20 seconds.

 

I will post one or two action sets as soon as possible. It may take some days.

 

It's another interesting challenge.

 

Likes

Translate

Translate

Report

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 ,
Apr 01, 2022 Apr 01, 2022

Copy link to clipboard

Copied

We are eagerly waiting for your prototype 😊

Likes

Translate

Translate

Report

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 ,
Apr 03, 2022 Apr 03, 2022

Copy link to clipboard

Copied

LATEST

You can download a sample action here:

 

Group Maker 1

 

The.zip file contains an action set (group_maker_1.aia) and a sample Illustrator file (group_maker_sample_001.ai) based on the sample file Ahmad provided above.

 

Instruction:

 

- Download and unzip the file
- Open the file group_maker_sample_001.ai
- In the Actions palette, import the action set group_maker_1.aia
- Don't select anything
- Run the action

 

Note that the action is bound to the sample file with exactly 10 labels, each surrounded by a red stroked rectangle with a stroke weight of 0,75 pt.

 

You may have to slightly modify the action to make it work in other files. Of course, one could make a similar action that would group more than 10 Labels, but just to demonstrate the idea I limited it to 10 labels in this case.

 

Likes

Translate

Translate

Report

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