-
[RESOLVED] Flex: displaying a calculated amount of icons in an itemRenderer
Hi all,
I want to make a population pyramid like this one: http://geheugenvannederland.nl/?/zoo...26size%3Dlarge
So instead of horizontal bars (1 bar for an age group from for example 0-5 years, the next for 5-10 years, etc) I want to work with a row of icons like in the above picture. I work from real data. The data is divided in year groups which I explained just now. The first row may look something like this: 501735, 492671, 461431, etc.
I have managed to visualise 1 year of data with horizontal bars which looks something like this: http://en.wikipedia.org/wiki/Population_pyramid
In the main application I use this code to pass data on to a custom itemRenderer:
PHP Code:
<s:Form x="136" y="59">
<s:DataGroup id="menRenderer"
dataProvider="{myProxy.populationMen}"
itemRenderer="components.DataItemRenderer">
<s:layout>
<s:VerticalLayout/>
</s:layout>
</s:DataGroup>
<s:DataGroup id="womanRenderer"
dataProvider="{myProxy.populationWomen}"
itemRenderer="components.DataItemRenderer">
<s:layout>
<s:VerticalLayout/>
</s:layout>
</s:DataGroup>
</s:Form>
The itemRender itself looks like this:
PHP Code:
<s:Graphic>
<s:Rect id="menRect" width="{data.data96/10000}" height="5" x="0" y="0">
<s:fill>
<s:SolidColor color="0x99CCFF"/>
</s:fill>
</s:Rect>
</s:Graphic>
As you can see I use this line width="{data.data96/10000}" to convert the really big numbers into a line of reasonable width. So now I have a bar graph. But what I want to do is further render this into a row of for example 50 icons when the population is 500000. So I have two questions:
1. How do I manipulate the data that comes into the renderer? If I try to work with the data like this:
PHP Code:
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var popMen96:ArrayCollection = data.data96;
[Bindable] private var men:ArrayCollection = new ArrayCollection();
[Bindable] private var grain:int = 10000;
for each(var value:Object in data.data96){
men.addItem(value/grain);
}
]]>
</fx:Script>
I get a lot of error messages including that data.data96 is read-only. So how can I further manipulate this data?
2. Can I use a renderer inside a renderer or is that not the way to go about it? My idea is to render the icons inside this renderer passing on the amount after I've calculated it. But maybe this is silly?
I hope someone can set me on the right track. Thanks very much in advance for your help.
// Kind regards, Danielle.
// specs: Flash CS5.5 | Flash Builder 4.6 | win xp pro
-
Some progres
Hi all,
I've managed to solve problem 1. I can now work with the data that comes into the renderer like this:
PHP Code:
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var men:ArrayCollection = new ArrayCollection();
private static const GRAIN:int = 10000;
override public function set data(value:Object):void{
super.data = value;
if(value){
men.addItem(value.data96/GRAIN);
}
}
]]>
</fx:Script>
So now I have an arrayCollection that holds the reduced numbers. So I get 50.1735, 49.2671, 46.1431, 47.3006, etc instead of 501735, 492671, 461431, 473006. What I now want to do is create 50.1735 icons for each row. I've created a dummy component which will hold the icon, for now it is like this:
PHP Code:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:Label text="{data}"/>
<s:Graphic>
<s:Rect id="dummyIcon" width="10" height="10" x="0" y="0">
<s:fill>
<s:SolidColor color="0xFF0000"/>
</s:fill>
</s:Rect>
</s:Graphic>
</s:ItemRenderer>
In the main ItemRenderer I've tried to create it like this:
PHP Code:
<s:DataGroup id="testRenderer"
dataProvider="{men}"
itemRenderer="components.IconRenderer">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:DataGroup>
But (of course) I still only get 1 item for each value. How can I make the item repeat for example 50.1735 time? I've been searching for quite some time on the net but can't find a sollution. So any help is very much appreciated. TIA.
// Kind regards, Danielle.
// specs: Flash CS5.5 | Flash Builder 4.6 | win xp pro
-
Senior Member
First of all make all values even by casting:
men.addItem(int(value.data96/GRAIN));
Then look into the Repeater component or even better the DataGroup component.
http://help.adobe.com/en_US/FlashPla...DataGroup.html
I am not sure it works for your example but it's just an idea.
- The right of the People to create Flash movies shall not be infringed. -
-
Hi cancerinform,
The values shouldn't be even because I want to display parts of icons (mask them for example) to show the remainder.
I'm already working with the datagroup component, view above. The problem is that 50.000 is just a number. I can use it for example to scale one rectangle in the ItemRenderer but I can't figure out how to use that number to multiply that rectangle (or icon in a later stage), if that makes any sense...
Thanks for your help.
// Kind regards, Danielle.
// specs: Flash CS5.5 | Flash Builder 4.6 | win xp pro
-
Senior Member
You need to replace one icon with another DataGroup, where you can place the appropriate number of icons.
PHP Code:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" autoDrawBackground="true"> <s:Label text="{data}"/> <s:DataGroup id="dummyRenderer" dataProvider="{data}" itemRenderer="components.DummyRenderer"> <s:layout> <s:HorizontalLayout/> </s:layout> </s:DataGroup> </s:ItemRenderer>
- The right of the People to create Flash movies shall not be infringed. -
-
Hi again,
I already did that. This is my ItemRenderer class as a whole:
PHP Code:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var men:ArrayCollection = new ArrayCollection();
[Bindable] public static var year:String;
[Bindable] private var yearSet:String = "data96"; //default
private static const GRAIN:int = 10000;
override public function set data(value:Object):void{
super.data = value;
if(value){
men.addItem(value.data96/GRAIN);
}
}
private function setYear():String{
if(year == "1996"){
yearSet = "data96";
}
if(year == "2001"){
yearSet = "data01";
}
if(year == "2006"){
yearSet = "data06";
}
trace(yearSet);
return yearSet;
}
]]>
</fx:Script>
<s:DataGroup id="testRenderer"
dataProvider="{men}"
itemRenderer="components.IconRenderer">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:DataGroup>
</s:ItemRenderer>
It just shows one dummyIcon item per renderer. Maybe I'm overlooking something very basic? Thanks for your help.
// Kind regards, Danielle.
// specs: Flash CS5.5 | Flash Builder 4.6 | win xp pro
-
Senior Member
I think I know what is the problem. The arraycollection "men" has those individual values like 50. or 45. etc. However, the itemrenderer only recognizes this as a single value and therefore puts one dummy. So you need to create subarrays or arraycollections for each individual value with 45 or 50 or whatever number of counts. That would be one way but you can only have integer numbers.
A second method is to create graphic blocks of varying length, which serve as mask. Underneath the mask you have an image with icons. Then you need to change the itemrenderer to something like this:
<s:Rect id="dummyIcon" width="{data * 10}" height="10" x="0" y="0">
- The right of the People to create Flash movies shall not be infringed. -
-
I had considered both your suggestions. I thought it was a bit silly to fill array with individual values, but I understand now that is the way it should be done. I need to animate the visualisation so I'm going for the seconds option and animate the mask. Thanks very much for your help, have a nice week.
// Kind regards, Danielle.
// specs: Flash CS5.5 | Flash Builder 4.6 | win xp pro
-
Senior Member
It's always fun to work out things together.
- The right of the People to create Flash movies shall not be infringed. -
-
It sure is!
I'd like to add that I'm using a slightly different approach, I'm using the an image fill for a rectangle:
<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0" >
<s:fill>
<s:BitmapFill source="@Embed('skins/pattern_147.gif')" fillMode="repeat" />
</s:fill>
</s:Rect>
// Kind regards, Danielle.
// specs: Flash CS5.5 | Flash Builder 4.6 | win xp pro
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|