Display Your Data With Funky Animated Needle Gauges

Display Data With Funky Animated Needle Gauges

Creating appealing data visualization has always been one of Flash’s key features. It allows you to achieve eye candy results with real dynamic data; be it in a preloader, a game, or an office presentation.

This simple tutorial will show you how to build a needle gauge meter. You’ll learn how to apply a “gloss” effect, communicate with XML, and apply a tween engine to rotations.

Step 1: Folder Setup

Create three files: gauge.fla, gauge.xml, and Main.as.

Step 2: XML Structure

Open gauge.xml. This file will contain the data that populates the meters; edit them however you like based on the following structure:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<indicators>
	<gauge>
		<value>64</value>
		<description>Male</description>
	</gauge>
	<gauge>
		<value>26</value>
		<description>Female</description>
	</gauge>
</indicators>

Value is a percentage and so should be between 0 and 100. The description will be displayed on the corresponding gauge.

Step 3: Stage Settings

Open gauge.fla and change the settings as shown below.

Step 4: Create the Gauge Movie Clip

Create a new symbol, name it gauge_mc and set the Class to Gauge.

Step 5: Background Settings

Next, create a circle as shown below:

This will form the gauge’s insides, so name this layer “background”.

Step 6: Add a Surrounding Stroke

Add a stroke using the ink bottle tool (shortcut: S) with the following settings:

(Click on the background circle to apply the stroke.)

Step 7: Create a Frame with Gradient Effects

Switch to the Selection tool, click the stroke to select it, and press Modify > Shape > Convert Lines to Fills. Now, copy the fill and paste it in a new layer, created above the existing layer, called “frame”. Add two new gradient strokes, each one pixel thick. One goes on the inside of the frame, the other goes on the outside.

Step 8: Draw the Pin

Create a new layer, name it “needle pin” and in the center make a small gray circle with a thick black outline:

Step 9: Draw the Needle

Create a new layer underneath the pin’s and name it “needle”. Draw a line, convert the line to a fill and convert this fill to a symbol (called needle_mc).

You need to move both the registration point and the rotation point of this new symbol to the center of the bottom of the line. To move the registration point, double-click the needle to edit, then drag the fill until the registration point is in the correct place. To move the rotation point, go back to editing the gauge_mc symbol, then use the Free Transform tool (shortcut: Q) to double-click the little circle. This will snap it to the registration point of the needle.

Step 10: Draw the Marker’s Ring

Create a new layer beneath the needle’s named “markers”. Draw a circle, smaller than the frame, with a thick black stroke and no fill.

Step 11: Create a Star

On another new layer, select the PolyStar tool, and use it to create a ten-sided star, centered on the needle. We’ll use this to create the little markers around the ring.

Step 12: Connect the Star’s Points to the Center

On the markers layer, draw thin lines from the needle to each point of the star. This way, you know that they are evenly spaced.

Step 13: Create an Inner Circle for Cropping

Create a circle even smaller than the marker ring, then select the lines inside this circle and press delete to erase them all.

Step 14: Further Crops

Erase the inner circle, the outer markers and the bottom section of the marker ring, as highlighted below:

Step 15: Label the Markers

Label the markers: the first as 0, the middle one as 50, and the last as 100.

Step 16: Make the Glassy and Glossy Effects

Create a new layer on top of all the others named “glass” and another one above that named “gloss”.

In the glass layer, draw a white circle the size of the background. Click Window > Color and give it a radial gradient fill, where both colors are white but one has a 20% alpha and the other has a 5% alpha.

In the gloss layer, create two white circles with gradient alphas that go from 70% to 30%. Use the Selection tool to squeeze their shapes to the ones shown below:

Step 17: Add a Description Label

Create another new layer named “label” and add a text field with “label_txt” as its instance name. Don’t forget to embed the font!

Step 18: Add a Value Label

Add a new layer named “value” and add a text field with “value_txt” as its instance name. Again, don’t forget to embed the fonts. I’m using a font called LCDDot, which you can find in the zip file.

Step 19: Correcting the Needle’s Rotation Point

