You can program your own graphs. This gives you total flexibility over the results. While this may seem daunting it is not. Most infographics are quite easy to codify, things like bar charts, line charts, radar charts, doughnut charts are all very easy to do.
All the simple charts build on the same code structure.
- Get a array (or arraylike structure) of data
- Loop over each item and draw a item.
- draw any annotations etc...
- Style items
OK lets start with a bar chart, for simplicity lets ignore how to obtain the data lets just make a dummy list and draw it
#target illustrator
data =[1.2, 3.0, 2.1, 0.42, 3.0, 1.1, 1.8];
doc = app.activeDocument;
// supporting vars
var mul = 24
var offsetX =100
var offsetY =-150
for (var i = 0; i < data.length; i++){
var val = data[i];
var newPath = doc.pathItems.add();
newPath.setEntirePath( [
[i * mul + offsetX, 0 + offsetY],
[i * mul + offsetX, val * mul + offsetY]
]);
}
Image 1: Simple unstyled graph
Ok, this draws some lines. Why not boxes? Well its relatively easy for you to make a line into a rectangle by applying a style with a mitered offset, convert to shape, pattern brush or art brush. So I would prefer to leave the styling to styles as it means the same script can be reused easily. Likewise i would like to leave coloring of datasets to color group swtaches.
Let us modularize the thing a bit and add a named style and some colors to the lines. Still not entirely practivcal but lets remedy that later. I assume you have a style named "graph", with a mitered offset effect, and a color group named "graph".
#target illustrator
data =[1.2, 3.0, 2.1, 0.42, 3.0, 1.1, 1.8];
doc = app.activeDocument;
// supporting vars
var mul = 24
var offsetX =100
var offsetY =-150
for (var i = 0; i < data.length; i++){
var val = data[i];
var newPath = makeBarLine(i, val);
setStyle(i, newPath);
}
function makeBarLine(i, val){
var newPath = doc.pathItems.add();
newPath.setEntirePath( [
[i * mul + offsetX, 0 + offsetY],
[i * mul + offsetX, val * mul + offsetY]
]);
return newPath
}
function setStyle(i, pathitem){
doc.graphicStyles.getByName("graph").applyTo( pathitem );
pathitem.fillColor=doc.swatchGroups["graph"].getAllSwatches()[i].color;
}
Image 2: Same graph but with automated styling
Ok so far we have had a slightly unrealistic table in reality your data is most likely contained in some sort of list of lists.
#target illustrator
data =[["Apricot", 1.2],
["Banana", 3.0],
["Clementine", 2.1],
["Dragon Fruit", 0.42],
["Entawak", 3.0],
["Fig", 1.1],
["Guava", 1.8]
];
var doc = app.activeDocument;
// supporting vars
var mul = 24
var offsetX =100
var offsetY =-150
for (var i = 0; i < data.length; i++){
var val = data[i];
var newPath = makeBarLine(i, val[1]);
makeLabel(i, val[0]);
valueOnTop(i, val[1]);
setStyle(i, newPath);
}
function makeLabel(i, val){
var ptext = doc.textFrames.add();
ptext.contents = val;
ptext.rotate(-70);
ptext.left = i * mul + offsetX-10;
ptext.top = -10 + offsetY;
}
function valueOnTop(i, val){
var ptext = doc.textFrames.add();
ptext.contents = val.toFixed(1);
ptext.left = i * mul + offsetX;
ptext.top = val * mul + offsetY+12 ;
ptext.textRange.justification = Justification.CENTER;
}
function makeBarLine(i, val){
var newPath = doc.pathItems.add();
newPath.setEntirePath( [
[i * mul + offsetX, 0 + offsetY],
[i * mul + offsetX, val * mul + offsetY]
]);
return newPath
}
function setStyle(i, pathitem){
doc.graphicStyles.getByName("graph").applyTo( pathitem );
pathitem.fillColor=doc.swatchGroups["graph"].getAllSwatches()[i].color;
}
Image 3: Adding decoration is not much harder
So you see we can get incrementtaly better. THere is still one thing to fix. That is the system will fail if there are more bars than colors in the color set. And finally how to read a csv file for example. I will try to flesh this out tomorrow.