A Flash Developer Resource Site

Results 1 to 8 of 8

Thread: [CS4] Simple 2D line graph help

  1. #1
    Member
    Join Date
    Feb 2005
    Posts
    81

    [CS4] Simple 2D line graph help

    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):



    The closest thing I found was this script here
    http://www.actionscript.org/forums/s....php3?p=687982

    Code:
    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.
    Attached Images Attached Images

  2. #2
    :
    Join Date
    Dec 2002
    Posts
    3,518
    ...
    Last edited by dawsonk; 03-30-2010 at 02:00 PM. Reason: Typo in code

  3. #3
    Member
    Join Date
    Feb 2005
    Posts
    81
    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 = 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);

    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 = new TextFormat();
        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 again!

  4. #4
    :
    Join Date
    Dec 2002
    Posts
    3,518
    Code:
    var data_a = 199;
    var data_b = 200;
    var data_c = 270;
    var data_d = 240;
    var data_e = 100;
    var data_f = 300;
    var data_g = 240;
    var data_h = 200;
    var data_i = 199;
    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());
    	drawAxis(contentMC,450,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,0xFF0000,100);
    	chartMC.moveTo(25,(-(dataY[0]-miniY)*multY));
    	for (var i = 1; i<dataY.length-1; i++) {
    		var point = makeMark(chartMC, i*50, -((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*50)-15,((dataY[i]-miniY)*multY)+overunder,"left",0x009900);
    	}
    	chartMC.lineTo(dataY.length*50-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 = 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);
    }
    Last edited by dawsonk; 03-30-2010 at 05:54 PM. Reason: Updated code

  5. #5
    Member
    Join Date
    Feb 2005
    Posts
    81
    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);
    }
    Attached Files Attached Files
    Last edited by mx_green; 03-31-2010 at 03:35 PM. Reason: eureka!

  6. #6
    Member
    Join Date
    Feb 2005
    Posts
    81
    gah! can't make it work...

    I put each code in one file and exported 2 swfs
    d_unlimited.swf (dynamic limitY)
    d_limited.swf (limitY = 1300)

    I then made a new one and on two layers I put an empty holder clip where I would load the two external graphs:

    Code:
    this.unlimhol_mc.loadMovie("d_unlimited.swf");
    this.limhol_mc.loadMovie("d_limited.swf");
    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...

  7. #7
    Member
    Join Date
    Feb 2005
    Posts
    81
    /bump

    any ideas???

  8. #8
    Member
    Join Date
    Feb 2005
    Posts
    81
    one new problem (sigh...) is that I need to load the variables from an external file so I have replaced them with

    Code:
    varReceiver = new LoadVars();
    varReceiver.load("data.txt");
    varReceiver.onLoad = function(){
    trace(this.data_a);
    trace(this.data_b);
    };
    and I put all the variables + their values in a data.txt file as follows:

    Code:
    data_a=19&data_b=20&data_c=27&data_d=24&data_e=10&data_f=5&data_g=24&data_h=20&data_i=19&day_b=Sunday&day_c=Monday&day_d=Tuesday&day_e=Wednesday&day_f=Thursday&day_g=Friday&day_h=Saturday
    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?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center