Stop Coloring Objects Manually: The Illustrator Script Every Designer Needs
As a graphic designer, you know that some of the most impactful visuals come from data. Whether it’s a seating chart for a parliament, a map showing population density, or a simple bar graph, data visualization is powerful. But let’s be honest: the process can be incredibly tedious.
Have you ever had to color hundreds of tiny shapes one by one? You select 138 circles and fill them with blue, then you select another 210 and fill them with pink, carefully tracking your counts. It’s slow, boring, and easy to make a mistake.
What if you could do it all in 10 seconds?
I’m excited to share a powerful Adobe Illustrator script that does exactly that. It’s a game-changer for anyone working on infographics or complex illustrations.

What is it?
It’s an advanced script called the Intelligent Color Filler. You select a large number of objects in Illustrator, and a simple dialog box pops up. In that box, you tell the script how many objects you want in each color, and it does all the work for you instantly.
Imagine having 577 seats in a parliament graphic. You just tell the script:
- 138 seats should be dark blue.
- 210 seats should be light blue.
- 192 seats should be pink.
- 37 seats should be gray.
You click “Fill Colors,” and it’s done.
Features Designed for Designers
This isn’t just a simple filler. It’s packed with smart features that give you creative control.

- Intelligent Auto-Count: The script automatically knows how many objects you’ve selected and even pre-fills the counts for you to get started.
- Live Tally: A running counter shows you how many objects you’ve assigned (
Assigned: 577 / 577). It even turns red if you accidentally assign too many! - Dynamic Groups: Need to represent 2 parties or 10? Use the
[+]and[-]buttons to add or remove color groups on the fly. - Creative Fill Directions: Don’t just fill randomly. You can tell the script to color objects from Left to Right, Top to Bottom, or vice-versa, creating organized patterns and gradients.
- Flexible Color Input: Use the color codes you already love, whether it’s
#RRGGBBhex codes from your brand guide or simpleR,G,Bvalues. - Automatic Grouping: The best part for future edits! After coloring, the script automatically groups all objects of the same color. Need to make all the blue seats a little bigger? Just click one, and they’re all selected.
How to Get Started in 5 Simple Steps
(function() {
// 1. SCRIPT SETUP & VALIDATION
// ===================================
if (app.documents.length === 0) {
alert("Error: No active document found.");
return;
}
var doc = app.activeDocument;
var selection = doc.selection;
var totalSelected = selection.length;
if (totalSelected === 0) {
alert("Error: No objects selected.");
return;
}
// 2. USER INTERFACE
// ============================
var dialog = new Window("dialog", "Intelligent Color Filler v4");
dialog.orientation = "column";
dialog.alignChildren = ["fill", "top"];
// --- Info Panel ---
var infoGroup = dialog.add('group');
infoGroup.add("statictext", undefined, "Total selected objects: " + totalSelected);
var assignedCountText = infoGroup.add("statictext", undefined, "");
assignedCountText.characters = 25; // Reserve space
// --- Container for Dynamic Color Groups ---
var groupsContainer = dialog.add("panel", undefined, "Color Groups");
groupsContainer.orientation = "column";
groupsContainer.alignChildren = "fill";
var allColorGroups = [];
// --- Group Management Buttons ---
var mgmtGroup = dialog.add("group");
mgmtGroup.alignment = "right";
var addBtn = mgmtGroup.add("button", undefined, "[+] Add Group");
var removeBtn = mgmtGroup.add("button", undefined, "[-] Remove Group");
// --- Default Data & Initial UI ---
var defaultData = [
{ name: "Group 1", color: "#00008B" }, { name: "Group 2", color: "#1E90FF" },
{ name: "Group 3", color: "#FF69B4" }, { name: "Group 4", color: "#808080" },
{ name: "Group 5", color: "#9ACD32" }, { name: "Group 6", color: "#FF4500" },
{ name: "Group 7", color: "#20B2AA" }, { name: "Group 8", color: "#9370DB" },
{ name: "Group 9", color: "#F4A460" }, { name: "Group 10", color: "#FFFFFF" }
];
// --- Options Panel ---
var optionsPanel = dialog.add("panel", undefined, "Options");
optionsPanel.orientation = "row";
optionsPanel.alignment = "fill";
var directionDropdown = optionsPanel.add("dropdownlist", [0,0,120,25], ["Random", "Left to Right", "Right to Left", "Top to Bottom", "Bottom to Top"]);
directionDropdown.selection = 0;
var applyToDropdown = optionsPanel.add("dropdownlist", [0,0,80,25], ["Fill", "Stroke", "Both"]);
applyToDropdown.selection = 0;
var groupCheckbox = optionsPanel.add("checkbox", undefined, "Group by color");
groupCheckbox.value = true;
// --- Action Buttons ---
var buttonGroup = dialog.add("group");
buttonGroup.orientation = "row";
buttonGroup.alignment = "right";
buttonGroup.add("button", undefined, "Cancel");
var okButton = buttonGroup.add("button", undefined, "Fill Colors", { name: "ok" });
// 3. UI LOGIC & MANAGEMENT
// =========================
function updateTotals() {
var currentTotal = 0;
for (var i = 0; i < allColorGroups.length; i++) {
var count = parseInt(allColorGroups[i].countInput.text) || 0;
currentTotal += count;
}
assignedCountText.text = "Assigned: " + currentTotal + " / " + totalSelected;
// Change color to red if total is invalid
var red = [1, 0, 0, 1];
var defaultColor = [0, 0, 0, 1];
assignedCountText.graphics.foregroundColor = assignedCountText.graphics.newPen(
assignedCountText.graphics.PenType.SOLID_COLOR,
currentTotal > totalSelected ? red : defaultColor,
1
);
}
function addGroupPanel(index, initialCount) {
var data = defaultData[index];
var panel = groupsContainer.add("panel", undefined, data.name);
panel.orientation = "row";
panel.add("statictext", undefined, "Count:");
var countInput = panel.add("edittext", [0, 0, 60, 25], initialCount.toString());
panel.add("statictext", undefined, "Color (RGB/#HEX):");
var colorInput = panel.add("edittext", [0, 0, 120, 25], data.color);
countInput.onChanging = updateTotals;
allColorGroups.push({ panel: panel, countInput: countInput, colorInput: colorInput });
updateButtons();
dialog.layout.layout(true);
}
function removeGroupPanel() {
if (allColorGroups.length <= 2) return;
var lastGroup = allColorGroups.pop();
groupsContainer.remove(lastGroup.panel);
updateButtons();
updateTotals();
dialog.layout.layout(true);
}
function updateButtons() {
removeBtn.enabled = allColorGroups.length > 2;
addBtn.enabled = allColorGroups.length < 10;
}
addBtn.onClick = function() {
if (allColorGroups.length < 10) {
addGroupPanel(allColorGroups.length, 0);
updateTotals();
}
};
removeBtn.onClick = removeGroupPanel;
// --- Initialize with auto-distributed counts ---
var initialGroupCount = 2;
var baseCount = Math.floor(totalSelected / initialGroupCount);
var remainder = totalSelected % initialGroupCount;
for (var i = 0; i < initialGroupCount; i++) {
var count = baseCount + (i < remainder ? 1 : 0);
addGroupPanel(i, count);
}
updateTotals(); // Set initial assigned count text
// 4. DIALOG SUBMISSION LOGIC
// ===========================
okButton.onClick = function() {
var totalCount = 0;
var colorJobs = [];
for (var i = 0; i < allColorGroups.length; i++) {
var count = parseInt(allColorGroups[i].countInput.text) || 0;
if (count < 0) {
alert("Error: Invalid count for Group " + (i + 1) + ".");
return;
}
if (count === 0) continue;
var newColor = parseColor(allColorGroups[i].colorInput.text);
if (!newColor) {
alert("Error: Invalid color format for Group " + (i + 1) + ".");
return;
}
totalCount += count;
colorJobs.push({ count: count, color: newColor, items: [] });
}
if (totalCount > totalSelected) {
alert("Error: The sum of counts (" + totalCount + ") is greater than the number of selected objects (" + totalSelected + ").");
return;
}
applyColors(colorJobs, directionDropdown.selection.text, applyToDropdown.selection.text, groupCheckbox.value);
dialog.close();
if (totalCount > 0) {
alert("Coloring complete!\n" + totalCount + " of " + totalSelected + " objects have been colored.");
}
};
// 5. HELPER & CORE FUNCTIONS (Unchanged)
// ===============================================
function parseColor(colorString) {
var color = new RGBColor();
colorString = colorString.replace(/\s/g, '');
if (colorString.charAt(0) === '#') colorString = colorString.substring(1);
if (/^[0-9a-fA-F]{6}$/.test(colorString)) {
color.red = parseInt(colorString.substring(0, 2), 16);
color.green = parseInt(colorString.substring(2, 4), 16);
color.blue = parseInt(colorString.substring(4, 6), 16);
return color;
}
var rgb = colorString.split(',');
if (rgb.length === 3) {
var r = parseInt(rgb[0]), g = parseInt(rgb[1]), b = parseInt(rgb[2]);
if (!isNaN(r) && !isNaN(g) && !isNaN(b) && r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
color.red = r; color.green = g; color.blue = b;
return color;
}
}
return null;
}
function applyColors(jobs, direction, target, shouldGroup) {
var objectsToColor = [].slice.call(selection);
switch (direction) {
case "Left to Right": objectsToColor.sort(function(a, b) { return a.position[0] - b.position[0]; }); break;
case "Right to Left": objectsToColor.sort(function(a, b) { return b.position[0] - a.position[0]; }); break;
case "Top to Bottom": objectsToColor.sort(function(a, b) { return b.position[1] - a.position[1]; }); break;
case "Bottom to Top": objectsToColor.sort(function(a, b) { return a.position[1] - b.position[1]; }); break;
default: // Random
for (var i = objectsToColor.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = objectsToColor[i]; objectsToColor[i] = objectsToColor[j]; objectsToColor[j] = temp;
}
break;
}
var objectIndex = 0;
for (var i = 0; i < jobs.length; i++) {
for (var j = 0; j < jobs[i].count; j++) {
if (objectIndex >= objectsToColor.length) break;
var item = objectsToColor[objectIndex];
if (item.typename === "PathItem" || item.typename === "CompoundPathItem") {
if (target === "Fill" || target === "Both") { item.filled = true; item.fillColor = jobs[i].color; }
if (target === "Stroke" || target === "Both") { item.stroked = true; item.strokeColor = jobs[i].color; }
jobs[i].items.push(item);
}
objectIndex++;
}
}
if (shouldGroup && doc.groupItems.length > 0) {
doc.selection = null;
for (var i = 0; i < jobs.length; i++) {
if (jobs[i].items.length > 0) {
var newGroup = doc.groupItems.add();
for (var k = jobs[i].items.length - 1; k >= 0; k--) {
jobs[i].items[k].move(newGroup, ElementPlacement.PLACEATBEGINNING);
}
}
}
}
redraw();
}
dialog.show();
})();- Install the Script:
Simply place the.jsxfile into your Illustrator Scripts folder.- Windows:
C:\Program Files\Adobe\Adobe Illustrator [Version]\Presets\en_US\Scripts\ - macOS:
/Applications/Adobe Illustrator [Version]/Presets/en_US/Scripts/
(You’ll only need to do this once!)
- Windows:
- Select Your Shapes:
In your Illustrator document, select all the objects you want to color. - Run the Script:
In Illustrator, go toFile > Scripts > IntelligentParliamentFiller. - Configure and Create!
The script’s dialog box will appear. Adjust your counts and colors, choose your options, and click “Fill Colors”.
And that’s it. The hours you used to spend on tedious coloring can now be spent on what really matters: creating beautiful and effective designs.
I hope this tool helps you streamline your workflow and opens up new possibilities for your data visualization projects. Give it a try and see how much time you save!