Right now, the needle is pointing at the 50% mark. We need it to be pointing at 0% when it starts, so double-click “needle_mc”, select the fill and rotate it to -143º. This will give us the offset we need.

Step 20: Set the Document Class

Make sure nothing is selected, then in the Properties panel, type Main into the Class box to set Main.as as your document class. Now open it.

Step 21: Import Classes

We will be using GreenSock’s tweening engine, TweenMax. You can download it here: http://blog.greensock.com/tweenmax/

Import the necessary classes for Main.as:

	package {
		import flash.display.MovieClip;
		import flash.events.Event;
		import flash.net.URLLoader;
		import flash.net.URLRequest;
		import com.greensock.TweenMax;
		import com.greensock.events.TweenEvent;
	}

Step 22: Write the Main Constructor

This code should go after “import com.greensock.events.TweenEvent;” but before the last “}”. The Main() function will be the first function run when the SWF loads.

	public class Main extends MovieClip {
		
		private var xmlLoader:URLLoader; //this will load the xml
		private var xml:XML; //this will contain the xml data loaded by the xmlLoader
		private var gauges:Array; //this will store the created gauges
		
		public function Main() {
			gauges = new Array(); //start the array
			xmlLoader = new URLLoader(); //start the loader
			xmlLoader.addEventListener(Event.COMPLETE,updateGauges) //when XML is loaded, updates the gauges
			xmlLoader.load(new URLRequest("gauge.xml")); //initiates the loading of the XML file
			
		}
	}

Step 23: Make the Gauge Move

Put this code before the last two “}” in your file. This function will be run when the XML has loaded.

	private function updateGauges(e:Event):void {
		//populates the xml with the received data
		xml = new XML(e.target.data);
		
		//iterates through the gauges inside the xml structure
		var ln:int = xml.gauge.length();	//number of <gauge>s inside the XML file
		var i:int = 0
		
		while (i < ln) {
			gauges[i] = new Gauge(); //creates a new Gauge and puts it in the gauges[] array
			gauges[i].label_txt.text = xml.gauge[i].description[0].toUpperCase(); //adds the description to the label of the i-th gauge based on the XML's i-th <gauge>
			gauges[i].value_txt.text = "0%" //starts the gauge meter value
			//animates the gauge rotation (286 is the maximum rotation of the needle we built)
			var tm:TweenMax = new TweenMax(gauges[i].needle_mc, 2, { rotation:Math.round(xml.gauge[i].value[0] * 286 / 100) } );
			//this event is activated when the tween value changes; we do this to update the value text according to the needle position
			tm.addEventListener(TweenEvent.UPDATE, onTween)
			//y positioning
			gauges[i].y = 45
			//x positioning (220 pixels of distance between them and 50 pixels offset from the left margin
			gauges[i].x = (i * 220) + 50
			//adds to stage
			addChild(gauges[i]);
			//increases i for the next iteration
			i++
		}
	}

Step 24: Make the Numbers Change

Again, insert this before the last two “}” in your code. This function is run repeatedly as the needle is tweened (rotated).

	private function onTween(e:Event):void {
		/*this will prevent a well known rotation bug inside flash
		 * where, when rotating, after it reaches 180º it starts to count up from -180
		 * (i.e. 0 to 180, -180 to 0). By adding 360 to the equation when the rotation is negative
		 * we can make sure the value is correct.
		 * */
		if (e.target.target.rotation < 0) {
			e.target.target.parent.value_txt.text = (Math.round( (360+e.target.target.rotation) * 100 / 286) + "%");
		}else{
			e.target.target.parent.value_txt.text = (Math.round( e.target.target.rotation * 100 / 286) + "%");
		}
	}

Step 25: Check Out the Full Code

Confused about where any of the code should go? Check it out here.

Step 26: Finish Up

Now all you need is to head back to gauge.fla, and in the first frame add a background and a title:

Conclusion

