I can sort of do this with svg and change svg points in a polyline, but I was wondering if it’s possible to access the points of Hype’s native polygon and line tools?
The idea is to make an interactive line graph, data for the graph will be set from an array of values which will control the vertical position of the points, horizontal position should be evenly spaced by incrementing a step value.
So, this seems doable: In the uploaded sample file you can drag the “year” right and left to animate the lines. The red line was set manually and the points copied over onto a motion path to control the little circle.
The blue line was also created with Hype’s native Vector Shape tool. I gave the shape an id in the inspector “MyChart”. And was able to run this script to set attribute of the path “d”. (see below)
It works, however setting the points is still a manual task, so I had to cut and paste '+ rankings[1]*10 +' at every step. Idealy I would be able to do it like:
Managed to work out the steps and array!
Seems pretty solid so far. Does anyone know how to take that approach and apply it to the points of the motion path so I can repeat the effect created in the red line?
$.getJSON("https://spreadsheets.google.com/feeds/list/xxxxxxxxxxx/od6/public/values?alt=json", function(data) {
var rankings = [];
var steps = [];
var pairsArray = [];
var step = 0;
for (i = 0; i < data.feed.entry.length; i++) {
step += 50;
rankings.push(data.feed.entry[i].gsx$stephanedberg.$t)
steps.push(step)
pairsArray.push([steps[i], rankings[i]*10]);
var MyChart = hypeDocument.getElementById("myChart_path");
}
MyChart.setAttribute('d', 'M' + steps[0] + ' ' + rankings[0]*10 +' L '+ pairsArray);
});
Yes that works really well.
Next steps, working out how to do this for multiple lines without it being too manual and also how to duplicate this for motion paths.
Got a rudimentary ‘follow’ to work. A purple circle is animated along with one of the lines, by calculating the line’s total length and then dividing it by current time in timeline (to get a sort of percentage) Total time is 10sec so I multiply that by ten to get 100. It’s ‘bumpy’ to say the least, but it does work.
var Edberg = hypeDocument.getElementById("Edberg_path");
var EdbergPic = hypeDocument.getElementById("EdbergPic");
var EdbergPathLength = Math.floor(Edberg.getTotalLength());
var prcnt = (EdbergPathLength / 100)*hypeDocument.currentTimeInTimelineNamed('Main Timeline')*10;
var pt = Edberg.getPointAtLength(prcnt);
pt.x = Math.round(pt.x)-10;
pt.y = Math.round(pt.y)+44;
EdbergPic.style.top = pt.y+'px';
EdbergPic.style.left = pt.x+'px';
Maybe a better way would be to attach the circle to the endpoint of path.style.strokeDasharray or path.style.strokeDashoffset as it progresses through the animation?
OK! So this now works smoothly when run while dragging the “year” marker. Three circles attached to the end of their respective paths! But there must be an easier way of writing this… But at least it works!
The attached Hype document has two scenes. The first pulls data from one sheet where the year is in a column and player names are in a row. The code for this is very long and I only added 4 player (I would need 131 to cover the history of the top ten).
So the second scene is a different approach with a different code. Essentially the table is flipped with player names in a column and year in a row. For some reason, at least to me this seemed easier to implement… also a lot shorter (apart from the list of years that can’t be numbers?!
var players = [];
var rankings = [];
var points = [];
$.getJSON("https://spreadsheets.google.com/feeds/list/xxxxxxxxx/2/public/values?alt=json", function(data) {
var steps = [];
var step = -49;
var stepSize = 49;
var command = 'M ';
for (j = 0; j < data.feed.entry.length; j++) {
step += stepSize;
steps.push(step);
players.push(data.feed.entry[j].gsx$players.$t)
rankings.push(data.feed.entry[j].gsx$seventhree.$t, data.feed.entry[j].gsx$sevenfour.$t, data.feed.entry[j].gsx$sevenfive.$t, data.feed.entry[j].gsx$sevensix.$t, data.feed.entry[j].gsx$sevenseven.$t, data.feed.entry[j].gsx$seveneight.$t, data.feed.entry[j].gsx$sevennine.$t, data.feed.entry[j].gsx$eightzero.$t, data.feed.entry[j].gsx$eightzero.$t, data.feed.entry[j].gsx$eightone.$t, data.feed.entry[j].gsx$eighttwo.$t);
points.push(command + steps[j] + ' ' + rankings[j]*20 + ' ' + (steps[j]+(stepSize - 10)) + ' ' + rankings[j]*20);
command = 'L ';
}
for (i = 0; i < players.length; i++) {
var player = hypeDocument.getElementById(players[i]+"_path");
player.setAttribute('d', points);
}
});
But this is not working quite right. If I look in the console log, the same points are set for all the native vector lines. I somehow need to split the point array to apply only to individual players. Seems nearly there, but now I’m stuck.