Skip to main content
Participating Frequently
January 30, 2021
Answered

How to color a map based on data?

  • January 30, 2021
  • 2 replies
  • 2614 views

Hey everyone,

I hope someone can help me with my problem! I'm a journalist and very new to Illustrator and coding.

 

I have a map, that I converted from a geoJSON file made up of 555 Groups, which I all renamed to a certain areacode (f.e. 21100000) that is also the name of the first column of my spreadsheet. In a CSV-file it looks like this 21100000;36,672991;38,52744966;7,525960381;11,42868801;2,084990922;0,124446621;0,36109921;0;1,305669462;0;0,161168574;0,159128466

 

Every column, except the first one, should have a color adjusted to it (second one is red, third one is black)

 

I want my script to select the highest value (in this case 38,52744966) and adjust the Fill Color of the Group (in this case 21100000) with the adjusted color of the column (in this case column 3 = black).

 

In a second step, I want to set the opacity of the Group to a percentage linked to the value of the column, while a value of 70 would be 100% and a value of 25 being 20%

 

Would be a blast if someone has a solution to this, or can tell me if that is even possible, so I can pay someone to write the script for me. I am willing to learn how to write scripts myself though, if someone has a guide or something I could follow, I'd be very greatful aswell.

 

This topic has been closed for replies.
Correct answer Silly-V

Hey, you are right, it's easier to manage the data in excel instead of a script, I haven't thought about this.

 

So I could basically make two spreadsheets and scripts. One for the fill, one for the opacity.

 

I would wrangle my data in excel so I only have the area code and an RBG color associated with it. That would mostly be black or red, 1 or 2 in my spreadsheet. So I'd have something like this

 

211000001
231001342

 

How would a script look like that just associates a RBG color with a different value and colorizes my groups in AI accordingly?

 

For the second spreadsheet I will translate the value in my spreadsheet to the opacity I want for my groups.

 

So that would be two quite rudimentary scripts. But I still don't know how to even go on about using a script in AI and how to translate my thoughts into code.


You can still do both opacity and color in just one sheet and only have one script, but you'd want to ensure that your spreadsheet has distinct columns that contain the data that is going to be used by the script. So in your case as you want to assign a swatch, you can either have your document contain swatches named "1" and "2", and their color would be the color values you consider to be red or black, or you can have an extra column that has a formula that turns one of those numbers into a string because it would look up the text "RGB Red" (or rgb, whatever) in some other sheet or table that has a "1" matching with the string "RGB Red". A brute way would be to select the column and do a find-and-replace to change "1" to "RGB Red" so that you don't have to rename your document swatches to "1". This is useful in cases where you get a lot of data imported from somewhere and you don't want to change your document swatch names to "1" and "2" necessarily but also can handle cases where another type of recurring import has "A" instead of "1" where it means to be red. There you can edit your formula or its data source to contain multiple keys to match to certain strings, so you can have entries like

1

RGB Red

A

RGB Red

2

RGB Black

BLK

RGB Black

 

The new formula-powered column would be sort of like this:

Item Name

Color Key

Color

45678900

1

RGB Red

32165465

2

RGB Black

32134650

2

RGB Black

The opacity could be handled in a similar way, and you can have your Illustrator-specific columns in some spot where you can quickly look and see. Or you are free to use any columns in any order, because in the script you can find your desired column by the name of its header. (Otherwise you'll have to hard-code an index-based lookup which makes it more tedious if the columns ever need to change order: you'll have to always go back to your script and fix it even when the change is only data.) I would recommend using a single csv instead of multiple ones because it's better to see the name of the shape, the color and opacity all in one place so when you highlight a row you can see exactly what appears rather than toggling between two separate files to do so.

 

Now you'll just need to learn how to use ES3-style javascript to ingest and split up a basic CSV (basic assumes there's no semicolons between your semicolons, so you never have a cell that is completely in quotes for the purpose of containing a literal semicolon - that's where you'll need CSV parsing code that does more advanced parsing than basic javascript String.split() function. This will be a great way to learn scripting, so do a search on this forum and see hundreds of examples of csv-reading code. The good news is that the process of reading text data and splitting it up so that a javascript array of rows and cells is created is not complicated and can be done in just a few lines of code (for basic csvs that is).

 

