ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Animated Line Graph

FAQ   •   VIEW ALL
 Animated Line Graph on Oct 10, 2009 at 11:33:31 pm

Several questions I have here.

I'm trying to make a line chart in AE, and I've got some working methods, but they all involve expressions that aren't very efficient. I'm looking for something a little leaner.

The look I'm going for is a line chart with data points at set intervals. So what I have right now is a comp with all my data points, each using a custom expression to work out what position it should have in the comp based on the original data:

x=(720/19)*1;
y=480-((3/360000)*480);
[x,y]

So there are 19 intervals on the x axis and my comp width is 720, and this data point is the first one on the graph, hence the x=(720/19)*1. The data value is 3 and my scale is from 0 to 360000, and my comp height is 480, hence the y=480-((3/360000)*480). Hope that makes sense so far. Although this works, I have to make 19 separate expressions for each data point, represented by 19 different solids in the comp. So question number one is how to create these points with one or two expressions and be able to use my spreadsheet of values without punching in each value manually.

The lines that connect these points are also solids. They have a position expression that essentially links them to data point 1. The rotation parameter calculates the angle between data points 1 and 2 and applies it to the rotation of the solid. And the scale parameter calculates the distance between data points 1 and 2 with the pythagorean theorem and scales the solid to connect the two points. But again, I have to have expressions for 18 different solids to connect all the points and wanted a more efficient way to do this. I've seen the mask+stroke method, but I wanted to be really precise with my lines and points since I want to zoom in on the graph a lot.

The animation is pretty simple: just a wipe, and a simple transition to make each point appear as the line hits that x interval.

Now I want to zoom in and make the camera follow the line from left to right and up and down as it traces the graph. The x animation is easy enough: just 0 to 720 over the course of the wipe. But the y movement is more tricky. Is there a way to put the position of the data points I created earlier into an array, and then have the position parameter of my camera animate through the array with a set number of frames between each element of the array?

Hope this isn't too confusing or demanding, but I'm going to be doing enough graphs that I need a quick way to do them, but can't afford to buy an expensive plugin.

Thanks!

 Re: Animated Line Graphon Oct 11, 2009 at 4:03:49 am

For the pos expression, you need two variables i and data_value, where i can be read from the layer index (say if your layers containing data points are number 1-19, your x expression for all 19 layers would be x=720*index/19). The point's data value can be controlled by a slider expression control on each layer, say "Value", then your expression for y is y=480-((effect("Value")(1)/360000)*480);

Xinlai Ni

 Re: Animated Line Graphon Oct 11, 2009 at 5:29:36 pm

Thanks! That's a much more efficient way of assigning expressions to each point. Is there a way to import a spreadsheet and assign the spreadsheet values to the sliders for the Y position so that I wouldn't have to enter in 19 values manually each time?

 Re: Animated Line Graphon Oct 11, 2009 at 6:16:34 pm

A simple script should do it, you can either read the values from external file, or construct an array containing data points as array in your script. The script just goes throw all layers and assign their expression properties, something like:
{
app.beginUndoGroup("SetPositionFromValues");
// js array containing the point values, indexes start from 0.
var DATA_VALUES = [
3, // layer 1
5, // layer 2
...
];
// assume active comp is the comp you want to work on.
var activeComp = proj.activeItem;
for (i = 1; i <= 19; ++i) {
// layer indexes start from 1
var dataLayer = activeComp.layers[i];
dataLayer.property("position").expression =
"x = 720 * index / 19;\n" +
"y = 480 - (" + (DATA_VALUES[i - 1]) + " / 360000) * 480;\n" +
"[x, y]";
}
app.endUndoGroup();
}

Xinlai Ni