I would like to scroll the amcharts flex stock chart programmatically on it's horizontal axis, in other words along the time axis.
I need to do this, because I need to scroll one period at a time and would like to hook this up to keyboard events.
I couldn't find anything in the documentation here: http://flex.amcharts.com/stock_class_reference/com/amcharts/stock/package-detail.html
I've also tried mucking around with the period selector to see whether I can change the values on it, but no luck there.
You should simply set some interval and zoom chart each time. For example:
private function initialZoom():void
{
var firstDate:Date = dataSet.dataProvider[0].date;
var endDate:Date = new Date(firstDate);
endDate.setDate(endDate.getDate() + 20);
chart.zoom(firstDate, endDate);
setInterval(zoomChart, 1000);
}
private function zoomChart():void
{
var startDate:Date = new Date(chart.startDate);
var endDate:Date = new Date(chart.endDate);
startDate.setDate(startDate.getDate() + 1);
endDate.setDate(endDate.getDate() + 1);
chart.zoom(startDate, endDate);
}
initialZoom should be called on dataUpdated event fired by AmStockChart. Note, you shouldn't set any period as "selected" in order this to work.
Related
I'm having a problem similar to FLEX: dialog not display immediately . Code follows:
private function saveBitmap(event:ContextMenuEvent):void
{
loadingScreen.visible = true;
loadingScreen.appLoadingText.text = "Preparing bitmap...";
addChild(loadingScreen);
validateNow();
var bmpd:BitmapData = new BitmapData(canv.width, canv.height);
bmpd.draw(canv);
var fr:FileReference = new FileReference();
fr.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, removeLoadingScreen);
fr.addEventListener(Event.CANCEL, removeLoadingScreen);
var png:PNGEncoder = new PNGEncoder();
var iba:ByteArray = png.encode(bmpd);
fr.save(iba, "export.png");
}
Basically, bmpd.draw and/or png.encode are dog slow, so I'd like to have a nice "please hold while we prepare your png" dialog to appear. I can't use callLater() because of the FileReference.
And just for good measure, the loading screen appears at the same time the save dialog appears from the call to fr.save().
Any ideas?
Cheers!
You're adding the child in this function. Are you doing any other work to the loadingScreen, such as sizing it? Or positioning it? Most commonly this is done in updateDisplayList(). What container are you using?
Are you sure the Z-order of your two children is correct? You can swap children with the swapChildren method
I'm a beginner in Flex so there must be more elegant way of doing this.
//move effect
private var m:Move = new Move();
//this function creates labels with some text and starts move effect on them
public function moveText(i:int):void {
var myLabel:Label = new Label();
myLabel.text = "some text";
m.target = myLabel;
...
m.play();
}
Method moveText is called in a loop so I guess that labels don't get "garbage collected".
What I want to do is to remove Labels created in moveText method after play animation ends.
Another way of doing this is maybe creating some kind of "pool" of labels which I would use to move arround text. I don't know how would I return labels in to "pool".
The question is how to do something after effect animation ends?
You can listen to the EffectEnd event.
Check out here
Look at the effectEnd event in the Effect class. You can put a handler in there that does your garbage collection.
for (iss = 0; iss < listOfProductIds2.length; iss++)
{
// Alert.show(listOfProductIds2[iss]);
var productMain:VBox=new VBox();
var p1:HBox=new HBox();
var l1:Label=new Label();
var b1:Button=new Button();
var spacer:Spacer=new Spacer();
spacer.width=300;
b1.label="Remove";
b1.setConstraintValue("id","");
b1.addEventListener(MouseEvent.CLICK,removeProduct);
l1.text="Product "+iss;
p1.setActualSize(500,500);
p1.addChild(l1);
p1.addChild(spacer);
p1.addChild(b1);
productMain.addChild(p1);
}
function removeProduct(event:MouseEvent):void
{
// How do i know which button is clicked
}
Use event.currentTarget (instead of event.target) because event.target might be the Label component or some styling component within the button, but currentTarget is assured to be the object with which the listener was registered.
To get a handle to the button that was clicked you can just cast the currentTarget to a button.
function removeProduct(event:MouseEvent):void
{
var b1:Button = Button(event.currentTarget);
}
The method setConstraintValue is for setting layout constraints, not setting id. The id property is used by mxml for creating variable names for objects. You can get/set id as you would get/set any other property (say width) - but neither have I seen anyone doing that nor do I see any need to do that in the first place.
event.target should point to the Button you clicked on, shouldn't it ? However you should probably give ids to the buttons to be able to differenciate them (since you create them dynamically.)
Look at event.target.
If ids are assigned dynamically as in the example given b1.id = "button_" + listOfProductIds2[iss]
Then the function that processes the click event would look at the currenttarget, and what I usually do is do a string replace on the part of the id that you know is not dynamic like "button_" with "", which leaves you with the name of the product.
Is there anyway I can effectively call the equiv. of setText on a Flex Graphics object ?
Specifically I'm using a custom cell renderer to display data in a datagrid. The renderer uses the Graphics object to set the background colour of only a portion of the cell (say the left half) based upon the underlying data. I would like to be able to have text over only that portion of the cell which has the background colour (eg centred within the left half).
I know all the widths (of both the cell itself and the graphics object) but I don't know how I can set text (centred) over the graphics object.
Anyone got any ideas pls?
Tks vm
Here's a solution that avoids adding UI components:
private function WriteText(text:String, rect:Rectangle):void
{
var uit:UITextField = new UITextField();
uit.text = text;
uit.width = rect.width;
var textBitmapData:BitmapData = ImageSnapshot.captureBitmapData(uit);
var matrix:Matrix = new Matrix();
var x:int = rect.x;
var y:int = rect.y;
matrix.tx = x;
matrix.ty = y;
graphics.beginBitmapFill(textBitmapData,matrix,false);
graphics.drawRect(x,y,uit.measuredWidth,uit.measuredHeight);
graphics.endFill();
}
The idea is to use the UITextField to create a bitmap, that can be used with the graphics object to fill a rectangle.
This is based on a blog post by Olga Korokhina at Adobe Developer Connection.
The short answer is that you can't draw text programmatically with a Graphics object. What you'll need to do is create one of the Text-like classes (e.g. Label, Text, etc.) and position that appropriately within your cell renderer.
Assuming that you're doing your custom painting in updateDisplayList, you'd want to do something like the following:
override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
{
super.updateDisplayList( unscaledWidth, unscaledHeight );
// perform all your custom painting
var label:Label = new Label();
label.text = "Some text";
label.width = widthOfCustomPainting;
// can also set x- and y-coordinates of label too
label.setStyle( "textAlign", "center" );
this.addChild( label );
}
This will need some tweaking based on how your item renderer is set up, but it should pretty much be what you need.
Note that my code above does not use best practices for custom item renderers. It would be worthwhile to take a look at this excellent blog post which describes how to properly create item renderers.
Polygonal labs comes up with a solution that convert the font to vector curves so that you can draw the text as graphics. See it here. The code has not been published, but you can see some similar projects in the comments.
But you will need to do it in AS instead of MXML or you write you own class for that.
using textformat for uit's defaulttextformat is the solution of my problem...
Greetings!
I'm calling a Web service from Javascript when a user clicks on a link. I need to get the coordinates where the user clicked so that I can display a DIV in an appropriate location. My client-side script looks like the following:
var g_event;
function DoWork(event, theId)
{
if (IsIE())
g_event = window.event;
else
g_event = event;
Acme.WebServices.Worker.GetInformation(theId, DoWorkSuccess);
}
function DoWorkSuccess(result)
{
var l_elemDiv = document.getElementById("content-area-div");
DisplayAreaDiv(g_event, l_elemDiv, result);
}
It's used like this:
Help
This works great in Firefox, Safari, and Opera. In IE7, not so much. For example, if I place the following code at the end of both the DoWork() and DoWorkSuccess() functions:
alert(g_event.clientX + ", " + g_event.clientY);
In IE, I'll get two alerts; the first one has correct coordinates, but the second one (which displays on top of the first one) is simply "[object]". Since that "[object]" one is the last one, my DIV is incorrectly displayed in the top left of the browser window. Is there a way I can prevent IE from giving me a second "bad" event? Thanks.
Why not extract and save the coordinates in DoWork and simply use them in DoWorkSuccess rather than saving the event. Of course this won't work if there is more data you are extracting from the event.
var client_x;
var client_y;
function DoWork(event, theId)
{
var g_event;
if (IsIE())
g_event = window.event;
else
g_event = event;
client_x = g_event.clientX;
client_y = g_event.clientY;
Acme.WebServices.Worker.GetInformation(theId, DoWorkSuccess);
}
function DoWorkSuccess(result)
{
var l_elemDiv = document.getElementById("content-area-div");
DisplayAreaDiv( { clientX : client_x, clientY : client_y }, l_elemDiv, result);
}
Have you tried setting window.event.cancelBubble = true in your DoWork function?
If not, quirks mode has good article on events and event bubbling - http://www.quirksmode.org/js/events_order.html that has helped me a lot with these kinds of issues.