As you can see, it’s easier than it looks. Take your time and expand upon the concept: make a preloader, a bandwidth meter, whatever you like. Hope you enjoyed this tutorial, thanks for reading!

  • http://www.hsp.dk Henrik Pedersen

    To me, the needle looks like it’s aint right in the center, as if the needle is rotated around the corner of itself…

    But still a very nice applikation and defently usefull.. I’m thinking about integretaing it with our household power usage via .NET, PHP and so of course flash :D

    • Bruno Crociquia
      Author

      now that you mention it, i think your right, i must have nudged it a bit without noticing…

      • Johann

        Hi,

        Cool gauge. I got it running fine. However, my application is a bit different. This is what I got:
        I want to embed the gauge onto a web page so it will dynamically update its value in real time from a PLC. The data is provided in html as

        http://my_ip/readreg.htm;reg-R2;fmt-INT;rfs-5

        How can I modify your code to allow this value to update the gauge.xml value, or directly update the gauge value in Main.as? So basically, the code needs to get the remote value and then update the meter with that value.

        Any help will be greatly appreciated.

        Thanks.

  • Pingback: uberVU - social comments

  • André

    Wow, it´s very nice my friend… I will give some tips…

    Would be nice if you created a property in Gauge like .value, a value between 0 to 100, in percentage, so you can create the gauge any time and wont need to calculate the rotation everytime…

    I will create now a tutorial on how to create custom components for flash using some of this techniques.

    • Bruno Crociquia
      Author

      sounds awsome :)

  • http://www.personabledesign.com Chris

    This is such a wonderful tut – thanks!

  • http://www.elquefaltaba.es/qborreda.html qborreda

    Nice little tut. The good thing about this whole one is that you can learn to use the tweens to calculate values of a variable, using the TweenEvent methods like you used : tm.addEventListener(TweenEvent.UPDATE, onTween)

    Tip: you don’t really need to have any actual visual effect going on, but still, it will trigger the UPDATE event and call the function.

    Nice one Bruno.

  • Pingback: Domain-Inventory.com International Domain Names ccTLDs. Garrick Davis, Funky Doodle | World online hosting review

  • http://www.ricardofilipe.com Ricardo

    Thank you so much for this tutorial. It is exactly what I’ve been needing to write a cool weather application. Now I have animated gauges to show both temperature and wind speed ;)

    Thanks.

  • milkywayer

    Nice tutorial. was looking for a tut on how to make a guage like this. Thanks!

  • Joao Aliano

    Nice one! Congrats, Bruno =)

  • Konstantin

    I couldn’t get this part:
    > if (e.target.target.rotation < 0) {
    e.target.target.parent.value_txt.text = (Math.round( (360+e.target.target.rotation) * 100 / 286) + "%");

    Can you, please, explain it in detail? :)

    I just can't understand why is it multiplied by 100 and where does the number 286 come from?

    I'd really appreciate the explanation :-)

    • Bruno Crociquia
      Author

      What we are doing here is basic algebra

      A simple rule of three equation, an ancient mechanical method to find out a greatness value of two directly or indirectly proportioned greatness, basically finding out a proportion between two different measures.

      What i need to do here is to see to how much degrees a given percentage corresponds.

      In this case 286 is the maximum amount of degrees my gauge is allowed to move within the range of 0 to 100 percent.

      if you know your math then you will know that:

      because
      curdegree/maxdegrees == curpercentage/maxpercentage

      and curpercentage is what i’m trying to find, then

      currentdegree*maximumpercentage/maximumdegrees = currentpercentage

      I Math.rounded so i could have a full value and i added 360 to prevent the bug i commented about on the code.

      Hope i could help

      Cheers

  • http://switch-design.com Matt

    I’m just getting back into flash so maybe I’m missing but I’m trying to get the needle to rotate but no matter where I put the registration point it always rotates from the centre. Any ideas?

    • sean

      You gotta move both the registration pt and the rotation pt, see step 9…

      nice tutorial, I may use with flash vars via php rather than xml, but good to have both ways, thanx

  • Lo

    Thanks so much for this tutorial, I am going to impress my boss!!!!

  • jon

    that’s awesome! How would you change this if you just wanted display a value with markers numbered like a speedometer instead of percentage.

  • raj

    i am gating error pleas help me (gauges [i] = Gauge(); //creates a new Gauge)

  • raj

    sorry it works great boos thanks

  • James

    Hi, i want manipulate arrow, in value 252 or 575 and etc. how i can set in position arrow? very need, help