Let's leave the csv part and do a little exploration into the interesting part: making Illustrator do things!
In the script you can have a statement like this:
var doc = app.activeDocument;

doc.pathItems.getByName("45678900").fillColor = doc.swatches.getByName("RGB Red").color;

 

If you really have a path with such a name and a swatch with such a name, it should apply the color to it.

Now you'll have to learn how to use variables to stick a replaceable string in place of those hard-coded strings.

 

var doc = app.activeDocument;

var pathName = "45678900";

var swatchName = "RGB Red";

doc.pathItems.getByName(pathName).fillColor = doc.swatches.getByName(swatchName).color;

 

Then you can chart out some pseudo code, let's start without column headers and use hard-coded indexes to create a simplistic foundation:

{{NAME INDEX}} = 0 Note: javascript arrays begin at 0, so the 1st column in the csv would be at index 0.

{{COLOR INDEX}} = 1 (pretend the 2nd column has the swatch name)
{{DOC}} - get the active Illustrator document. (What happens when you use the app.activeDocument command and there's no document?)
{{CSV FILE}} - get csv file reference in the script somehow.

{{CSV TEXT}} - read the csv file contents into a variable that contains all of its text.

{{CSV ROWS}} - make the script split the text via nextline characters to get an array of row text.

>> do this for every row:

  {{ROW CELLS}} - split each row string by semi-colons to get a collection of cells.

  {{PATH NAME}} - get the cell at index {{NAME INDEX}} in the array {{ROW CELLS}}.

  {{SWATCH NAME}} - get the cell at index {{COLOR INDEX}} in the array {{ROW CELLS}}.

  Apply the color to the path with the scripting command:
  {{DOC}}.pathItems.getByName({{PATH NAME}}).fillColor = {{DOC}}.swatches.getByName({{SWATCH NAME}}).color;

 

2 replies

Legend
January 30, 2021

Am I right that your data uses comma as decimal separator (e.g. three and one half is 3,50)?

m_crevoirAuthor
Participating Frequently
January 30, 2021

You are right, I'm German, we do it that way, I didn't really think about it. Sorry, I can convert it easily, if that's a problem.

Silly-V
Legend
January 30, 2021

Sounds interesting, but it is hard to tell whether you are using a comma-delimited or semicolon-delimited csv. Do you have a screenshot of your data in a spreadsheet editor?

m_crevoirAuthor
Participating Frequently
January 30, 2021

Hey, it's semicolon-delimited. The values use a decimal comma instead of a decimal point, which I could change, if that's a problem.

Silly-V
Legend
January 30, 2021

Ok, so which columns are supposed to be the colors again?

And in those color columns, the colors are going to be rgb or cmyk swatches?

The opacity statement I am not able to comprehend as if 70 were 100% then there's no way 25 would be 20%. It should be more 35%. (right?)

I will recommend that you handle as much data transformation in a spreadsheet program as much as possible and help reduce scripting features needed so there will be more testable accuracy in the whole process. For example, rather than build data-transformation logic into a script that makes sense of your data, create instead a more rudimentary script that takes in data as is and performs operations on artwork using the data raw or with minor processing such as turning a text-string into a number.

So, if you are able to use formulas to add some columns which calculate your preferred opacity values even if they are arbitrary or result of some unknown calculations, you will end up with a csv that you can just use numbers 0-100 from for your opacity. And then it's easier to write a script to just find items and set their opacity to just the incoming number. Then when the script isn't working right and there's bugs in it, there will be less question about the source of the bug because data transformation has been separated from art processing and you can verify data or the script code as a responsible source for errors much more quickly.

 

Otherwise, there is more explanation needed regarding the columns and colors, it's hard to understand what colors you want to apply to what objects, if they are color values or color swatch names which exist in your document.