Displaying an item renderer balloon above the data point - apache-flex

I'm using a custom item renderer for an AreaChart:
<mx:AreaChart id="numParticipants" left="10" right="10" top="10"
bottom="10" color="#8D8D8D"
dataProvider="{UsersModel.graphData.data_points.point}" dataTipMode="multiple"
dataTipRenderer="tooltip.ChartTooltip" fontSize="9" mouseSensitivity="10"
seriesFilters="[]" showDataTips="true" >
inside it's data set:
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="180" height="42">
<mx:Style source="css/style.css"/>
<mx:Script>
<![CDATA[
import models.UsersModel;
import mx.charts.HitData;
import mx.formatters.DateFormatter;
override public function set data(value:Object):void
{
I'm displaying my text.
However, I want the balloon to be exactly above the data point.
I tried to change the (x,y) coordinates but it doesn't seem to change.
How can I move this balloon around to a desired location?

I'm afraid that using your own custom location is not something within the scope of the datatip (I know, stupid right?). It's meant to be used just as a set and forget it kind of this.
If you want, you can create your own custom data tips by simply using the popup manager when you hover over your data. You'll have a lot more flexibility in a lot of other aspects as well, but of course, this means more code for you to create and test.
EDIT:
Another thing came to mind, and that would be to extend the chart itself which controls the datatips and adding your own functionality of where/how to move the datatip. I found this post on how to change the behavior of line charts.

Just stumbled on a solution, so I'm posting for future generations.
Simply override the move function of the tool tip renderer:
override public function move(x:Number, y:Number):void
{
super.move(x+10, y+10); // just sample
}
HTH

Probably the quickest (but not necesarily a good practice) is to use a UIComponent as the base Class for your dataTipRenderer (UIComponent doesn't measure or lay out anything). Measure and lay out everything in updateDisplayList, and move everything up and to the left within the UIComponent until it is where you want it relative to the data point. Leave your measure() method empty (so the measured size is 0, 0), and Flex will put the top left corner of the UIComponent (that you've moved things to be above and to the left of) above your data point.

Related

Horizontal List or Carousel for Flex mobile?

Im creating a person search interface in Adobe Flex / Actionscript where we have an image for each person and a bit of text. Im looking to implement some like this:
HorizontalList Interface
OR
Carousel Interface
Both of these packages are unfortunately only for desktop Flex, I was wondering if anyone knew mobile flex (particularly Blackberry Playbook) alternatives?
Thanks
Phil
If you're using the standard s:List, you can change its layout property to a HorizontalLayout instance.
Basically, something like this:
<s:List>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:List>
Maybe you could use a TileList instead. This is a horizontal list that automatically uses the next row if the page is full. You can fill it with data by using the DataProvider tag.
Here is an example:
<mx:TileList id="tileList" borderStyle="none" paddingBottom="0"
paddingTop="5" paddingLeft="5" paddingRight="5" itemClick="onClickHandler(event)"
dataProvider="{yourArrayList}" itemRenderer="renderer.WidgetRenderer" />
The class widgetrenderer creates my imageButtons (so normal images can be used too). These buttons are made of the data in my arraylist that can be approached by data.(the item in the arraylist his properties) If you need the clicked item you can use the id of your tilelist and choose for selected item.
In this example:
var object:Object = tileList.selectedItem;
I don't know if you understand my explanation, if not feel free to ask.
I hope this could help you.
There is a perfect example of this in tour de flex that uses a custom layout with the postLayoutTransform properties to build the 3d effect.
I don't know how to link to the specific example, but if you go here just click on Other Components -> Layouts -> Carousel
Cheers!
Horizontal List should work fine on mobile!

Extending DataGrid component, and adding buttons to it

I'd like to extend the standard DataGrid component in flex with mxml. But I want to add buttons to the bottom of the component. I've tried attempting the following but its not working...
Am I adding the Button to the wrong element?
<mx:DataGrid xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:mx = "library://ns.adobe.com/flex/mx"
xmlns:s = "library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
override protected function createChildren():void
{
super.createChildren();
listContent.addChild(button);
}
]]>
</fx:Script>
<s:Button id="button" label = "asdasdas"/>
</mx:DataGrid>
You need to define "Not working"! Are you getting compiler errors? Or runtime errors? Or is the button just not showing up? I'll assume the latter.
The DataGrid does not have any mechanism for positioning or laying out it's children. Your button most likely has a height and width of zero and resides at position 0,0; making it effectively invisible. Many Flex container classes have the ability to size and position their children; but the DataGrid is not a container and does not provide built in functionality for that. It focuses, primarily, on working with the columns array.
You will need to override the updateDisplayList() to position the function. Quite possibly you will need to make changes to commitProperties() and measure() along the way. You may also need to re-work how the columns are positioned and sized as to not interfere with your new button. If stuff is locked away in private methods (which is probable) then you're in a for a not-so-fun-time.
Read up on the Flex Component LifeCycle methods for more information and also review the DataGrid code to figure out what it does.
You may have an easier time just putting the button and DataGrid in a container, and treating that container as a single entity instead of trying to get a Button renderered inside of the DataGrid.
Got it. All I needed to do was replace listContent.addChild(button); with...
parent.addChild(button);
Thanks!

Flex : Cross resolution applications

What is the best way to create applications in Flex/AIR,
which look and feel the same irrespective of the screen
resolution?
When creating the layout in your flex application, you can achieve a consistent screen resolution independent look and feel from using relative scaling.
This is much akin to creating a liquid layout with HTML.
For example, to create a simple two column application— left navigation and content— you only need two containers, one predefined and one left to scale indefinitely.
As follows:
<mx:HBox width="225">
<mx:Button label="Menu 1"/>
<mx:Button label="Menu 2"/>
<mx:Button label="Menu 3"/>
</mx:HBox>
<mx:HBox width="100%">
Any content here will flow fluidly across the entire screen regardless of window size/screen resolution.
</mx:HBox>
Using the above basics you can create a application layout that forms to any screen.
However, sometimes you need to create a more elaborate layout scheme with many interchanging components resizing dynamically to fit the window.
For this you can do Absolute Positioning.
override the components updateDisplayList() function and create your own sizing/positioning rules.
This of course requires you to be within a Canvas container or have the main Application container set to absolute layout.
A simple example:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
{
//find out how big we are
var stageWidth:int = this.width;
//center the box in the middle of the page.
centeredBox.x = stageWidth - (centeredBox/2);
}
</mx:Script>
<mx:HBox id="centeredBox" width="500"/>
</mx:Application>
By overriding updateDisplayList() you can create endless ways to better dynamically position and size your components to better use the screen realestate.
You can create a application with height and width respective to the container so that way all components will aling themself properly at all screen resolutions.
We typically create a MainFrame.mxml which acts as our primary component and has layout relative scaling as mentioned by the others. Then we create the AIR app which just embeds that one MainFrame.mxml and another Flex app that embeds it as well. This way we can keep the entire app within MainFrame and not worry about if it is in Flex or Air. This being said you will need to make sure you do not use any AIR specific or Flex specific calls that do not translate to the other.

Flex custom button component

I want my custom button to look like the button sample below.
More specifically, I want the width of the button to be determined by the width of the largest word in the label (i.e. width of "Elongated" in my example). The label must wrap, not truncate.
And I want only one pixel between the top edge of the icon and my button's top edge.
I have tried lots of things but to no avail so far. I have reduced the horizontalGap and verticalGap to zero and padding to zero. But still nothing. Please help.
Here's what I have right now:
<mx:Button top="0" cornerRadius="2" paddingLeft="0" paddingRight="0" leading="0" letterSpacing="0" paddingTop="0" paddingBottom="0" verticalGap="0" horizontalGap="0" textAlign="center" labelPlacement="bottom" icon="{MyIcon}" height="60" width="75" label="Elongated Label" fontSize="10" />
That's not at all simple.
You will need to create your own button,
public class Mybutton extends Button {...}
override createChildren and set the word wrap of the IUITextField used for the label to true.
override measure and use your own line metrics to determine the width that the button should be. If you get the measure right, the button will lay itself out properly.
I don't have a dev environment in front of me at the moment, but something along these lines should work:
Set truncateToFit property of the Label to false (OR use a TextField with wordWrap set to true - I think this should keep the words together as much as possible).
I haven't had the need to use any of the above yet, and hopefully you haven't tried them yet because it would be an easy solution to a part of your problem. Without any code, I'm not sure why padding didn't work, but maybe it's something to do with the word truncation.
As an alternative, why not use a Button, embed or specify a source for your icon and decide where to place the text by specifying the object's labelPlacement property?
EDIT: Since there's no property in Button about wordWrap, as they would recommend in the Adobe Flex forums for such questions regarding sizing based on content where there is no automatic feature to do that, you have to find the longest word and adjust the width of the button (i.e.: in the creationComplete event). Experimenting to find the font to pixel ratio would be my best bet (or you can use a Monospace font where all the characters are given the same space thereby simplifying the estimation):
creationComplete="event.target.width=returnMyWidth();"
As for the padding, it may be related to the custom width that you had set or it may be from embedding the image automatically setting a padding by being included - I'm not really sure, so it would be good if someone can offer a comment based on experience with this.

How can I create a Flex application with dynamic height?

Is there a way to allow a flex application to have a dynamic height while embedded in an HTML wrapper?
I want the Flex application to grow in height in a way that it will not cause vertical scroll bars.
The best way should be overriding the Application's measure method like:
private var _lastMeasuredHeight:int;
override protected function measure():void
{
super.measure();
if (measuredHeight != _lastMeasuredHeight)
{
_lastMeasuredHeight = measuredHeight;
if (ExternalInterface.available)
{
ExternalInterface.call("setFlashHeight", measuredHeight);
}
}
}
This function assumes that you have a javascript function named setFlashHeight which can accept a height (or whatever you name it) parameter. An example would be:
function setFlashHeight(newHeight){
//assuming flashDiv is the name of the div contains flex app.
var flashContentHolderDiv = document.getElementById('flashDiv');
flashContentHolderDiv.style.height = newHeight;
}
I use swfobject to embed my flex applications. So the flash object resides inside a div. If yours not; the js function could easily be altered to set the flash object's height. When you implement this solution, you'll notice that scrollBars aren't working as flash consumes the event. But that's another subject...
This is possible. For an example, see the new Kontain by fi. You can see it directly in action by creating a new blog post and adding lines to the entry field. As the entry field grows in size, the page gets taller.
You'll have to coordinate between Flash and Javascript via ExternalInterface. When your Flex app needs to change size, find the new size (probably by digging into Flex's layout engine) and throw that up to a Javascript function via ExternalInterface. The javascript then can set a new height property on the container. You'll probably also want to set verticalScrollPolicy="off" on your tag so that Flex doesn't show the scroll bars when the layout engine runs.
I'm not sure I fully understand the question, are you trying to get the aplication to have a size larger than the browser's view port? If so, then as #hasseg commented and #RickDT mentioned, you can set the Application's horizontalScrollPolicy and/or verticalScrollPolicy properties to "off"?
If you're simply trying to make sure your application scales with changes to the browser's shape and size, then make sure you set the following (or values that suit) in your outer most application tag.
percentWidth="100"
percentHeight="100"
Unfortunately no, I think the only way you could do this is to get rid of the html wrapper in the first place. HTH.
There is no need for all that, just change the application from spark to mx. this will show it automaticly because I think spark does not support that at all ( I think it's stupid bug from adobe )
like this:
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009" >
</mx:Application>
instead of:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" >
</s:Application>
leave application tag without height specification "don't use height="100%"

Resources