Copy link to clipboard
Copied
I am trying to create a unique graph that has three concentric circles for each data point with different widths for each ring. For example, if the x-axis is amount of sales and the y-axis is how long the deal took to close then each ring could correspond to eastern region, western region or southern region.
I can plot these points on the screen (using javascript and VB), but I can't make this work without creating a void to make a ring instead of a circle. For example, if I manually create two circles and select "make compound path" this works perfectly, but I can't duplicate this from the code.
After I get this to work, I need to draw axes and am sure someone has done that before -- are there some examples, resources for creating custom graphs from scratch? i have spent hours looking at the reference and can't get this to work.
Greatly appreciate any help on this!
Best,
Tim
just trying to build one ring is challenging me:
var myDocument = app.documents.add();
var diameter = 0
var ring = myDocument.compoundPathItems.add()
for (var i=1;i<=2;i++)
{
var offset = Math.random()*72*2
diameter -= offset
var height = diameter
var top = diameter/2+500
var left = -diameter/2+600
var newCircle = ring.pathItems.ellipse(top,left,diameter,height)
newCircle.opacity = 80
var cmykColor = new CMYKColor();
cmykColor.cyan = Math.random() * 100;
cmykColor.yellow = Math.random() * 100;
cmykColor.magenta = Math.random() * 100;
if (i == 1) {
//newCircle.artworkKnockout = KnockoutState.ENABLED;
newCircle.filled = true;
newCircle.fillColor = cmykColor;
newCircle.stroked = true
newCircle.strokeWidth = 3;
newCircle.strokeColor = app.activeDocument.swatches[3].color;
}
else
{
newCircle.filled = false;
newCircle.stroked = false;
newCircle.strokeColor = app.activeDocument.swatches[3].color;
}
}
Copy link to clipboard
Copied
I can't visualize from your description what you want this graph to look like, or the kind of data values it would use.
Do a manual mockup of the kind of graph you are trying to achieve, complete with some sample values and a legend. Post that as an image for reference.
just trying to build one ring is challenging me
As for that, the meager documentation only shows an example of creating a new Compound Path and then creating paths inside it. It doesn't show an example of adding a pre-existing path to the Compound Path (at least not in the section on Compound Paths). Try this:
if ( app.documents.length > 0 ) {
docRef = app.activeDocument;
newPathA=docRef.pathItems.ellipse(72, 0, 72, 72, true, true);
newPathB=docRef.pathItems.ellipse(54,18, 36, 36, true, true);
newCompoundPath = docRef.activeLayer.compoundPathItems.add();
newPathA.move(newCompoundPath,ElementPlacement.INSIDE);
newPathB.move(newCompoundPath,ElementPlacement.INSIDE);
}
However....
Your description seems to desire simply three concentric circles, unfilled. So why mess with Compound Paths? Why not just make ellipses and give them different-colored strokes with heavy stroke weights, without fills?
JET
Copy link to clipboard
Copied
Thank you very much for your reply and I greatly appreciate your assistance. The sparse documentation and lack of internet interest makes this difficult to pick up.
Attached is a quick mock up. The width of the ring would be one set of data which sum to the x axis position, the y axis data would be another column.
For example, this could be runner stats.
Runner,Average Speed,Races Won: 5k, 10k, Marathon
Tim, 5:10, 20: 10 4 6
Bob, 5:30, 2: 0 1 1
Mike, 5:01, 6, 5 0 1
where for Tim the y axis is at 5:10, x at 20 with three concentric circles of radius 10, 14, 20 or (10, 10+4, 10+4+6).
in general, i am trying to learn how to build automated interesting graphs in illustrator -- i now need to write a script to build the axes as well.
best,
tim
Copy link to clipboard
Copied
Tim,
On this page is described a javascript named JET_AIVariablesFTROU. There is both a link to a .zip archive that contains the script and a PDF that describes what it does. It has nothing to do with graphs, but the concept is similar to what I would envision for your situation.
The Variables FTROU script gets the values needed for its variables (and for the objects it creates) from an ordinary textFrame object on the page, which contains tab-delimited text. In my case, the script:
• Finds the text strings between the tabs in the first "row" of the text. For each of those, it create a stack of other textframe objects which are bound as Variable Data objects (for use with Illustrator's Variables Palette) and positions them at the upper left corner of the page.
• Finds the text strings before the first tab of each line (i.e.; the first "column"). For each of those, it creates and accordingly names a DataSet in Illustrator's Variables palette.
• Finds the other text strings between the tabs for each line and uses them as values for the DataSets.
Similarly, a solution for a graph like you have described could:
• Use an ordinary textFrame object on the page to contain some tab-delimited text. That text can be either keyed in manually, or entered in a spreadsheet, then copied, then pasted into the textFrame object. Either way, format the text as it would be in a spreadsheet: First line of values contains the names of your columns (Runner, Average Speed, Total Wins, 5k Wins, 10k Wins, Marathon Wins). For the rest of the lines, the first entry after each para return would be the runner names (thereby constituting the values of the legend), the value after the first tab would become the Y values, the value after the second tab would be the X values, and so on.
• Write the Javascript to reference the selected textFrame object, and use the text handling methods and properties of the Javascript model to obtain the values. But instead of creating and positioning VariableData objects, create and position circles, tick mark for the axes, text objects for the legend, etc., according to the values "read" by the script.
It will be rather tedious; I certainly wouldn't recommend it for a one-time need. But if this is a regularly-recurring project, it wouldn't be too onerous for practicality. Use the examples in the AI Javascript Reference to see how to create, position, and fill/stroke the paths you need to create. Use the example of my Variables FTROU script to see how a script can be made to "parse" tab-separated values out of an ordinary text object.
Possible pseudocode for drawing the Y axis:
textRef=the selected textFrame object;
chartHeight=Prompt (desired height of the chart);
chartWidth=Prompt (desired width of the chart);
numberYLines=number of lines in textRef contents;
ySpacing=chartHeight/numberYLines;
For(counter; counter<numberYLines; ++){
tickMark[counter]=Create a horizontal straight path;
tickMark{counter}.left=the left page margin;
tickMark[counter].top==ySpacing*counter;
tickLabel[counter]=Create a pointType object;
tickLabel[counter].content=first word of last line of textRef;
tickLabel[counter].left=tickMark.left-tickLabel.width;
tickLabel[counter].top=tickMark.top;
yAxis=Create a vertical straight path;
yAxis.left=tickMark[0].left+tickMark[0].width;
YAxis.top=chartHeight;
...and so on. Similar constructs for creating the X axis and point marker ellipses.
You could position the textRef object off the Artboard; draw the graph on the Artboard. Then, when you need to draw an updated graph, past new tab-delimited text into the textRef object, delete or hide the existing graph, re-run the script.
JET
Copy link to clipboard
Copied
Had same problem with compound path not subtracting one path from another.
Set the evenodd property of the two paths to true then placing into compound path seemed to do the trick,. (see below, please ignore the rough code)
mydoc = app.activeDocument;
var rect = mydoc.pathItems.rectangle( (3250*2.834645),(-2630*2.834645),16348,16348);
var newcmykcolor = new CMYKColor();
newcmykcolor.cyan = 0;
newcmykcolor.magenta = 0;
newcmykcolor.yellow =0;
newcmykcolor.black =40;
rect.fillColor = newcmykcolor
rect.fillOverprint = true;
rect.stroked = false;
rect.evenodd = true;
rect.artworkKnockout = KnockoutState.ENABLED;
cur_width = mydoc.width
cur_height = mydoc.height
var page_rect = mydoc.pathItems.rectangle( (cur_height),(0),cur_width,cur_height);
var newcmykcolor = new CMYKColor();
newcmykcolor.cyan = 0;
newcmykcolor.magenta = 0;
newcmykcolor.yellow =0;
newcmykcolor.black =0;
page_rect.fillColor = newcmykcolor
page_rect.stroked = false;
page_rect.artworkKnockout = KnockoutState.ENABLED;
page_rect.evenodd = true;
var compaths = mydioc.compoundPathItems.add();
rect.move(compaths,ElementPlacement.INSIDE);
page_rect.move(compaths,ElementPlacement.INSIDE);
Find more inspiration, events, and resources on the new Adobe Community
Explore Now