Is it possible to create a packed bubble chart in Flex like the following example?
Source: http://blog.tiger.com.pl/wp-content/uploads/2013/06/bubble2.jpg
I googled it and didn't find anything. If there is not a native way to do it, can someone suggest how I could draw it myself?
Well, after searching and searching I found a library called flare here you can see an example of what I was looking for demo at Layout/Bubbles. But everything was done in Actionscript 3. Then I started to create my own class to be used in Flex and I got it. Here is the code of the class I wrote.
package classes
{
import flare.animate.FunctionSequence;
import flare.animate.Transition;
import flare.animate.TransitionEvent;
import flare.animate.Transitioner;
import flare.display.TextSprite;
import flare.query.methods.add;
import flare.query.methods.div;
import flare.query.methods.mul;
import flare.util.Shapes;
import flare.util.Strings;
import flare.vis.Visualization;
import flare.vis.controls.DragControl;
import flare.vis.controls.ExpandControl;
import flare.vis.controls.HoverControl;
import flare.vis.controls.IControl;
import flare.vis.controls.TooltipControl;
import flare.vis.data.Data;
import flare.vis.data.DataList;
import flare.vis.data.DataSprite;
import flare.vis.data.NodeSprite;
import flare.vis.events.SelectionEvent;
import flare.vis.events.TooltipEvent;
import flare.vis.operator.OperatorSwitch;
import flare.vis.operator.encoder.PropertyEncoder;
import flare.vis.operator.label.Labeler;
import flare.vis.operator.layout.CircleLayout;
import flare.vis.operator.layout.CirclePackingLayout;
import flare.vis.operator.layout.DendrogramLayout;
import flare.vis.operator.layout.ForceDirectedLayout;
import flare.vis.operator.layout.IcicleTreeLayout;
import flare.vis.operator.layout.IndentedTreeLayout;
import flare.vis.operator.layout.Layout;
import flare.vis.operator.layout.NodeLinkTreeLayout;
import flare.vis.operator.layout.RadialTreeLayout;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import mx.core.Container;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.ResizeEvent;
public class PackedBubblesChart extends UIComponent {
public static const DEFAULT_FLEX_SERIES_COLORS:Array = [
0xe48701, 0xa5bc4e, 0x1b95d9, 0xcaca9e,
0x6693b0, 0xf05e27, 0x86d1e4, 0xe4f9a0,
0xffd512, 0x75b000, 0x0662b0, 0xede8c6,
0xcc3300, 0xd1dfe7, 0x52d4ca, 0xc5e05d,
0xe7c174, 0xfff797, 0xc5f68f, 0xbdf1e6,
0x9e987d, 0xeb988d, 0x91c9e5, 0x93dc4a,
0xffb900, 0x9ebbcd, 0x009797, 0x0db2c2
];
// Constructor
public function PackedBubblesChart() {
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
}
protected function addedToStage(event: Event) : void {
(this.parent as Container).addEventListener(ResizeEvent.RESIZE, resizeBubbleChart);
tryRender();
}
protected function removedFromStage(event: Event) : void {
clearNodes();
(this.parent as Container).removeEventListener(ResizeEvent.RESIZE, resizeBubbleChart);
}
protected function clearNodes() : void {
if(vis) {
for each(var sprite : DataSprite in _nodesInformation.nodes) {
sprite.parent.removeChild(sprite);
}
vis = null;
}
}
protected function resizeBubbleChart(event:ResizeEvent) : void {
_bounds = new Rectangle(0, 0, parent.width, parent.height);
tryRender();
}
private var _init:Boolean = false;
private var _bounds:Rectangle;
public var labelField : String = "label";
public var valueField : String = "value";
public function get bounds():Rectangle { return _bounds; }
public function set bounds(b:Rectangle):void {
_bounds = b;
resize();
}
private var _dataProvider : Array = [];
private var _nodesInformation : Data = new Data();
private var _nodeDefaultFormat : Object =
{
name: "Bubbles",
op: new CirclePackingLayout(8, false, "depth"),
nodes:{
shape: Shapes.CIRCLE,
fillColor: 0x11aaaaaa,
lineColor: 0xdddddddd,
lineWidth: 4,
alpha: 1,
visible: true
},
edges: {alpha:0, visible:false},
ctrl: new DragControl(NodeSprite),
canStraighten: true
}
public function get dataProvider() : Array {
return _dataProvider;
}
public function set dataProvider(info : Array) : void {
/*
if(vis && _dataProvider && _dataProvider.length > 0) {
for each(var sprite : DataSprite in _nodesInformation.nodes) {
sprite.parent.removeChild(sprite);
}
vis = null;
}
*/
_dataProvider = info;
tryRender();
}
protected function tryRender() : void {
if(parent) _bounds = new Rectangle(0,0,parent.width, parent.height);
if(_dataProvider && _dataProvider.length > 0 && _bounds) {
clearNodes();
_nodesInformation = createNodes(_dataProvider.length);
_nodesInformation.nodes.setProperties(_nodeDefaultFormat.nodes);
var index : uint = 0;
for each(var item : Object in _dataProvider) {
var labelText : String = item[labelField];
var valueNumber : Number = item[valueField];
_nodesInformation.nodes[index].data.label = labelText;
_nodesInformation.nodes[index].buttonMode = true;
_nodesInformation.nodes[index].size = item[valueField];
_nodesInformation.nodes[index].props.value = valueNumber;
_nodesInformation.nodes[index].props.name =labelText;
_nodesInformation.nodes[index].props.name_value = labelText+"\n("+valueNumber+")";
_nodesInformation.nodes[index].fillColor = 0xff000000 + DEFAULT_FLEX_SERIES_COLORS[index % 28];
index++;
}
_nodesInformation.nodes.sortBy("props.value");
// create the visualization
vis = new Visualization(_nodesInformation);
vis.bounds = bounds;
vis.operators.add(_nodeDefaultFormat.op);
vis.setOperator("nodes", new PropertyEncoder(_nodeDefaultFormat.nodes, "nodes"));
vis.operators.add(new Labeler("props.name_value", Data.NODES,new TextFormat("Arial",12,0,true,null,null,null,null, TextFormatAlign.CENTER),null));
vis.controls.add(new TooltipControl(DataSprite, null,
function(evt:TooltipEvent):void {
var d:DataSprite = evt.node;
TextSprite(evt.tooltip).htmlText = Strings.format(_tipText, d.props.name, d.props.value);
}
));
init();
}
}
public static function createNodes(n:uint):Data {
var g:Data = new Data();
for (var i:uint=0; i < n; i++) {
var node:NodeSprite = g.addNode();
node.data.label = String(i);
}
return g;
}
public function set toolTipFormat(value : String) : void {
_tipText = value;
}
private var _tipText:String = "<b>Label</b>: {0}<br/><b>Value</b>: {1}";
private var vis:Visualization;
private var os:OperatorSwitch;
private var shape:String = null;
public function init():void {
vis.controls.add(new HoverControl(NodeSprite,
// by default, move highlighted items to front
HoverControl.MOVE_AND_RETURN,
// highlight node border on mouse over
function(e:SelectionEvent):void {
e.node.lineWidth = 10;
e.node.lineColor = 0x88ff0000;
},
// remove highlight on mouse out
function(e:SelectionEvent):void {
e.node.lineWidth = 4;
e.node.lineColor = _nodeDefaultFormat.nodes.lineColor;
}));
vis.controls.add(_nodeDefaultFormat.ctrl);
vis.update();
addChild(vis);
}
public function resize():void
{
if (vis) {
vis.bounds = bounds;
vis.update();
}
}
}
}
And here is an application example of what to use it in flex
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
minWidth="955" minHeight="600" creationComplete="init(event)" layout="vertical"
verticalAlign="middle">
<mx:Script>
<![CDATA[
import classes.PackedBubblesChart;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
protected var companies : Array = [];
protected var otherCompanies : Array = [];
protected var bubbleChart : PackedBubblesChart = new PackedBubblesChart();
protected function init(event:FlexEvent):void {
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Sunray Management Group", count:92});
companies.push({company_name:"Chevron", count:145});
companies.push({company_name:"Nabors", count:35});
companies.push({company_name:"Milicom", count:23});
companies.push({company_name:"gNostos", count:200});
companies.push({company_name:"Cisco", count:43});
otherCompanies.push({company_name:"Chevron", count:145});
otherCompanies.push({company_name:"Nabors", count:35});
otherCompanies.push({company_name:"Milicom", count:23});
otherCompanies.push({company_name:"gNostos", count:200});
bubbleChart.labelField = "company_name";
bubbleChart.valueField = "count";
bubbleChart.toolTipFormat = "<b>Company</b>: {0}<br/><b>Count</b>: {1}";
bubbleChart.dataProvider = companies;
canvas.addChild(bubbleChart);
}
protected function button_clickHandler(event:MouseEvent):void {
if(bubbleChart.dataProvider == companies) bubbleChart.dataProvider = otherCompanies;
else bubbleChart.dataProvider = companies;
}
]]>
</mx:Script>
<mx:Canvas id="canvas" width="100%" height="100%">
</mx:Canvas>
<mx:Button label="New data provider" click="button_clickHandler(event)"/>
</mx:Application>
Well, I answer my own question because I think it could be useful for other people.
Sorry for my english.
this was the result... Ah, Beautyful. Thanks to Flare people.
I am working on Flex 4.6 Air application in which there is a list and the data is transparent background swf file. My problem is that when i double click on the list item the respected swf file should be play in the background or we can say on desktop like virtual girl application. if we minimize the main application, swf should be play on desktop like virtual girl application.
If anybody have any idea please tell me.
Thnank You so much.
You can use the following code in which you will open a mx or spark window on double click of list item.
May be the following code useful for you.
<?xml version="1.0" encoding="utf-8"?>
<s:Window xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:customcomponents="customs.customcomponents.*"
xmlns:services="services.*"
width="100%" height="100%" backgroundAlpha="0"
creationComplete="window1_creationCompleteHandler(event)" minimizable="false"
showStatusBar="false" systemChrome="none" transparent="true">
<fx:Script>
<![CDATA[
import air.net.URLMonitor;
import dbconnection.Connection;
import globalData.DataModel;
import mx.collections.ArrayCollection;
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import mx.utils.UIDUtil;
import vo.UserSettingsVo;
private var movie:MovieClip;
private var movieTotalFrame:int = 0;
public var countMovie:int = 0;
public var timer:Timer;
private var newRate:int = 0;
private var mainScreen:Screen = Screen.mainScreen;
private var newStyle:CSSStyleDeclaration;
private var flagPreNext:String="";
private var flagFullMin:Boolean = false;
private var monitor:URLMonitor;
private var timerClosePop:Timer;
private var sqlStatStatus:SQLStatement;
private var objSelectedItem:Object;
[Bindable]
private var modellocator:DataModel = DataModel.getInstance();
[Bindable]
private var uservo:UserSettingsVo = UserSettingsVo.getInstance();
private var connection:Connection = Connection.getInstance();
protected function window1_creationCompleteHandler(event:FlexEvent):void
{
seqEffect.target = this;
rotate.target = canDesktopVideo;
loadMovie(0);
}
protected function myVidTeaser_completeHandler(event:Event):void
{
trace(modellocator.arrMovie[countMovie].Videoname.toString());
movie = myVidTeaser.content as MovieClip;
if(movie != null)
{
movieTotalFrame = movie.totalFrames;
var sizeWidth:Number = 0;
var sizeHeight:Number = 0;
/** Always on top setting **/
if(modellocator.userSettingsac[0].alwaysontop == "no")
{
this.alwaysInFront = false;
}
else
{
this.alwaysInFront = true;
}
/** Size Settings **/
if(modellocator.flagMaxMin)
{
sizeWidth = mainScreen.visibleBounds.width;
sizeHeight = mainScreen.visibleBounds.height;
}
else
{
sizeWidth = mainScreen.visibleBounds.width*(modellocator.userSettingsac[0].size/100);
sizeHeight = mainScreen.visibleBounds.height*(modellocator.userSettingsac[0].size/100);
}
if(!this.closed)
{
this.width = mainScreen.visibleBounds.width;
this.height = mainScreen.visibleBounds.height;
}
modellocator.setSizeWidth = sizeWidth;
modellocator.setSizeHeight = sizeHeight;
rotate.autoCenterTransform = true;
rotate.angleYFrom = 0;
myMov.xTo = 0;
myMov.xFrom = mainScreen.visibleBounds.width;
myMov.yFrom = 40;
myMov.yTo = 40;
myMov.duration = 0;
fadeEffect.alphaFrom = 0;
fadeEffect.alphaTo = 1.0;
fadeEffect.duration = 1000;
rotate.play();
seqEffect.play();
}
}
protected function myVidTeaser_enterFrameHandler(event:Event):void
{
if(modellocator.flagDesktopVIdeoPlay == true)
{
if(movie != null)
{
if(movie.currentFrame == movieTotalFrame)
{
if(countMovie == (modellocator.arrMovie.length - 1))
{
countMovie = 0;
}
else
{
countMovie++;
}
/** Show Time Settings **/
movie.gotoAndStop(0);
System.gc();
System.gc();
timer = new Timer(int(modellocator.userSettingsac[0].showtime)*60000);
timer.addEventListener(TimerEvent.TIMER, movieLoadOnTimer, false, 0, true);
timer.start();
}
}
}
else
{
if(timer != null)
{
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, movieLoadOnTimer);
timer = null;
System.gc();
System.gc();
}
event.preventDefault();
event.stopImmediatePropagation();
}
}
private function movieLoadOnTimer(event:TimerEvent):void
{
loadMovie(countMovie);
}
public function loadMovie(num:int):void
{
if(modellocator.arrMovie != null && modellocator.arrMovie.length > 0)
{
if(num < modellocator.arrMovie.length)
{
if(modellocator.arrMovie[countMovie] != null)
{
if(modellocator.arrMovie[countMovie].VideoBuyFlag == "yes")
{
if(flash.system.Capabilities.os.indexOf("Mac") > -1)
{
myVidTeaser.source = "file://" + modellocator.arrMovie[countMovie].VideoFullURL;
}
else
{
myVidTeaser.source = modellocator.arrMovie[countMovie].VideoFullURL;
}
}
else
{
if(flash.system.Capabilities.os.indexOf("Mac") > -1)
{
myVidTeaser.source = "file://" + modellocator.arrMovie[countMovie].VideoTeaserURL;
}
else
{
myVidTeaser.source = modellocator.arrMovie[countMovie].VideoTeaserURL;
}
}
}
}
else
{
countMovie = 0;
loadMovie(countMovie);
}
}
else
{
this.close();
}
}
]]>
</fx:Script>
<fx:Declarations>
<s:Move id="moveUp" duration="500" target="{this}" yFrom="350" yTo="0"/>
<s:Move id="moveDown" duration="500" target="{this}" yFrom="0" yTo="350"/>
<s:Sequence id="seqEffect">
<mx:Move id="myMov"/>
<mx:Fade id="fadeEffect"/>
</s:Sequence>
<s:Rotate3D id="rotate"/>
</fx:Declarations>
<mx:Canvas id="canDesktopVideo" width="100%" height="100%" horizontalScrollPolicy="off"
verticalScrollPolicy="off">
<s:SWFLoader id="myVidTeaser" right="0" bottom="0" width="{modellocator.setSizeWidth}"
height="{modellocator.setSizeHeight}" alpha="{modellocator.setTransparency}"
buttonMode="true"
complete="myVidTeaser_completeHandler(event)"
enterFrame="myVidTeaser_enterFrameHandler(event)" maintainAspectRatio="true"
scaleContent="true"
scrollRect="{new Rectangle(0, 0, myVidTeaser.width, myVidTeaser.height)}"
useHandCursor="true"/>
</mx:Canvas>
</s:Window>
I can take snapshot of a component. But the problem is the component is lil bigger with scroll bars. The saved image has scrollbars (only the visible area is getting saved). What i need is I want the entire component to be saved as an image.
This exact functionality is available while we print the component using FlexPrintJob, where by setting the FlexPrintJobScaleType.NONE.
But here in my case i want it to be saved using ImageSnapShot ( not thru FlexPrintJob ).
Thanks Advance,
Sriss
I thought I knew how to do this, but there seem to be lots of awkward issues. I got it working but it's not nice. :-( Maybe you can improve on it.
Here's the code for an example application. And below is the code for the MyCanvas class. When you click the button an image of the Canvas container but without scrollbars should be drawn.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:my="*">
<mx:Script><![CDATA[
import flash.display.BitmapData;
import flash.events.Event;
import mx.containers.Canvas;
import mx.graphics.ImageSnapshot;
import flash.geom.Matrix;
import mx.core.ScrollPolicy;
public function onclick():void
{
var bitmapData:BitmapData = ImageSnapshot.captureBitmapData(canvas);
canvas.addEventListener("BitMapReady", onBitMapReady);
canvas.horizontalScrollPolicy = ScrollPolicy.OFF;
canvas.CreateBitMapData();
}
private function onBitMapReady(e:Event):void
{
DrawBitmapDataAt(canvas.bitMapData, 100, 100);
canvas.removeEventListener("BitMapReady", onBitMapReady);
canvas.horizontalScrollPolicy = ScrollPolicy.AUTO;
}
private function DrawBitmapDataAt(bitmapData:BitmapData,x:int,y:int):void
{
var matrix:Matrix = new Matrix();
matrix.tx = x;
matrix.ty = y;
box.graphics.lineStyle(0,0,0);
box.graphics.beginBitmapFill(bitmapData, matrix, false);
box.graphics.drawRect(x,y,bitmapData.width,bitmapData.height);
}
]]></mx:Script>
<mx:Box id="box">
<my:MyCanvas width="50" height="50" backgroundColor="white" id="canvas">
<mx:Button label="Hello" click="onclick()" />
</my:MyCanvas>
</mx:Box>
</mx:Application>
MyCanvas class:
package
{
import flash.events.Event;
import flash.events.TimerEvent;
import mx.containers.Canvas;
import flash.display.BitmapData;
import mx.core.ScrollPolicy;
import mx.graphics.ImageSnapshot;
import flash.utils.Timer;
public class MyCanvas extends Canvas
{
public var bitMapData:BitmapData;
private var creatingBitMap:Boolean = false;
private var timer:Timer;
public function CreateBitMapData():void
{
this.horizontalScrollPolicy = ScrollPolicy.OFF;
creatingBitMap = true;
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (creatingBitMap == true && this.horizontalScrollBar == null)
{
bitMapData = ImageSnapshot.captureBitmapData(this);
this.dispatchEvent(new Event("BitMapReady"));
creatingBitMap = false;
timer = new Timer(10);
timer.addEventListener(TimerEvent.TIMER, onTimer);
this.width += 1;
timer.start();
}
}
private function onTimer(e:TimerEvent):void
{
this.width -= 1;
trace("timer");
timer.removeEventListener(TimerEvent.TIMER, onTimer);
timer.stop();
}
}
}
How do I diable the drag-drop of an image. I've tried to stopPropagation, but that didn't help.
Here is the snippet of the code that I've written
<mx:Image width="24" height="24" complete="init()" dragStart="disableMove(event)"
source="{(data.id==null)?'': (data.id.search('\\.') > 0) ? 'assets/icons/teacher.png' : 'assets/icons/student.png'}"
toolTip="{data.data}" doubleClick="itemDoubleClick(event, data.id)" doubleClickEnabled="true">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import flash.events.MouseEvent;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
private var allCurrentItems: Array = new Array();
private function itemDoubleClick(event: Event, id: String): void {
Alert.show("Clicked = "+id);
}
private function init(): void {
var menuLabel:String = "About School\u00A0";
var cm:ContextMenu = new ContextMenu();
cm.hideBuiltInItems();
var item:ContextMenuItem = new ContextMenuItem(menuLabel);
this.addEventListener(MouseEvent.MOUSE_DOWN, showClick);
//add eventlisteners to the menu item and provide functions
cm.customItems.push(item);
//cm.customItems = [item];
this.contextMenu = cm;
}
private function showClick(event:MouseEvent): void {
if (event.buttonDown) {
Alert.show(String(event.buttonDown));
}
}
private function disableMove(event: MouseEvent): void {
event.stopImmediatePropagation();
}
]]>
</mx:Script>
</mx:Image>
I got it, instead of calling disableMove(event) on dragStart(), I called it on mouseDown() it worked.
I'm experimenting with Adobe AIR and Google Maps API in Flex Builder. The question is, i'm making a NativeMenu, and was wondering, how can I change the label of the "Fullscreen" item to "Exit fullscreen" when the stage is in fullscreen?
If you see any thing in the code that could/should be written better, please let me know ;)
Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
height="600"
width="700"
minHeight="100"
minWidth="100"
showStatusBar="false"
title="Gmaps 0.002"
>
<maps:Map
xmlns:maps="com.google.maps.*"
id="map"
mapevent_mapready="onMapReady(event)"
width="100%"
height="100%"
url=""
key=""
/>
<mx:Button id="fullscreenButton" click="toggleFullScreen()"/>
<mx:Script>
<![CDATA[
import com.google.maps.LatLng;
import com.google.maps.Map;
import com.google.maps.MapEvent;
import com.google.maps.MapType;
import com.google.maps.MapMouseEvent;
import com.google.maps.controls.MapTypeControl;
import com.google.maps.controls.ZoomControl;
import com.google.maps.controls.PositionControl;
import flash.display.NativeMenu;
import flash.display.NativeMenuItem;
import flash.events.Event;
import mx.core.Window;
import flash.display.StageDisplayState;
private function onMapReady(event:Event):void {
map.setCenter(new LatLng(59.908165,10.742719), 14, MapType.NORMAL_MAP_TYPE);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
function keyDownHandler(event:KeyboardEvent):void {
if (event.keyCode == 70) {
toggleFullScreen();
}
}
createMenu();
map.enableScrollWheelZoom();
map.enableContinuousZoom();
map.enableControlByKeyboard();
systemManager.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
map.addEventListener(MapMouseEvent.ROLL_OVER, function(event:MapMouseEvent):void {
map.addControl(new ZoomControl());
map.addControl(new PositionControl());
map.addControl(new MapTypeControl());
});
map.addEventListener(MapMouseEvent.ROLL_OUT, function(event:MapMouseEvent):void {
map.removeControl(new ZoomControl());
map.removeControl(new PositionControl());
map.removeControl(new MapTypeControl());
});
}
private function createMenu():void{
var mainMenu:NativeMenu = new NativeMenu();
var fullscreenMenu:NativeMenuItem = new NativeMenuItem("Fullscreen");
var maximizeMenu:NativeMenuItem = new NativeMenuItem("Maximize");
var restoreMenu:NativeMenuItem = new NativeMenuItem("Restore");
var separatorA:NativeMenuItem = new NativeMenuItem("A", true);
var closeMenu:NativeMenuItem = new NativeMenuItem("Close");
fullscreenMenu.addEventListener(Event.SELECT, handleMenuClick);
maximizeMenu.addEventListener(Event.SELECT, handleMenuClick);
restoreMenu.addEventListener(Event.SELECT, handleMenuClick);
closeMenu.addEventListener(Event.SELECT, handleMenuClick);
mainMenu.addItem(fullscreenMenu);
mainMenu.addItem(maximizeMenu);
mainMenu.addItem(restoreMenu);
mainMenu.addItem(separatorA);
mainMenu.addItem(closeMenu);
//fullscreenMenu.enabled = false;
//fullscreenMenu.label = "Test";
this.contextMenu=mainMenu;
}
private function handleMenuClick(e:Event):void{
var menuItem:NativeMenuItem = e.target as NativeMenuItem;
if(menuItem.label == "Fullscreen") toggleFullScreen();
if(menuItem.label == "Maximize") this.maximize();
if(menuItem.label == "Restore") this.restore();
if(menuItem.label == "Close") this.close();
}
private function fullScreenHandler(evt:FullScreenEvent):void {
if (evt.fullScreen) {
//fullscreenMenu.label = "Test";
} else {
}
}
private function toggleFullScreen():void {
try {
switch (systemManager.stage.displayState) {
case StageDisplayState.FULL_SCREEN_INTERACTIVE:
systemManager.stage.displayState = StageDisplayState.NORMAL;
break;
default:
systemManager.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
break;
}
} catch (err:SecurityError) {
// ignore
}
}
]]>
</mx:Script>
</mx:WindowedApplication>
in order to change a label into a NativeMenu, you can try this
yourNativeMenu.getItemAt(0).label="new_label";
where getItemAt(0) return the first item in the NativeMenu