Hello all,
I'm looking for a very simple solution to map 7 points on a graph (last week's stats). All I need is a line (red) that is drawn using 9 points (first and last points aren't labeled, as they are outside of the date's focus and are there to give some visual continuity to the line). On top or under each point there should be a label (green) that has 2 strings: day and stats number. The vertical axis should be from 0 to 1300 (if you can't see the following pic, I also attached it below):
var anaPreLineX:Array = new Array("110","120","130","140","150","160","170","180","190","200","210","220","230","240","250","260","270","280","290","300","310","320","330","340","350","360","370","380","390","400","410","420","430","440","450","460","470","480","490");
var anaPreLineY:Array = new Array("342.4","332.4","332.4","342.4","352.4","342.4","352.4","342.4","332.4","342.4","352.4","362.4","362.4","352.4","342.4","352.4","352.4","342.4","332.4","322.4","312.4","322.4","322.4","312.4","322.4","312.4","322.4","332.4","322.4","312.4","322.4","312.4","322.4","332.4","332.4","322.4","312.4","302.4","292.4");
for(i=1;i<anaPreLineX.length;i++){
_root.createEmptyMovieClip("line"+i, 100+i);
_root["line"+i].lineStyle(2, 0x000000, 100);
_root["line"+i].moveTo(anaPreLineX[i-1], anaPreLineY[i-1]);
_root["line"+i].lineTo(anaPreLineX[i], anaPreLineY[i]);
}
problem is, the above uses pixel coordinates instead of direct numbers mapped on a 0-1300 vertical axis, and it doesn't have a label for each point. I'd be grateful if anyone could mod that or come up with something else. Thanks.
great! this is ace! I'll see how I can style it a bit (font type, size, etc) and put all input data in vars (they will be loaded from remote txt or php files). Somehow, if the line is too spiky it overlaps the days + numbers close to it (oh well, it won't be that spiky anyway from the numbers I've seen)
Actionscript Code:
var data_a = 599 var data_b = 200 var data_c = 100 var data_d = 240 var data_e = 800 var data_f = 270 var data_g = 140 var data_h = 200 var data_i = 600
var day_b = "Sunday" var day_c = "Monday" var day_d = "Tuesday" var day_e = "Wednesday" var day_f = "Thursday" var day_g = "Friday" var day_h = "Saturday"
var limitY = 1300; var sizeY = 450; var multY = sizeY/limitY; var dataY:Array = newArray(data_a, data_b, data_c, data_d, data_e, data_f, data_g, data_h, data_i); var dayArray = newArray(day_b, day_c, day_d, day_e, day_f, day_g, day_h);
makeChart();
function makeChart(){ var contentMC = _root.createEmptyMovieClip("contentMC", _root.getNextHighestDepth()); drawAxis(contentMC,sizeY,300); makeTxtBox(contentMC,limitY,-10,300,"right",0x000000); makeTxtBox(contentMC,"0",-10,20,"right",0x000000); contentMC.lineStyle(2,0xFF0000,100); contentMC.moveTo(25,(-dataY[0]*multY)); for(var i = 1; i<dataY.length-1; i++){ contentMC.lineTo(i*50,-(dataY[i]*multY)); var infoTxt = dayArray[i-1]+newline+dataY[i]; var overunder = (i%2 == 1) ? 40 : -10; makeTxtBox(contentMC,infoTxt,(i*50)-15,(dataY[i]*multY)+overunder,"left",0x009900); } contentMC.lineTo(dataY.length*50-25,-(dataY[dataY.length-1]*multY)); } function drawAxis(mc, x2, y2){ mc.lineStyle(2,0x000000,100); mc.moveTo(0,0); mc.lineTo(0,-y2); mc.moveTo(0,0); mc.lineTo(x2,0); mc._x += 50; mc._y += y2+50; } function makeTxtBox(mc, infoTxt, posX, posY, align, color){ var my_fmt:TextFormat = newTextFormat(); my_fmt.color = color; var my_txt = mc.createTextField("my_txt", mc.getNextHighestDepth(), posX, -posY, 0, 0); my_txt.autoSize = align; my_txt.multiline = true; my_txt.text = infoTxt; my_txt.setTextFormat(my_fmt); }
Also, for a second graph I need that uses the same data but in a much smaller scale, is there a way to have the var limitY = 1300; become dynamic, according to the maximum value from the var dataY:Array ? Something that will scale the graph's top close to the maximum value so that when too small values are entered, a fluctuation is still visible on the drawn line. For example, if my input data is say, 5, 10, 8, 9, 14, 3 , then the vertical axis should be something like 14 (max value inserted) + 10 = 24 instead of 1300. If the max value inserted is 100, then it should be 100 + 50 = 150 instead of 1300. Don't know if it's easy to make the added range from max input grow as the max input grows too, if it's too much of a hassle, adding a predefined number will be fine too.
Thanks! This works fine! I'm trying to wrap my head around how to make it show both the 1300 max limit and a close up of the fluctuations happening when the input data is something really low, around 10 or even 20. When it's shown with a 1300 max limit like you did the first time, those small numbers produce a straight line. So, we go to the next step where the max limit is dynamically set just a bit above the max input data and that works fine as it shows a wave, but now the 1300 limit is too far away to be shown onscreen (and it kinda has to be visible in order to show how far below that number our data is). So, at the same time, I need to show both graphs at the same space... Hmmmm will see how that's possible, meanwhile, thanks for all your help, I wish I knew how to do all that code, you're a life saver!
Edit: I think I have it (although by now it's definitely not a "simple line graph" anymore). The concept is as follows: We have graph 1 (with 1300 limit) created on stage, then graph 2 (dynamically set limit) is created above it and has a third movieclip that acts as a slow panning mask that rolls from left to right and back (not following mouse, just rolling on its own).
I have attached an FLA+SWF with this concept in plain tweens and shapes so you can see what I mean. It should be just a matter of loading the two graph codes on top of each other and making that mask spin...
I also faded the line a bit so the points stand out and the text is readable when intersecting with that line (no need to go into any collision detection mess):
Code:
//current week graph data
var data_a = 19;
var data_b = 20;
var data_c = 27;
var data_d = 24;
var data_e = 10;
var data_f = 5;
var data_g = 24;
var data_h = 20;
var data_i = 19;
var day_b = "Sunday";
var day_c = "Monday";
var day_d = "Tuesday";
var day_e = "Wednesday";
var day_f = "Thursday";
var day_g = "Friday";
var day_h = "Saturday";
var dataY:Array = new Array(data_a, data_b, data_c, data_d, data_e, data_f, data_g, data_h, data_i);
var dayArray = new Array(day_b, day_c, day_d, day_e, day_f, day_g, day_h);
var limitY = 0;
var miniY = dataY[0];
for (var i in dataY) {
limitY = Math.max(limitY, dataY[i]);
miniY = Math.min(miniY, dataY[i]);
}
limitY += 40;
miniY -= 40;
var sizeY = 300;
var multY = sizeY/(limitY-miniY);
makeChart();
function makeChart() {
var contentMC = _root.createEmptyMovieClip("contentMC", _root.getNextHighestDepth());
contentMC._x = 700;
contentMC._y = 0;
drawAxis(contentMC,600,sizeY);
makeTxtBox(contentMC,limitY,-10,300,"right",0x000000);
makeTxtBox(contentMC,miniY,-10,20,"right",0x000000);
var chartMC = contentMC.createEmptyMovieClip("chartMC", contentMC.getNextHighestDepth());
chartMC.lineStyle(2,0x000000,20);
chartMC.moveTo(25,(-(dataY[0]-miniY)*multY));
for (var i = 1; i<dataY.length-1; i++) {
var point = makeMark(chartMC, i*65, -((dataY[i]-miniY)*multY));
chartMC.lineTo(point._x,point._y);
var infoTxt = dayArray[i-1]+newline+dataY[i];
var overunder = (i%2 == 1) ? 40 : -10;
makeTxtBox(chartMC,infoTxt,(i*65),((dataY[i]-miniY)*multY)+overunder,"center",0xFFFFFF);
}
chartMC.lineTo(dataY.length*65-25,-((dataY[dataY.length-1]-miniY)*multY));
}
function makeMark(mc, x1, y1) {
var markMC = mc.createEmptyMovieClip("markMC"+mc.getNextHighestDepth(), mc.getNextHighestDepth());
markMC.lineStyle(3,0xFF0000);
markMC.beginFill(0xFF0000,100);
markMC.moveTo(-1,1);
markMC.lineTo(1,1);
markMC.lineTo(1,-1);
markMC.lineTo(-1,-1);
markMC.lineTo(-1,1);
markMC.endFill();
markMC._x = x1;
markMC._y = y1;
return markMC;
}
function drawAxis(mc, x2, y2) {
mc.lineStyle(2,0x000000,100);
mc.moveTo(0,0);
mc.lineTo(0,-y2);
mc.moveTo(0,0);
mc.lineTo(x2,0);
mc._x += 50;
mc._y += y2+50;
}
function makeTxtBox(mc, infoTxt, posX, posY, align, color) {
var my_fmt:TextFormat = new TextFormat();
my_fmt.color = 0x000000
my_fmt.font = "Verdana";
my_fmt.size = 12;
my_fmt.align = "center";
var my_txt = mc.createTextField("my_txt", mc.getNextHighestDepth(), posX, -posY, 0, 0);
my_txt.autoSize = align;
my_txt.multiline = true;
my_txt.text = infoTxt;
my_txt.setTextFormat(my_fmt);
}
Last edited by mx_green; 03-31-2010 at 03:35 PM.
Reason: eureka!
over the top one (unlimhol_mc) I added a mask layer with a circle movieclip that tweens left and right (like a searchlight) so only a part of it is shown having limhol_mc as background.
Problem is, the code of those two graphs flies over the mask, hiding nothing from unlimhol_mc...
when I test the movie the trace window shows the values of data_a and data_b but the rest of the script does not work and gives undefined everywhere. It seems like the variables are properly loaded but the rest of the script cannot use them. What am I doing wrong?