Column charts with ticks
After having some issues with the Flex Forum due to spamming (not me), I went back on to answer a few quick questions. A question about creating tick lines between the interval lines on a column chart was followed up with setting the number of tick lines between the intervals. The first part of adding tick lines is fairly straight forward. When you create a ColumnChart and add LinearAxis, you can set the minorInterval value, which creates the ticks between the main intervals. After that is set, you can add an AxisRenderer to the verticalAxisRender to adjust what the tick looks like.
<mx:verticalAxisRenderers>
<mx:AxisRenderer axis="{countAxis}" minorTickPlacement="inside" minorTickStroke="{s1}" minorTickLength="330" />
</mx:verticalAxisRenderers>
As part of the question, the user wanted to create grid lines, which to me was to stretch the tick line across the entire chart. In order to have the tick lines only show up on the chart, you need to set the placement to “inside” and set the length. Unfortunately, you can’t simply get the width of the chart and set the length of the tick line, because the chart also includes any legends and interval numbers. Also, the tick line is white, so if you want it to match the grid lines, you need to create a stroke and set that value.
Finally, the user asked if the number of tick lines could be manipulated. What I found was that the chart would take the main interval value and divided it by the minor interval value in order to show the number of ticks, including the tick at the interval value. So, I came up with the simple formula to determine the minorInterval value based on a users selection. I added the value to a change function for a droplist of 1-9. The value 0 doesn’t work, because once you set it to show the minorInterval, it will always show something.
Minor Interval Value = Major Interval Value / (Viewable Tick Count + 1)
protected function tickViewList_changeHandler(event:IndexChangeEvent):void
{
var tickCount:int = tickViewList.selectedItem;
var tickView:Number = countAxis.interval / (tickCount + 1);
countAxis.minorInterval = tickView;
}
DataGrid Row Move
Another question on the Flex Forum about how to move a selected row on the DataGrid up or down, based on a button click. The answer is straight forward, but with a catch.
When you click on the DataGrid, it will give you an index for the row you have clicked. The first row in the DataGrid is 0. If you wanted to simply move a row up and down the DataGrid, then you simply add or subtract 1 from the selected index.
// Move Item Up SelectedIndex--; // Move Item Down SelectedIndex++;
Simple enough. Unless you sort the DataGrid, which throws that out of wack and is pointless. So, if you don’t plan on sorting the data, then adding a couple of buttons to move an item up and down within the DataGrid and the ArrayCollection provider, then here is the code. It also includes checks to make sure you don’t move the item off ofthe grid.
Code for the Move Up Button
protected function moveUpBtn_clickHandler(event:MouseEvent):void
{
var upSelectedIndex:int = myDataGrid.selectedIndex;
// Move Item
if(upSelectedIndex > -1) {
if(upSelectedIndex > 0) {
// Get the selected Object
var moveObject:Object = myArrayCollection.getItemAt(upSelectedIndex);
// Get actual Object location if grid is sorted
var upActualIndex:int = myArrayCollection.getItemIndex(moveObject);
// Remove selected item at actualIndex
myArrayCollection.removeItemAt(upActualIndex);
myArrayCollection.refresh();
// Move both indexes
upActualIndex--;
upSelectedIndex--;
// insert item at actualIndex
myDataGrid.dataProvider.addItemAt(moveObject, upActualIndex);
myArrayCollection.refresh();
// select grid at selectedIndex
myDataGrid.selectedIndex = upSelectedIndex;
} else {
Alert.show("Item is currently at the top of the list.", "Move Alert", Alert.OK, this);
}
} else {
Alert.show("No Item Selected.", "Move Alert", Alert.OK, this);
}
}
Code for the Move Down Button
protected function moveDownBtn_clickHandler(event:MouseEvent):void
{
var downSelectedIndex:int = myDataGrid.selectedIndex;
if(downSelectedIndex > -1) {
// Move Item
if(downSelectedIndex < myArrayCollection.length -1) {
// Get the selected Object
var moveObject:Object = myArrayCollection.getItemAt(downSelectedIndex);
// Get actual Object location if grid is sorted
var downActualIndex:int = myArrayCollection.getItemIndex(moveObject);
// Remove selected item at actualIndex
myArrayCollection.removeItemAt(downActualIndex);
myArrayCollection.refresh();
// Move both indexes
downActualIndex++;
downSelectedIndex++;
// insert item at actualIndex
myDataGrid.dataProvider.addItemAt(moveObject, downActualIndex);
myArrayCollection.refresh();
// select grid at selectedIndex
myDataGrid.selectedIndex = downSelectedIndex;
} else {
Alert.show("Item is currently at the bottom of the list.", "Move Alert", Alert.OK, this);
}
} else {
Alert.show("No Item Selected.", "Move Alert", Alert.OK, this);
}
}
I did modify the DataGrid, so that the selectioMode is “singleRow”, which simplifies the selectedIndex information. I also set the selectedIndex for the row after the move, so the user can continue to move the row up and down and not have to select it again. Here is the example and source.
UPDATE: Had to set the Down Move to look for the Length of the ArrayCollection -1, because the DataGrid row starts at 0, it is one less than the total length of the ArrayCollection.
View Source
[kml_flashembed publishmethod="dynamic" fversion="11.0.0" movie="http://deanlogic.com/demo/Flex/SimpleDataGrid/SimpleDataGrid2.swf" width="800" height="600" targetclass="flashmovie" /]
Column Chart with Item Renderer – updated
Okay, it didn’t take me long to get back and do some more fiddling with the Column Chart Item Renderer. I went ahead and changed the static ArrayCollection to a dynamic one, because I was trying to figure out something with Themes and needed a button and the button should do something. The ArrayCollection is fairly simple for this chart, so all I did was create a couple of random values from 0 to 100 and made the “date” value the counter time 10. I set it up so that you can press a button and create new data, which is helpful to see the changes to the columns.
// Create some random data for Yesterday and blank data for today
private function dataCreation():void {
currentArray.removeAll();
for(var h:int = 0; h < 4; h++) {
// Generate Random Data
var randomClose:Number = Math.floor(Math.random() * 100);
var randomOpen:Number = Math.floor(Math.random() * 100);
// create a temporary object and add the three values
var tmpObject:Object = new Object();
tmpObject.date = (h + 1) * 10;
tmpObject.close = randomClose;
tmpObject.open = randomOpen;
// insert new tmpObject
currentArray.addItem(tmpObject);
}
// Refresh the data
currentArray.refresh();
}
After that was fixed, I went ahead to modify the ItemRenderer again, but this time to use a GradientFill and a BitMapFill. I had to reduce what was defined for the rectangle, to just a Graphic item as a holder.
s:Graphic id="graphicHolder" />
And then I declared three different rectangles, one for each type of fill. Again, this was to simplify things and also to make sure I was doing the right thing for each fill. As you can see in the Gradient Fill, I had to set the three GradientEntry items to create the look I need. You could do this all dynamically, but I don’t think most people will try different Gradients for each column. Which is why my Gradient fill only changes the Start, Mid and End color of the Gradient.
<fx:Declarations> <s:Rect id="imageRect"> <s:stroke> <s:SolidColorStroke id="rectImageStroke" /> </s:stroke> <s:fill> <s:BitmapFill id="imageRectFill" fillMode="repeat" scaleX=".70" scaleY=".70" smooth="true" /> </s:fill> </s:Rect> <s:Rect id="gradientRect"> <s:stroke> <s:SolidColorStroke id="rectLinGradStroke" /> </s:stroke> <s:fill> <s:LinearGradient id="rectLinGrad"> <s:entries> <s:GradientEntry id="linGradColorStart" ratio="0" alpha=".5" /> <s:GradientEntry id="linGradColorMid" ratio=".25" alpha=".5" /> <s:GradientEntry id="linGradColorEnd" ratio=".66" alpha=".5" /> </s:entries> </s:LinearGradient> </s:fill> </s:Rect> <s:Rect id="solidRect"> <s:stroke> <s:SolidColorStroke id="rectSolidStroke" /> </s:stroke> <s:fill> <s:SolidColor id="rectSolidColor" /> </s:fill> </s:Rect> </fx:Declarations>
From here, it was just setting the color for the Gradients and the appropriate image for the BitMap Fills. Except that it took me a while to figure out the correct syntax for the Image. I couldn’t declare it. I couldn’t just Embed it as the source. I had to Embed it as a Bindable Class and then set the BitmapAsset to that Class and finally make it the source for the BitMapFill.
// Embed the Red Apple Image [Embed(source="../assets/images/red-apple.png")] [Bindable] public var imgRedApple:Class; // Red Image Fill var imgRedAppleObj:BitmapAsset = new imgRedApple() as BitmapAsset; imageRectFill.source = imgRedAppleObj;
I simplified the code so that different columns do only two fills. I had columns doing all three fills, but decided that was too much code and could get really confusing. With the example below;
- If the 1st column has more than 45, then the Red Apple Image Fill is used, else the Red Gradient Fill
- If the 2nd column has more than 45, then the Blue Gradient Fill is used, else the Blue Solid Fill
- If the 3rd column has more than 45, then the Green Apple Image Fill is used, else the Green Solid Fill
- If the 4th column has more than 45, then the Purple Solid Fill is used, else the Purple Gradient Fill
I created a second file for this example, so that the first example and this example could be viewed separately.
View Source
[kml_flashembed publishmethod="dynamic" fversion="11.0.0" movie="http://deanlogic.com/demo/Flex/SimpleCharts/SimpleCharts2.swf" width="800" height="500" targetclass="flashmovie"/]
Column Chart with Item Renderer
When doing the Column Chart with fillFunction for a question in the Flex Forum, the poster said that he was trying to do something a little different. Instead of a simple fill, he wanted the fill to be semi-transparent with a solid border. When I looked at the iFill function, it didn’t have a stroke option and it doesn’t seem that the standard column item deals with the column border. My guess was, that an item renderer should be used for the column instead. Within the item render, you can create a rectangle graphic and then adjust the border and fill parameters. Since this seemed like an interesting exercise, I decided to make myself an example (the best way I learn something).
I started out using the simple array data found in other examples. I will probably update this to something more dynamic later.
[Bindable]
public var SMITH:ArrayCollection = new ArrayCollection([{date:10, close:41.87, open: 30},{date:20, close:45.74, open: 40},
{date:30, close:42.77, open: 60}, {date:40, close:48.06, open: 50}]);
And then I attached this to a ColumnChart and create a single ColumnSeries with the “date” on the xAxis and the “close” count on the yAxis. I then added the itemRenderer parameter, which popups a window for creating the component.
<mx:ColumnChart id="myColumnChart1" dataProvider="{SMITH}" >
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="date" />
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries id="columnSeries1" xField="date" yField="close" itemRenderer="components.myColumnRenderer" />
</mx:series>
</mx:ColumnChart>
In the ItemRender, the way to kick everything off is to override the set data function. You have to check to see if the value is null first, or you get errors when the chart is initially loading. Once there is data in the value, then you can start altering the renderer for the column.
override public function set data(value:Object):void {
super.data = value;
// Check to see if the data property is null.
if (value== null) {
return;
} else {
// data display and other stuff start here
}
}
To create the background rectangle, you first have to start with a Graphic and then add the Rect and the parts of the Rect that you want to alter. You could just add the Rect and then alter the stroke and fill dynamically, but having them already defined makes it a little easier. I am only doing a Solid stroke and fill, if you wanted to do gradient or mix gradient and solid, then you definitely would want to do that dynamically. The Graphic is first, since it is on the bottom. Anything you want to display above the rectangle graphic goes afterward in the code.
<s:Graphic> <s:Rect id="columnRect"> <s:stroke> <s:SolidColorStroke id="rectSolidColorStroke" /> </s:stroke> <s:fill> <s:SolidColor id="rectSolidColor" /> </s:fill> </s:Rect> </s:Graphic>
Once you are ready to alter the column, you have to create the rectangle graphic for the background and you need to set the width and height to the super call for the column. If you don’t do this, then the rectangle is size 0 and you can’t see anything.
columnRect.width = super.width; columnRect.height = super.height;
Since you are passing in the column data, you can modify the look of each column either by the xValue or the yValue. In this case, I wanted to change each column based on the yValue. I am only doing a simple solid fill and solid stroke, so I only need to change one color. I declared the colors to make it easier to set the uint values. Finally, I adjust the stroke weight and the fill alpha. These could also be changed based on the column data.
switch(value.xValue) {
case 10:
// Red Color
columnFillColor = colorRed;
columnStrokeColor = colorRed;
break;
case 20:
// Blue Color
columnFillColor = colorBlue;
columnStrokeColor = colorBlue;
break;
case 30:
// Green Color
columnFillColor = colorGreen;
columnStrokeColor = colorGreen;
break;
case 40:
// Purple Color
columnFillColor = colorPruple;
columnStrokeColor = colorPruple;
break;
}
rectSolidColorStroke.color = columnFillColor;
rectSolidColorStroke.weight = 2;
rectSolidColor.color = columnStrokeColor;
rectSolidColor.alpha = .3;
This example didn’t take very long to make and I will probably try to add some other feature to this simple chart.
View Source
[kml_flashembed publishmethod="dynamic" fversion="11.0.0" movie="http://deanlogic.com/demo/Flex/SimpleCharts/SimpleCharts.swf" width="800" height="500" targetclass="flashmovie" /]
Column Chart with Fill Function
When you have a column chart, sometimes you want to change the column colors based on the data. A question in the Flex Forum asked how to alter the column color on each column. To do this, yo need to use the fillFunction on a ColumnSeries to set the color of the fill. One issue with doing this, is how it affects the chart legend.
If you use the fills property or the fillFunction to define the fills of chart items, and you want a legend, you must manually create the Legend object for that chart.
But, this just gives me the opportunity to test out two different charting options.
I alter the stacked column chart that I created to answer another question on the forum. Since the column chart in this example is created dynamically, I had to add the fillFunction parameter when creating the column series for the green and red apple columns.
columnSeries1.fillFunction = greenAppleFillFunction;
Then I just created a simple function to change the color of the column if the count was less than 50.
private function greenAppleFillFunction(element:ChartItem, index:Number):IFill {
var item:ColumnSeriesItem = ColumnSeriesItem(element);
var count:Number = Number(item.yValue);
if (count < 50) {
return scFadeGreen;
} else {
return scGreen;,
}
}
To make things easier, I had already defined my SolidColor values, this makes it easier to keep it consistent throughout the chart. In this example, I am only getting the yValue, but you could also get the xValue, if you wanted to change the column colors based on that.
Next I need to update the legend to reflect the new fillFunctions, which is fairly straight forward and I can also use the defined SolidColor parameters.
<mx:Legend direction="horizontal" >
<mx:LegendItem label="Red Apples" fill="{scRed}" />
<mx:LegendItem label="Red under 50" fill="{scFadeRed}" />
<mx:LegendItem label="Yellow Apples" fill="{scYellow}" />
<mx:LegendItem label="Green Apples" fill="{scGreen}" />
<mx:LegendItem label="Green under 50" fill="{scFadeGreen}" />
</mx:Legend>
I also added a Refresh Data button so that the data can be cycled and the column color changes can be seen.
View Source
[kml_flashembed publishmethod="dynamic" fversion="11.0.0" movie="http://deanlogic.com/demo/Flex/StackedColumnWithLineSeries/StackedColumnLineChart.swf" width="800" height="600" targetclass="flashmovie" /]
TextArea auto scroll update
There was a question on the Flex Forum about how to auto-scroll a TextArea. You can set the VerticalScrollPolicy to auto or you can add a little code to valueCommit to move the vertical scroller. Since I lost where I created the example of adding the code to the valueCommit, I decide to remake the example to show the difference. Both text areas are updated every 10 seconds with a random generated sentence, based off of quotes from Mark Twain.
The left TextArea box uses the VerticalScrollPolicy set to “auto”
<s:TextArea id="tmpTxtArea1" width="98%" height="98%" verticalScrollPolicy="auto" />
The right TextArea box uses the valueCommit code to move the verticalScrollBar
<s:TextArea id="tmpTxtArea2" width="98%" height="98%" valueCommit="tmpTxtArea2.scroller.verticalScrollBar.value = tmpTxtArea2.scroller.verticalScrollBar.maximum" />
View Source
[kml_flashembed publishmethod="dynamic" fversion="11.0.0" movie="http://deanlogic.com/demo/Flex/TextAreaScroll/TextAreaScroll.swf" width="800" height="300" targetclass="flashmovie" /]
While the right box doesn’t move the TextArea scroll bar 100%, it does move it.
The current issues I need to update with this example is a better random sentence generator and fix the regular expression that is supposed to remove the commas and periods before creating the word array. That’s probably some sort of project I can do later, so the sentences created are a little bit off, since I don’t remember how I did it in the previous example and the site I got the code idea from is no longer available.
Date Sort in a DataGrid – the easy way
While trying to give suggestions to a post on the Flex Forum, I modified my Simple Data Grid to include a column for a Date. The poster had an issue with sorting the column with dates in it. My guess is, the Date value is actually a String object. It really isn’t very hard to create a Date from a string, just parse out the String and feed the appropriate date times into the Date object. Here is how I create the random date value.
// Create a Random Date var randomMonth:Number = Math.floor(Math.random() * (11)); var randomDay:Number = Math.floor(Math.random() * (27)); var randomHour:Number = Math.floor(Math.random() * (23)); var randomMinute:Number = Math.floor(Math.random() * (59)); var thisDate:Date = new Date(); thisDate.month = randomMonth; thisDate.date = randomDay; thisDate.hours = randomHour; thisDate.minutes = randomMinute;
Since I insert the value into the item Object as a Date object, the sort function knows how to sort for Descending/Ascending. It might take a few more steps to convert a set of String data into objects and insert them into an ArrayCollection, but I think it saves time in the long run, because you work with each value as what they are and not a String that you have to convert to a Number, Int or Date.
Here is the DataGrid example. Not only does sorting by the column header work for the dates, I added a button to sort by the dates. The button switches between Ascending and Descending each time it is clicked.
View Source
[kml_flashembed publishmethod="dynamic" fversion="9.0.0" movie="http://deanlogic.com/demo/Flex/SimpleDataGrid/SimpleArrayCollectionUpdate.swf" width="850" height="500" targetclass="flashmovie"/]
Stacked Column Chart with Line Series
On the Flex Forum, I was attempting to help someone find their issue to a Stacked Column Chart with a Line Series. The y-axes values were not corresponding with the data being provided. This seemed like a glitch and I even attempted a work around by finding the minimum and maximum values. Finally, after looking at the Stacking Columns example and the Multiple Axis Example, reconstructed the chart using the static objects instead of dynamically creating the chart. From there, I recreated the chart items in a function and determined that the first issue the poster was having was building the column series incorrectly into a column set.
// add column series to column set columnset.series = [columnSeries1, columnSeries2];
The second issues is that the created column set and the line series would be the two series added to the chart, not the individual column series.
myChart.verticalAxisRenderers = [verticalAxisRendererRight, verticalAxisRendererLeft]; // column set and linear series to Chart myChart.series = [columnset, lineSeries];
I also added both x-axis and y-axis data column information, so that there would be no mistake as to were the data was coming from. These small changes apparently were the key to getting the axis values to match the column and charts.
var columnSeries1:ColumnSeries = new ColumnSeries();
columnSeries1.dataProvider = acChartData;
columnSeries1.xField = "hourOfDay";
columnSeries1.yField = "greenAppleCount";
columnSeries1.displayName = "Green";
columnSeries1.setStyle("fill", 0x009900);
columnSeries1.verticalAxis = verticalAxisLeft;
I used my apples data creator for this chart, since I already had that available on the other chart.
Another side note of obviousness, you fill columns and stroke lines.
[kml_flashembed publishmethod="dynamic" fversion="9.0.0" movie="http://deanlogic.com/demo/Flex/StackedColumnWithLineSeries/StackedColumnLineChart.swf" width="800" height="500" targetclass="flashmovie" /]
Simple DataGrid with Row Background Update
On the Adobe Flex forum, a question was asked about changing the background color for a row to a different color if the user selected it and hit the DELETE key. So, I updated the Simple Data Grid to include this feature. It doesn’t delete the row, but changes the background color to grey.
The first step is to capture the keyboard action. To do this, a listener has to be created and set to listen for a KeyBoard event. I set it for the stage, but doing so requires that the function is called when applicationComplete instead of earlier. An alternative would be to set it to FlexGlobals.topLevelApplication, either way works.
// Add keyboard listener stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
After you point the listener to your handler, you will need to make the handler look for the key or key press. In my example, I am only looking for the DELETE key, but you can look for any Keyboard key. And you can also check to see if things like the “shift”, “alt” or the “capsLock” is activated when the key is pressed. After the function determines that the key pressed is DELETE, then it updates the ArrayCollection object to set the “isDeleted” value to true. I modified my original data object to include the “isDeleted” boolean value, which I default to false.
private function keyHandler(event:KeyboardEvent):void {
// Handles the keyboard even
// If the keyboard event is DELETE
if(event.keyCode == Keyboard.DELETE) {
debugTxt.text += " \n Key was DELETE";
debugTxt.text += " \n keyCode = " + event.keyCode + "/" + event.charCode;
// If an item on the grid has been selected and isn't the header row
if(myDataGrid.selectedIndex >= 0) {
debugTxt.text += " \n Grid Index = " + myDataGrid.selectedIndex;
// Set the object to isDeleted
var tmpObject:Object = new Object();
tmpObject = myDataGrid.selectedItem;
tmpObject["isDeleted"] = true;
var itemFoundAt:int = myArrayCollection.getItemIndex(myDataGrid.selectedItem);
if(itemFoundAt != - 1) {
myArrayCollection.setItemAt(tmpObject, itemFoundAt);
}
} else {
debugTxt.text += " \n Grid not selected ";
}
} else {
debugTxt.text += " \n " + event.keyCode + "/" + event.charCode;
}
}
After the data is updated, then a physical change needs to take place to the DataGrid to show this change. As in the earlier example, I used an itemRenderer, but I added it to the DataGrid and not to the individual columns. This renderer simply checks the data value for “isDeleted” and sets the alpha and color for the column accordingly. Instead of setting the backgroundColor of the label, the renderer creates a rectangle as the background and the color fill and alpha values are set. I set the alpha to 0 for the false option, because this will allow the alternating rows to continue with the color displayed.
override public function prepare(hasBeenRecycled:Boolean):void {
if(data != null) {
if(data["isDeleted"]) {
bgColor.color = 0xcccccc;
bgColor.alpha = 1;
} else {
bgColor.alpha = 0.0;
}
lblData.text = data[column.dataField];
} else {
return;
}
}
What I haven’t done is the final step to delete the rows highlighted for deletion. This would simply be a function to go through the ArrayCollection and find the isDeleted == true objects and then remove them. I also added the debug text area to show the key listener results.
Select a row and then hit the DELETE key on your keyboard.
View Source
[kml_flashembed publishmethod="dynamic" fversion="9.0.0" movie="http://deanlogic.com/demo/Flex/SimpleDataGrid/SimpleArrayCollectionUpdate.swf" width="750" height="500" targetclass="flashmovie" /]
Simple Chart Overlay
One of the screens I created for work is a “dashboard” type that allows the view to quickly see the current status of service call volume. There are multiple charts on the display, but one of them is a column chart that shows the current day’s numbers vs. the prior week of the same day. By having this information, the viewer can see if the volume of calls is in a “normal” range, because the it fluctuates throughout the day and the week, but is similar based on the day of the week. Friday’s call volume is usually lower than Wednesday volume. When I initially created the display in Flex 3, I had to worry about putting both column charts in the same x and y spot in order for the overlay to work. With the Group component, it makes it much easier, because it automatically puts the items stacked upon each other.
The example creates some random data of the number of red, green and yellow apples picked in an hour. The random data is created for all of the previous day’s hours and then a 15 second timer creates the current day’s hours one by one. In the real chart, the data is update every 15 minutes. The bottom chart is added first, which is the “Yesterday” values and the top chart is added next, which is “Today” values. The “Yesterday” values are slightly hidden by using a alpha setting in the “Today” chart.
// Bottom Chart for "Yesterday" values
<mx:ColumnChart id="countsYesterday" width="100%" height="100%" showDataTips="true" dataProvider="{acChartYesterday}">
// Top Chart for "Today" values
<mx:ColumnChart id="countsToday" width="100%" height="100%" showDataTips="true" dataProvider="{acChartToday}" alpha=".65">
To help with the color offset, I picked colors for the “Yesterday” values that seem to be faded version of the “Today” colors. You could use any colors for the columns, but having less bright values in the back help with contrast. It also helps when the values for “Today” are greater than for “Yesterday”. The only downfall for doing things this way is that the datatips for the bottom chart cannot be seen. But, I’m sure the datatip function could be modified to get both values.
[kml_flashembed publishmethod="dynamic" fversion="9.0.0" movie="http://deanlogic.com/demo/Flex/ChartOverlay/ChartOverlay.swf" width="800" height="500" targetclass="flashmovie"]

