<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Odds and Sodds &#187; Charts</title>
	<atom:link href="http://www.scottlogic.co.uk/blog/graham/tag/charts/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.scottlogic.co.uk/blog/graham</link>
	<description>Odds and Sodds</description>
	<lastBuildDate>Wed, 16 Nov 2011 09:49:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>A Critique of Radar Charts</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2011/09/a-critique-of-radar-charts/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2011/09/a-critique-of-radar-charts/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 18:03:19 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Visualisation]]></category>
		<category><![CDATA[Charts]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=568</guid>
		<description><![CDATA[This article presents a critique of radar charts, a chart type commonly used to display multivariate data, highlighting how they are poorly designed to effectively communicate information in the underlying data, and presents a number of more effective alternatives Introduction Radar charts, sometimes known as spider, start or web charts, are a two-dimensional chart type [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2011%252F09%252Fa-critique-of-radar-charts%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fn7npfp%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22A%20Critique%20of%20Radar%20Charts%22%20%7D);"></div>
<p><em>This article presents a critique of radar charts, a chart type commonly used to display multivariate data, highlighting how they are poorly designed to effectively communicate information in the underlying data, and presents a number of more effective alternatives</em></p>
<h2>Introduction</h2>
<p><a href="http://en.wikipedia.org/wiki/Radar_chart" target="_blank">Radar charts</a>, sometimes known as spider, start or web charts, are a two-dimensional chart type designed to plot one or more series of values over multiple common quantitative variables by providing an axis for each variable, arranged radially as equi-angular spokes around a central point.  The values for adjacent variables in a single series are connected by lines, and, frequently, the polygonal shape created by these lines in filled with a colour.  Beyond this there are many subtle variations that have different consequences with respect to the efficacy of the chart.  These variations will be covered at appropriate points in the following critique.</p>
<p><a name="chart1"></a><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/Spider_Chart_wikipedia.jpg" alt="Radar Chart from Wikipedia" title="Radar Chart from Wikipedia" width="538" height="295" class="aligncenter" /></a></p>
<p style="font-style: italic; margin-left: 180px;">Chart 1: Radar chart from <a href="http://en.wikipedia.org/wiki/File:Spider_Chart.jpg" target="_blank">Wikipedia</a></p>
<h2 style="margin-bottom: 5px">Critique</h2>
<h4>Axes and Values</h4>
<p>The axes of radar charts represent independent scales for each of the quantitative variables under consideration.  Therefore, barring <a href="#occlusion">occlusion</a>, comparing values for a single variable between series is straightforward and relatively effortless since it merely consists of assessing their position along a line, something we are able to do without any thought.  However, a number of distinct issues arise when attempting to compare values across different axes.</p>
<p>Firstly (and most easily grasped), by definition there is nothing prohibiting axes representing wildly different scales since they are nominally independent.  This is shown at its extreme in <a href="#chart2">Chart 2</a>.  Clearly comparison across variables is pointless in this case, yet it is something a radar chart is designed to encourage us to do.  Hopefully from this extreme example you are also able to appreciate that even in subtler cases where the scales are genuinely independent, whether that be the inversion of the scale on one axis or slightly different ranges of values being represented, comparison is rather absurd.  So much so that very few charting libraries or applications support this in any way.</p>
<p><a name="chart2"></a><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/few.png" alt="Radar Chart by Stephen Few" title="Radar Chart by Stephen Few" width="428" height="288" class="aligncenter" /></a></p>
<p style="font-style: italic; margin-left: 130px;">Chart 2: <a href="www.perceptualedge.com/articles/dmreview/radar_graphs.pdf" target="_blank">Artificial radar chart by Stephen Few to show independent axis scales</a></p>
<p>Unfortunately, even with a common scale between axes, comparing values across them remains cumbersome and error-prone.  This is because rather than the simple straight-line comparison our visual perception is hard-wired to perform that is found in &#8220;conventional&#8221; chart types, comparison in radar charts requires conscious thought to mentally project a sort of arc of rotation to map a value from one axis onto another, something we are not particularly adept at.</p>
<p><a name="chart3"></a><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/radar_chart_visiblox.png" alt="Radar Chart by Visiblox" title="Radar Chart by Visiblox" width="531" height="336" class="aligncenter" /></a></p>
<p style="font-style: italic; margin-left: 250px;">Chart 3: Radar chart by<a href="http://www.visiblox.com/examples/RadarChart" target="_blank">Visiblox</a></p>
<p>In order to help general perception and, in particular, comparison across axes, radar charts usually display gridlines connecting axes when they share a common scale (giving them their traditional spider-web-like appearance).  However, even with these gridlines it remains cumbersome to compare values on non-adjacent axes.  For example, try comparing the Space and Comfort scores for Monster Truck in <a href="chart3">Chart 3</a>.  It requires a surprising amount of conscious effort, doesn&#8217;t it?</p>
<p><a name="chart4"></a><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/radar_chart_kaplab.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/radar_chart_kaplab.png" alt="Radar Chart by Kap Lab" title="Radar Chart by Kap Lab" width="537" height="432" class="aligncenter" /></a></p>
<p style="font-style: italic; margin-left: 260px;">Chart 4: Radar chart by <a href="http://lab.kapit.fr/display/radarchart/Radar+Chart" target="_blank">Kap Lab</a></p>
<p>Aside from the <a href="http://www.infovis-wiki.net/index.php/Data-Ink_Ratio" target="_blank">non-data ink</a> gridlines inevitably add, they also introduce further issues to radar charts.  Mainly, they tend to add confusion around axis value labelling by breaking the association by proximity used to associate a particular value label with a mark on an axis.  This is very clearly demonstrated in <a href="#chart1">Chart 1</a>.  It requires active thought to disassociate the labels from the gridlines over which they inadvertently lie.  For example, what is actually the $60 gridline appears to be labelled $50 instead.  <a href="chart3">Chart 3</a> demonstrates a commonly attempted solution to this problem that unfortunately makes the chart just as difficult to read, only in a different way.  Here the labels are so far away from the axis that, once again, conscious effort is required to comprehend what should be an inconspicuous, almost sub-conscious interpretation aide for the chart.</p>
<p><a name="chart5"></a><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/radar_chart_dundas.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/radar_chart_dundas.png" alt="Radar Chart by Dundas Data Visualisation" title="Radar Chart by Dundas Data Visualisation" width="417" height="336" class="aligncenter" /></a></p>
<p style="font-style: italic; margin-left: 215px;">Chart 5: Radar chart by <a href="http://support2.dundas.com/OnlineDocumentation/winchart2005/RadarChart.html" target="_blank">Dundas Data Visualisation</a></p>
<p><em>Occasionally the gridlines on a radar chart are presented as circles rather than straight connecting lines between equivalent values on adjacent axes, as in <a href="#chart5">Chart 5</a>.  Conceptually, I do not understand how a chart can combine circular connections between axis values and straight line connections between series values.  Surely they must adhere to the same notional underlying data space?!  Otherwise the chart is fundamentally broken.  If anyone feels like creating a radar chart using strictly <a href="http://en.wikipedia.org/wiki/Polar_coordinate_system" target="_blank">polar data space</a> for both gridlines and series shapes, could you please send me a link?  I&#8217;ve never actually seen one, and always like a giggle&#8230;</em></p>
<h4><a name="lines"></a>Connecting Lines and Nominal Scales</h4>
<p>The quantitative variables and their values represented on the various axes of a radar chart are, with the exception of some less common cases such as when plotting timeseries data, distinct and unrelated.  Yet, by design, radar charts force the suggestion of some relationship between the variables by having a connecting line between values on different axis in order to create the series grouping, thereby misleading the user.  To help clarify this point, the chart below is identical to <a href="chart5">Chart 5</a> except that the information is plotted using &#8220;conventional&#8221; <a href="http://en.wikipedia.org/wiki/Cartesian_coordinate_system" target="_blank">cartesian coordinates</a> rather than the (pseudo-)<a href="http://en.wikipedia.org/wiki/Polar_coordinate_system" target="_blank">polar coordinates</a> of a radar chart.</p>
<p><a name="chart6"></a><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/line_chart_dundas.png" alt="Line Chart of Radar Chart by Dundas Data Visualisation" title="Line Chart of Radar Chart by Dundas Data Visualisation" width="586" height="263"  class="aligncenter" /></p>
<p>In this more familiar, non-circular format it is hopefully much more obvious that we are in fact dealing with a nominal scale on the x axis.  That is, the categories on the x axis are simply named entities that have no intrinsic order and do not represent quantitative values.  As such, the relationship and incline or decline in value the connecting line implies is grossly misleading since we could arbitrarily change the relationships by rearranging the categories (something we are free to do because of their lack of intrinsic ordering).  When shown this way, many of you will recognise that this kind of information is likely to be best presented as a bar chart in some form, depending on the specific purpose of the chart, as shown for <a href="chart5>Chart 5</a> below.</p>
<p><a name="chart7"></a><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/bar_chart_dundas.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/bar_chart_dundas.png" alt="Bar Chart of Radar Chart (Dundas)" title="Bar Chart of Radar Chart (Dundas)" width="573" height="300" class="aligncenter" /></a></p>
<h4><a name="occlusion"></a>Occlusion</h4>
<p>Occlusion, in data visualisation, refers to the phenomenon where a part of the visualisation obscures another part.  Clearly this should be avoided, or at least minimised, since hidden visuals prevents you from interpreting the information correctly.  Unfortunately, the design of radar charts means significant occlusion is inevitable when multiple series are plotted, since they must be &#8220;on top&#8221; of each other.  In cases where the fill colour of the shape of a series is relatively or completely opaque, such as <a href="chart5">Chart 5</a>, it can be nigh on impossible to see particular values.  In these cases, the gridlines are also at best partially obscured, thereby making it even more cumbersome to discern the value any any given point.  In <a href="#chart5">Chart 5</a> this is has been somewhat overcome by adding tick marks on top of the series, which, unfortunately, also adds to the overall clutter on the chart.</p>
<p>When transparency is used to circumvent the problems caused by solid fill colours it creates a new problem: the unavoidable tinting effect can make differentiating the underlying series or matching them to a legend very difficult.  As such, the approach that suffers least from occlusion is when no fill colour is used, as in <a href="#chart1">Chart 1</a>.</p>
<h4>Shapes</h4>
<p>One argument given by proponents of radar charts is that we are naturally adept at seeing and evaluating simple shapes.  Although this is true, it overlooks the major issue that the overall shape presented for a series on a radar chart does not leverage any of the <a href="http://en.wikipedia.org/wiki/Pre-attentive_processing" target="_blank">pre-attentive attributes</a> we perceive quantitatively.  In essence, this means we are unable to attribute much genuine meaning to the shape of a series.  The only patterns our visual perception can really discern in a data set presented as a radar chart are similarity and extreme outliers.  Both patterns are just as easy, if not easier, to recognise in more effective <a href="#alternatives">alternative visualisations</a>, such as line and bar charts, where the shapes also have quantitative perception.  Consider the example radar charts above, can you reliably say anything useful about the respective series based on their shapes other than where they are similar or there is an outlier?</p>
<p>A further issue with the shapes presented by radar charts are that the area of the shapes increases as a square of the values rather than linearly.  This can cause us to misinterpret the data since a small difference in values results in a significant difference in area, thereby exaggerating any difference when we follow our natural inclination to compare the size of the shapes.</p>
<h2><a name="alternatives"></a>Alternatives</h2>
<p>There are numerous more effective alternatives to radar charts, depending on the information being presented.  These include bar charts, <a href="#lines">as shown above</a>, line charts (particularly for timeseries data), <a href="http://www.perceptualedge.com/articles/b-eye/parallel_coordinates.pdf" target="_blank">parallel coordinates charts</a> and, quite simply, tables showing the raw figures.  The latter is commonly overlooked, but when dealing with relatively small, simple data sets it is frequently the most immediate and clear way to represent the information.  In more complex cases, a more effective alternative to a radar chart can be to use a concept called <a href="http://en.wikipedia.org/wiki/Small_multiple" target="_blank">small multiples</a>, devised by <a href="http://www.edwardtufte.com/tufte/" target="_blank">Edward Tufte</a>, in conjunction with bar charts.  Using this approach, individual series are separated onto individual charts, all sharing a common x and/or y axis scale to enable meaningful comparison across them.  This way it is easier to gain both a higher level overview and investigate at more detail because the clutter, occlusion and related issues common to complex charts, and particularly radar charts, are removed.  The following chart is a redesign of <a href="#chart4>Chart 4</a> using small multiples.  Notice how much easier it is to absorb the information in this form.</p<</p>
<p><a name="chart8"></a><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/kaplab_multiple.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/kaplab_multiple.png" alt="Small Multiples of Radar Chart by KapLab" title="Small Multiples of Radar Chart by KapLab" width="933" height="160" class="aligncenter" /></a></p>
<p><em>Note that the x axis scale labels have been omitted because they were not present in the original example and, even after a little background research, I was unable to deduce them.  As far as I can tell, the data used to create the original chart is fictional.  If the genuine figures are of interest, I would suggest using Google&#8217;s <a href="http://www.google.co.uk/publicdata/directory" target="_blank">Public Data Explorer</a>.</em></p>
<p>An immediate advantage of using tables, bar columns or small multiples is that they naturally support ordering.  With a radar chart, introducing ordering would require the starting point and direction to be explicitly indicated somehow since neither can be inherently deduced from the radar chart design.  In the aforementioned alternatives, left-to-right or top-to-bottom ordering is immediately evident.  Although ordering is rarely a strict necessity for a chart with a nominal scale, it can provide useful structure to the information that reinforces or enhances the story being told.  For example, an ordering of best to worst for some value can add a great deal of clarity to a chart.</p>
<h4>Worked Example</h4>
<p>Based on what has been explained so far, it is hopefully clear that there are many more effective ways to represent the information shown in radar charts.  To further underscore this and to show how a little more thought and effort put into the design of a chart can have a significant effect on its efficacy, here follows a worked example based on <a href="chart1">Chart 1</a>.</p>
<p><a href="#lines">As previously highlighted</a>, the axis categories of a radar chart are frequently a nominal scale, meaning there is no relationship between their respective values.  Therefore, it is immediately clear that a bar chart would be a better representation of the data shown in <a href="chart1">Chart 1</a>.</p>
<p><a name="chart9"></a><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/wikipedia_simple.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/wikipedia_simple.png" alt="Alternative Approach Bar Chart 1" title="Alternative Approach Bar Chart 1" width="486" height="378" class="aligncenter" /></a></p>
<p>In the particular case of <a href="#chart1">Chart 1</a>, it is a fairly safe assumption to say that the chart is ultimately trying to convey the over- and under-spend of the respective departments.  As such, the following redesign focuses on the more important value, the actual spending, and its relationship to the budget, by reducing the visual salience of the budget values.</p>
<p><a name="chart10"></a><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/wikipedia_market.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/wikipedia_market.png" alt="Alternative Approach Bar Chart 2" title="Alternative Approach Bar Chart 2" width="486" height="378" class="aligncenter" /></a></p>
<p>Furthermore, it can be assumed that in this case the relative over- and under-spend of the respective departments is the primary concern.  By charting this difference as a percentage of the original budget and ordering the resulting bar chart from biggest overspend to biggest underspend, we have a very clear story of which departments are the worst offenders at both ends of the scale.</p>
<p><a name="chart11"></a><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/wikipedia_diff.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/09/wikipedia_diff.png" alt="Alternative Approach Bar Chart 3" title="Alternative Approach Bar Chart 3" width="467" height="360" class="aligncenter" /></a></p>
<h2>Conclusion</h2>
<p>Hopefully it is clear that radar charts, despite the initial appeal due to their interesting appearance, are ultimately useless, in that they are unable to efficiently and effectively communicate information to users.  Regrettably, many vendors of charting products continue to include them and users seem more interested in that first 5-second &#8220;cool&#8221; reaction than their ability to serve their purpose.  Furthermore, vendors are, quite justifiably, assumed to be experts in their field, or at least to have more expertise than consumers.  Therefore, so long as vendors of charting products continue to support and encourage fundamentally flawed features like radar charts, users will, unless educated otherwise, understandably continue to assume these features are perfectly suitable.  Vendors then often argue that consumers request these features.  And so a feedback loop of delusion has developed&#8230;</p>
<p>So I implore vendors of charting products to take a &#8220;brave&#8221; stance: please stop pointlessly including functionality that allows users to create flawed visualisations.  Or, at the very least, stop implying they are good practice by featuring them on your websites and marketing material.  You are collectively undermining the power of data visualisation by encouraging users towards cumbersome, frustrating charts that do not work, when really you should know better.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2011/09/a-critique-of-radar-charts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updating Flex Sparkline to Flex 4</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2011/04/updating-flex-sparkline-to-flex-4/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2011/04/updating-flex-sparkline-to-flex-4/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 16:50:59 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Visualisation]]></category>
		<category><![CDATA[Charts]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=516</guid>
		<description><![CDATA[In a previous post I presented a library of]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2011%252F04%252Fupdating-flex-sparkline-to-flex-4%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Updating%20Flex%20Sparkline%20to%20Flex%204%22%20%7D);"></div>
<p>In <a href="http://www.scottlogic.co.uk/blog/graham/2010/02/flex-sparkline/" target="_blank">a previous post</a> I presented a library of <a href="http://en.wikipedia.org/wiki/Sparkline target="_blank">sparkline</a> implementations for Flex 3.  I have finally gotten round to updating it for Flex 4.  The new source code, documentation and pre-compiled swf (namespace: <code>http://www.scottlogic.com/sparkline</code>) can be obtained from <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/04/Sparkline.zip'>here</a>.  As before, the components are being made available under the <a href='http://www.gnu.org/licenses/gpl.html'>GNU General Public License</a>.</p>
<p>As you can see, the versions appear identical:</p>
<p><b>Flex 3</b><br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="sparklines_3" width="445" height="85" align="center">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/SparklineApp.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/SparklineApp.swf" width="445" height="85" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
</p>
<p><b>Flex 4</b><br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="sparklines_4" width="445" height="85" align="center">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/04/SparklineApp.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/04/SparklineApp.swf" width="445" height="85" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
 </p>
<h4>Updating to Flex 4</h4>
<p>For those of you interested in some of the changes required to migrate code from Flex 3 to Flex 4, here follow some of the details required to update this particular code.</p>
<p>The main change was due to Flex 4 essentially deprecating the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/styles/StyleManager.html" target="_blank"><code>StyleManager</code></a> class and its static methods in order to provide mechanisms allowing <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=modular_5.html" target="_blank">modules</a> to have independent style declarations.  At the forefront of this change is the new <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/styles/IStyleManager2.html" target="_blank"><code>IStyleManager2</code></a> interface, an instance of which can be obtained from the static <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/styles/StyleManager.html#getStyleManager%28%29" target="_blank"><code>getStyleManager</code></a> method on <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/styles/StyleManager.html" target="_blank"><code>StyleManager</code></a> or, preferably, the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html#styleManager" target="_blank"><code>styleManager</code></a> property of <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html" target="_blank"><code>UIComponent</code></a>.  In practice, using the <code>Sparkline</code> class as an example, this means changing from the static Flex 3 style declaration approach:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Sparkline <span style="color: #0066CC;">extends</span> SparklineBase
<span style="color: #66cc66;">&#123;</span>
    <span style="color: #808080; font-style: italic;">/**
     *  @private
     */</span>
    <span style="color: #0066CC;">private</span> <span style="color: #0066CC;">static</span> <span style="color: #000000; font-weight: bold;">var</span> stylesInited:<span style="color: #0066CC;">Boolean</span> = initStyles<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #808080; font-style: italic;">/**
     *  @private
     */</span>
    <span style="color: #0066CC;">private</span> <span style="color: #0066CC;">static</span> <span style="color: #000000; font-weight: bold;">function</span> initStyles<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">Boolean</span>
    <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">var</span> sd:CSSStyleDeclaration = StyleManager.<span style="color: #006600;">getStyleDeclaration</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Sparkline&quot;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>sd<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#123;</span>
            sd = <span style="color: #000000; font-weight: bold;">new</span> CSSStyleDeclaration<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            StyleManager.<span style="color: #006600;">setStyleDeclaration</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Sparkline&quot;</span>, sd, <span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        sd.<span style="color: #006600;">defaultFactory</span> = <span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
        <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">lineStroke</span> = <span style="color: #000000; font-weight: bold;">new</span> Stroke<span style="color: #66cc66;">&#40;</span>0x828282, <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">markerFill</span> = <span style="color: #000000; font-weight: bold;">new</span> SolidColor<span style="color: #66cc66;">&#40;</span>0x2963a3<span style="color: #66cc66;">&#41;</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">markerStroke</span> = <span style="color: #000000; font-weight: bold;">new</span> Stroke<span style="color: #66cc66;">&#40;</span>0x2963a3, <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">markerRadius</span> = <span style="color: #cc66cc;">2</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">normalRangeFill</span> = <span style="color: #000000; font-weight: bold;">new</span> SolidColor<span style="color: #66cc66;">&#40;</span>0x000000, <span style="color: #cc66cc;">0.1</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">true</span>;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    ...
&nbsp;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>To overriding <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html" target="_blank"><code>UIComponent</code></a>&#8216;s <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html#moduleFactory" target="_blank"><code>moduleFactory</code></a> property to provide the &#8220;hook&#8221; for invoking the style declaration:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Sparkline <span style="color: #0066CC;">extends</span> SparklineBase
<span style="color: #66cc66;">&#123;</span>
    <span style="color: #808080; font-style: italic;">/**
     * @private
     */</span>
    <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> _moduleFactoryInitialized:<span style="color: #0066CC;">Boolean</span>;
&nbsp;
    <span style="color: #808080; font-style: italic;">/**
     * @private
     */</span>
    <span style="color: #0066CC;">public</span> override <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">set</span> moduleFactory<span style="color: #66cc66;">&#40;</span>factory:IFlexModuleFactory<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
    <span style="color: #66cc66;">&#123;</span>
        <span style="color: #0066CC;">super</span>.<span style="color: #006600;">moduleFactory</span> = factory;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>_moduleFactoryInitialized<span style="color: #66cc66;">&#41;</span>
            <span style="color: #b1b100;">return</span>;
        _moduleFactoryInitialized = <span style="color: #000000; font-weight: bold;">true</span>;
        initStyles<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/**
     * @private
     */</span>
    <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initStyles<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
    <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">var</span> sd:CSSStyleDeclaration = styleManager.<span style="color: #006600;">getStyleDeclaration</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;com.scottlogic.sparkline.Sparkline&quot;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>sd<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#123;</span>
            sd = <span style="color: #000000; font-weight: bold;">new</span> CSSStyleDeclaration<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            styleManager.<span style="color: #006600;">setStyleDeclaration</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;com.scottlogic.sparkline.Sparkline&quot;</span>, sd, <span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
        sd.<span style="color: #006600;">defaultFactory</span> = <span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
        <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">lineStroke</span> = <span style="color: #000000; font-weight: bold;">new</span> SolidColorStroke<span style="color: #66cc66;">&#40;</span>0x828282, <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">markerFill</span> = <span style="color: #000000; font-weight: bold;">new</span> SolidColor<span style="color: #66cc66;">&#40;</span>0x2963a3<span style="color: #66cc66;">&#41;</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">markerStroke</span> = <span style="color: #000000; font-weight: bold;">new</span> SolidColorStroke<span style="color: #66cc66;">&#40;</span>0x2963a3, <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">markerRadius</span> = <span style="color: #cc66cc;">2</span>;
            <span style="color: #0066CC;">this</span>.<span style="color: #006600;">normalRangeFill</span> = <span style="color: #000000; font-weight: bold;">new</span> SolidColor<span style="color: #66cc66;">&#40;</span>0x000000, <span style="color: #cc66cc;">0.1</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    ...
&nbsp;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>You will also see that as of Flex 4, getting style declarations now requires a fully qualified class name rather than just the name of the class, e.g. <code>com.scottlogic.sparkline.Sparkline</code> rather than <code>Sparkline</code>.  As before, this change is required due to the underlying shift in the approach used for style management by the framework in order to support independence between modules.</p>
<p>The other update required was due to the changed <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/IFill.html" target="_blank"><code>IFill</code></a> and <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/IStroke.html" target="_blank"><code>IStroke</code></a> interfaces.  In particular, the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/IFill.html#begin%28%29" target="_blank"><code>begin</code></a> method on <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/IFill.html" target="_blank"><code>IFill</code></a> takes an additional <code>targetOrigin</code> argument of type <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Point.html" target="_blank"><code>Point</code></a> that specifies intended origin of the shape drawing.  Similarly, <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/IStroke.html" target="_blank"><code>IStroke</code></a>&#8216;s <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/IStroke.html#apply%28%29" target="_blank"><code>apply</code></a> method now takes two additional arguments, <code>targetBounds</code> and <code>targetOrigin</code>, to provide the same drawing manipulation/restriction as <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/graphics/IFill.html" target="_blank"><code>IFill</code></a>.  Fortunately, the SDK team appear to have anticipated the potential complications and frustrations arising from these changes and have implemented them so that specifying a <code>null</code> value for the additional arguments results in identical behaviour to that which would have occurred in the Flex 3 code.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2011/04/updating-flex-sparkline-to-flex-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex Charts vs Silverlight Charts &#8211; a test of Performance</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2010/11/flex-charts-vs-silverlight-charts-a-test-of-performance/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2010/11/flex-charts-vs-silverlight-charts-a-test-of-performance/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 09:02:27 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Charts]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=368</guid>
		<description><![CDATA[This post follows on from the comparison of two Silverlight chart libraries produced by my colleague, Colin Eberhardt, by adding an implementation of the simple image processing tool in Flex using the Flex Charting library to the comparison. The results show that the Flex Charts perform easily as well as the Visiblox charts without the [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2010%252F11%252Fflex-charts-vs-silverlight-charts-a-test-of-performance%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FbEBuHe%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Flex%20Charts%20vs%20Silverlight%20Charts%20-%20a%20test%20of%20Performance%22%20%7D);"></div>
<p><em>This post follows on from the <a href="http://www.scottlogic.co.uk/blog/colin/2010/11/visiblox-charts-vs-silverlight-toolkit-charts-a-test-of-performance-2/" target="_blank">comparison of two Silverlight chart libraries</a> produced by my colleague, <a href="http://www.scottlogic.co.uk/blog/colin/" target="_blank">Colin Eberhardt</a>, by adding an implementation of the simple image processing tool in <a href="http://www.adobe.com/devnet/flex.html" target="_blank">Flex</a> using the <a href="http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf65518-7ff9.html" target="_blank">Flex Charting</a> library to the comparison.  The results show that the Flex Charts perform easily as well as the Visiblox charts without the need to specifically consider performance.</em></p>
<p>Since <a href="http://www.scottlogic.co.uk/blog/colin/" target="_blank">Colin</a> produced his comparison of the <a href="http://www.silverlight.net/content/samples/sl2/toolkitcontrolsamples/run/default.html" target="_blank">Silverlight Toolkit</a> and <a href="http://www.visiblox.com/" target="_blank">Visiblox</a> charts there has been some noted interest in how <a href="http://get.adobe.com/flashplayer/" target="_blank">Flash</a> stacks up against them.  This seems to be part of a general drive across the development community to gain a better understanding of the relative strengths of Flash/Flex, Silverlight and HTML5.  In order to contribute a little to this, I produced a comparable application to those of Colin using the charting library that is part of the free, open-source <a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4" target="_blank">Flex 4 SDK</a>.</p>
<p>Here are my Flex application and the &#8220;winning&#8221; application from Colin&#8217;s investigation side-by-side.  Click and drag a line across the image to plot the RGB pixel intensities along the line in the chart above.  From these examples, it is clear that there is little to differentiate them performance-wise.</p>
<table>
<tr>
<th style="text-align: center;">Flex Chart</th>
<th style="text-align: center;">Visiblox Chart</th>
</tr>
<tr>
<td style="text-align:center;">
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_2" width="280" height="380">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/11/FlexChartsPerformance.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/11/FlexChartsPerformance.swf" width="280" height="380">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
</td>
<td style="text-align:center;">
<object height="400" width="300" type="application/x-silverlight-2" data="data:application/x-silverlight,"><param value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/11/HistogramVisiblox.xap" name="source"><a style="text-decoration: none;" href="http://go.microsoft.com/fwlink/?LinkID=124807"><br />
<img style="border-style: none;" alt="Get Microsoft Silverlight" src="http://go.microsoft.com/fwlink/?LinkId=108181"><br />
</a><br />
</object>
</td>
</tr>
</table>
<p><span style="font-size: 0.8em;">[Squirrel image used royalty free from <a href="http://www.sxc.hu/photo/1079708" target="_blank">stock.xchng</a>; hare image used under CC licence from <a href="http://www.flickr.com/photos/heliocentric/2643028940/" target="_blank">flickr</a>]</span></p>
<h2>Implementation</h2>
<p>For details of the implementation of the Visiblox example above, see <a href="http://www.scottlogic.co.uk/blog/colin/2010/11/visiblox-charts-vs-silverlight-toolkit-charts-a-test-of-performance-2/">the original post</a>.  The mark-up for the Flex example above is as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:Application</span> <span style="color: #000066;">xmlns:fx</span>=<span style="color: #ff0000;">&quot;http://ns.adobe.com/mxml/2009&quot;</span></span>
<span style="color: #009900;">               <span style="color: #000066;">xmlns:s</span>=<span style="color: #ff0000;">&quot;library://ns.adobe.com/flex/spark&quot;</span></span>
<span style="color: #009900;">               <span style="color: #000066;">xmlns:mx</span>=<span style="color: #ff0000;">&quot;library://ns.adobe.com/flex/mx&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:layout<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:VerticalLayout</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:layout<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fx:Declarations<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:SolidColorStroke</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;axisStroke&quot;</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#cccccc&quot;</span> <span style="color: #000066;">weight</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fx:Declarations<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:Group</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;100%&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:CartesianChart</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;chart&quot;</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">&quot;100%&quot;</span> <span style="color: #000066;">visible</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:horizontalAxis<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:LinearAxis</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;xAxis&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:horizontalAxis<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:horizontalAxisRenderers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:AxisRenderer</span> <span style="color: #000066;">axis</span>=<span style="color: #ff0000;">&quot;{xAxis}&quot;</span> <span style="color: #000066;">axisStroke</span>=<span style="color: #ff0000;">&quot;{axisStroke}&quot;</span></span>
<span style="color: #009900;">                                 <span style="color: #000066;">showLabels</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000066;">tickPlacement</span>=<span style="color: #ff0000;">&quot;none&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:horizontalAxisRenderers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:verticalAxis<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:LinearAxis</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;yAxis&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:verticalAxis<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:verticalAxisRenderers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:AxisRenderer</span> <span style="color: #000066;">axis</span>=<span style="color: #ff0000;">&quot;{yAxis}&quot;</span> <span style="color: #000066;">axisStroke</span>=<span style="color: #ff0000;">&quot;{axisStroke}&quot;</span></span>
<span style="color: #009900;">                                 <span style="color: #000066;">tickPlacement</span>=<span style="color: #ff0000;">&quot;outside&quot;</span> <span style="color: #000066;">tickStroke</span>=<span style="color: #ff0000;">&quot;{axisStroke}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:verticalAxisRenderers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:series<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:LineSeries</span> <span style="color: #000066;">yField</span>=<span style="color: #ff0000;">&quot;red&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:lineStroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:SolidColorStroke</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#aa0000&quot;</span> <span style="color: #000066;">weight</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:lineStroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:LineSeries<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:LineSeries</span> <span style="color: #000066;">yField</span>=<span style="color: #ff0000;">&quot;green&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:lineStroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:SolidColorStroke</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#00aa00&quot;</span> <span style="color: #000066;">weight</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:lineStroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:LineSeries<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:LineSeries</span> <span style="color: #000066;">yField</span>=<span style="color: #ff0000;">&quot;blue&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:lineStroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:SolidColorStroke</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#0000aa&quot;</span> <span style="color: #000066;">weight</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:lineStroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:LineSeries<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:series<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:CartesianChart<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:Label</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;instructions&quot;</span> <span style="color: #000066;">visible</span>=<span style="color: #ff0000;">&quot;{!chart.visible}&quot;</span></span>
<span style="color: #009900;">                 <span style="color: #000066;">horizontalCenter</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">verticalCenter</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">                 <span style="color: #000066;">fontSize</span>=<span style="color: #ff0000;">&quot;9&quot;</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#cccccc&quot;</span></span>
<span style="color: #009900;">                 <span style="color: #000066;">text</span>=<span style="color: #ff0000;">&quot;Use the mouse to 'drag' a line across the image below.&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:Group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:Group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:Image</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;image&quot;</span></span>
<span style="color: #009900;">                  <span style="color: #000066;">source</span>=<span style="color: #ff0000;">&quot;@Embed(source='squirrel.jpg')&quot;</span></span>
<span style="color: #009900;">                  <span style="color: #000066;">mouseDown</span>=<span style="color: #ff0000;">&quot;imageMouseDownHandler(event)&quot;</span></span>
<span style="color: #009900;">                  <span style="color: #000066;">mouseUp</span>=<span style="color: #ff0000;">&quot;imageMouseUpHandler(event)&quot;</span></span>
<span style="color: #009900;">                  <span style="color: #000066;">mouseMove</span>=<span style="color: #ff0000;">&quot;imageMouseMoveHandler(event)&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:Line</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;line&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:stroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:SolidColorStroke</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#000000&quot;</span> <span style="color: #000066;">weight</span>=<span style="color: #ff0000;">&quot;3&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:stroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:Line<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:Group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:Application<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The above mark-up creates two <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/components/Group.html" target="_blank">Groups</a>: one containing the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/chartClasses/CartesianChart.html" target="_blank">CartesianChart</a> and instructions, and the other the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/Image.html" target="_blank">Image</a> and <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/primitives/Line.html" target="_blank">Line</a>.  This is remarkably similar to the mark-up of Colin&#8217;s Silverlight examples, if slightly more verbose.  The verboseness is the result of both <a href="http://www.adobe.com/devnet/flex.html" target="_blank">Flex</a> technicalities and my overriding the rather ugly default styles axis styles for aesthetic reasons.  Note that the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/chartClasses/CartesianChart.html" target="_blank">CartesianChart</a> was used rather than <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/LineChart.html" target="_blank">LineChart</a> purely because of the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/LineChart.html" target="_blank">LineChart</a> using the ugly <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/renderers/ShadowLineRenderer.html" target="_blank">ShadowLineRenderer</a> by default for <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/series/LineSeries.html" target="_blank">LineSeries</a> (the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/chartClasses/CartesianChart.html" target="_blank">CartesianChart</a> uses the simple <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/renderers/LineRenderer.html" target="_blank">LineRenderer</a>).</p>
<p>Unlike in Silverlight, there is no need to do anything <a href="http://www.scottlogic.co.uk/blog/colin/2010/06/throttling-silverlight-mouse-events-to-keep-the-ui-responsive/" target="_blank">funky</a> with mouse event handling Flex, as the <a href="http://www.developmentarc.com/site/wp-content/uploads/pdfs/understanding_the_flex_3_lifecycle_v1.0.pdf" target="_blank">Flex component lifecycle</a> means the UI will always have a chance to render.  This means a simple mouse move event handler can be used to construct the chart&#8217;s data:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> imageMouseMoveHandler<span style="color: #000000;">&#40;</span>event<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">MouseEvent</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000066; font-weight: bold;">!</span>_mouseDown<span style="color: #000000;">&#41;</span>
		<span style="color: #0033ff; font-weight: bold;">return</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	line<span style="color: #000066; font-weight: bold;">.</span>xTo = event<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">localX</span><span style="color: #000066; font-weight: bold;">;</span>
	line<span style="color: #000066; font-weight: bold;">.</span>yTo = event<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">localY</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #009900; font-style: italic;">// compute length of line</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">length</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #004993;">Math</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">sqrt</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">Math</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">pow</span><span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">.</span>xFrom <span style="color: #000066; font-weight: bold;">-</span> line<span style="color: #000066; font-weight: bold;">.</span>xTo<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span> <span style="color: #000066; font-weight: bold;">+</span>
				   <span style="color: #004993;">Math</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">pow</span><span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">.</span>yFrom <span style="color: #000066; font-weight: bold;">-</span> line<span style="color: #000066; font-weight: bold;">.</span>yTo<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #009900; font-style: italic;">// build the chart data</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">bitmapData</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">BitmapData</span> = <span style="color: #004993;">Bitmap</span><span style="color: #000000;">&#40;</span>image<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">content</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">bitmapData</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> chartData<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Array</span> = <span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> xIndex<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> yIndex<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> pixel<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">uint</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> point<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Object</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> i<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span> i <span style="color: #000066; font-weight: bold;">&lt;</span> <span style="color: #004993;">length</span><span style="color: #000066; font-weight: bold;">;</span> i<span style="color: #000066; font-weight: bold;">++</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		point= <span style="color: #000000;">&#123;</span><span style="color: #000000;">&#125;</span><span style="color: #000066; font-weight: bold;">;</span>
		xIndex = line<span style="color: #000066; font-weight: bold;">.</span>xFrom <span style="color: #000066; font-weight: bold;">+</span> <span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">.</span>xTo <span style="color: #000066; font-weight: bold;">-</span> line<span style="color: #000066; font-weight: bold;">.</span>xFrom<span style="color: #000000;">&#41;</span> <span style="color: #000066; font-weight: bold;">*</span> i <span style="color: #000066; font-weight: bold;">/</span> <span style="color: #004993;">length</span><span style="color: #000066; font-weight: bold;">;</span>
		yIndex = line<span style="color: #000066; font-weight: bold;">.</span>yFrom <span style="color: #000066; font-weight: bold;">+</span> <span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">.</span>yTo <span style="color: #000066; font-weight: bold;">-</span> line<span style="color: #000066; font-weight: bold;">.</span>yFrom<span style="color: #000000;">&#41;</span> <span style="color: #000066; font-weight: bold;">*</span> i <span style="color: #000066; font-weight: bold;">/</span> <span style="color: #004993;">length</span><span style="color: #000066; font-weight: bold;">;</span>
		pixel = <span style="color: #004993;">bitmapData</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">getPixel</span><span style="color: #000000;">&#40;</span>xIndex<span style="color: #000066; font-weight: bold;">,</span> yIndex<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
		point<span style="color: #000066; font-weight: bold;">.</span>red = pixel <span style="color: #000066; font-weight: bold;">&amp;</span> 0xff<span style="color: #000066; font-weight: bold;">;</span>
		pixel <span style="color: #000066; font-weight: bold;">&gt;&gt;</span>= <span style="color: #000000; font-weight:bold;">8</span><span style="color: #000066; font-weight: bold;">;</span>
		point<span style="color: #000066; font-weight: bold;">.</span>green = pixel <span style="color: #000066; font-weight: bold;">&amp;</span> 0xff<span style="color: #000066; font-weight: bold;">;</span>
		pixel <span style="color: #000066; font-weight: bold;">&gt;&gt;</span>= <span style="color: #000000; font-weight:bold;">8</span><span style="color: #000066; font-weight: bold;">;</span>
		point<span style="color: #000066; font-weight: bold;">.</span>blue = pixel <span style="color: #000066; font-weight: bold;">&amp;</span> 0xff<span style="color: #000066; font-weight: bold;">;</span>
		chartData<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">push</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">value</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	chart<span style="color: #000066; font-weight: bold;">.</span>dataProvider = chartData<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Once again, this code is very similar to that used in the Silverlight examples to construct chart data.  However, notice that here we can choose to take advantage of ActionScript 3&#8242;s dynamic objects to drive our chart for simplicity&#8217;s sake.  Furthermore, there has also been no need to pre-process the image data to obtain pixel information since the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/Image.html" target="_blank">Image</a>, <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Bitmap.html" target="_blank">Bitmap</a> and <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html" target="_blank">BitmapData</a> classes are designed and optimised for exactly this kind of pixel-level manipulation.</p>
<h2>Conclusions</h2>
<p>From the above examples it is apparent that there is little, if anything, to differentiate their relative performance.  Furthermore, it would be fair to say that the outright technology choice of Flash/Flex or Silverlight has not differentiated these examples.  Rather, the choice of charting library in either technology is far more significant with respect to performance.  Therefore, in this case, the technology choice would have to be driven by some other factor than performance, for example, plug-in penetration, cost or existing developer expertise.</p>
<p>However, at a more technical level there are some interesting points to consider alongside the comparative performance of the two applications.  The Silverlight examples were created with specific techniques for improving their performance.  The implication is that a naive Silverlight implementation of the application is likely to have noticeable performance issues.  In contrast, the Flex example has purposefully been created without any of the known performance improvement techniques, yet is still as responsive.</p>
<p>It is also worthwhile contrasting the respective charting libraries.  The Visiblox charting library has specifically been designed for performance over flexibility, where as the Flex charting library is the opposite.  The result is that although they are roughly equal in performance, the Flex charting library has many more options for customisation and extension than the Visiblox charting library.  However, it should be noted that the Flex charting library is relatively mature (~4 years old) compared to the Visiblox charts (~2 months old).</p>
<p>You can download the full source code for the Flex example given in this blog post here: <a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/11/FlexChartPerformance.zip" target="_blank">FlexChartPerformance.zip</a>; and the full source code for the Silverlight examples given in Colin&#8217;s blog post here: <a href="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/ChartPerformance.zip" target="_blank">ChartPerformance.zip</a></p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2010/11/flex-charts-vs-silverlight-charts-a-test-of-performance/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Stephen Few Data Visualisation Workshop</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2010/06/stephen-few-data-visualisation-workshop/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2010/06/stephen-few-data-visualisation-workshop/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 08:05:31 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Visualisation]]></category>
		<category><![CDATA[Charts]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=246</guid>
		<description><![CDATA[Last week I attended a series of information visualisation workshops run by Stephen Few. The classes were based around his three books to date: Show Me The Numbers, Information Dashboard Design and Now You See It. Here follows an overview of the material covered and my thoughts on the event. Show Me The Numbers Day [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2010%252F06%252Fstephen-few-data-visualisation-workshop%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F9ec7AP%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Stephen%20Few%20Data%20Visualisation%20Workshop%22%20%7D);"></div>
<p>Last week I attended a series of information visualisation workshops run by <a href="http://www.perceptualedge.com" target="_blank">Stephen Few</a>.  The classes were based around his three books to date: <a href="" target="_blank">Show Me The Numbers</a>, <a href="" target="_blank">Information Dashboard Design</a> and <a href="" target="_blank">Now You See It</a>.  Here follows an overview of the material covered and my thoughts on the event.</p>
<p><span style="font-size: 1.2em; font-weight: bold">Show Me The Numbers</span></p>
<p>Day one of the workshops was titled &#8220;Designing Tables and Graphs to Enlighten&#8221; and focused on how to effectively communicate a single story in a data set using a table or graph.  The starting point was to highlight that the <a href="http://en.wikipedia.org/wiki/Gricean_maxims" target="_blank">Gricean Maxims</a> apply equally well to the communication of quantitative data as they do conversational communication, i.e. information visualisation should:</p>
<ul>
<li>be as informative as necessary but not more informative than necessary (maxim of quantity)</li>
<li>not convey any message that is believed to be false or for which there is a lack of evidence (maxim of quality)</li>
<li>be relevant (maxim of relation)</li>
<li>be brief and orderly, avoiding ambiguity and obscurity of expression</li>
</ul>
<p>Fundamentally, to achieve this, <a href="http://www.perceptualedge.com" target="_blank">Stephen Few</a> proposes 2 major steps.  First, you should determine the medium that tells the story best.  (Should you use a table or a graph?  If a graph, then which kind of graph?)  Then you must design the chosen component so that the story is told clearly.  </p>
<p>For the first step, the relative strengths and weaknesses of tables and graphs and different graph types were presented.  Regarding graphs, <a href="http://www.perceptualedge.com" target="_blank">Stephen</a> presented what he considers to be the 7 relationships commonly displayed in graphs &#8211; time-series, ranking, part-to-whole, deviation, distribution, correlation and nominal comparison &#8211; and which graph types most concisely convey these relationships.  Unsurprisingly, <a href="http://en.wikipedia.org/wiki/Pie_chart" target="_blank">pie charts</a> were a graph type singled out for their general ineffectiveness (see <a href="http://www.perceptualedge.com/articles/visual_business_intelligence/save_the_pies_for_dessert.pdf">Save The Pies For Dessert</a> for details).  In addition to graph types, the concept of <a href="http://en.wikipedia.org/wiki/Small_multiple" target="_blank">small multiples</a> was highlighted as a simple technique for improving the <a href="http://en.wikipedia.org/wiki/Affordance" target="_blank">affordance</a> of graphs that endeavour to compare across data that differs only along a single variable.</p>
<p>Oh, and 3D charts, where to begin&#8230;  The almost guaranteed occlusion (where something is hidden behind something else) meaning it is impossible to see the entire picture at once?  The inability to directly compare values, sizes and/or positions due to depth?  The colour variation due to &#8220;lovely&#8221; lighting effects?</p>
<p>With determining the appropriate medium covered, a range of techniques and areas for consideration were introduced with the aim of maximising the effectiveness of the chosen component(s).  <a href="http://www.edwardtufte.com/tufte/" target="_blank">Edward Tufte</a>&#8216;s argument that the &#8220;data-ink ratio&#8221; should be maximised by removing, de-emphasising and/or regularising the unnecessary and emphasising the most important was introduced as the foundation of good table and graph design.  Additionally, the fundementals of visual perception were considered and how they can be harnessed to improve the clarity of the story being portrayed.  In particular, attributes such as size, shape, orientation and colour are <a href="http://www.infovis-wiki.net/index.php/Preattentive_processing" target="_blank">processed pre-attentively</a>.  That is, we perceive and process them instantaneously, in a highly parallelised fashion and without conscious thought, thereby laying down an  immediate interpretation before conscious thought is required.  Further to this, the pre-attentive attributes of length, 2-dimensional position, width, size and colour intensity are perceived quantitatively, i.e. some values are greater than others, and are therefore powerful building blocks for data visualisation.</p>
<p>As well as covering areas such as where best to locate the scale, how to arrange the visualisation to avoid label rotation and how to minimise problems associated with legends, there was an emphasis on the importance of colour, from when and where it is (not) required to palette choice.  A fair amount of <a href="http://www.perceptualedge.com" target="_blank">Stephen</a>&#8216;s thoughts on colour are covered in his article <a href="http://www.perceptualedge.com/articles/visual_business_intelligence/rules_for_using_color.pdf" target="_blank">Rules for Using Color</a>.  A couple of useful links that came up were <a href="http://www.personal.psu.edu/cab38/" target="_blank">Cynthia Brewer</a>&#8216;s <a href="http://www.colorbrewer.org" target="_blank">Color Brewer</a>, a tool for colour palette choice, and <a href="http://www.vischeck.com/" target="_blank">VisCheck</a>, a tool for simulating colour blindness.</p>
<p><span style="font-size: 1.2em; font-weight: bold">Information Dashboard Design</span></p>
<p>The 2nd day of the workshops, &#8220;Dashboard Design for at-a-glance monitoring&#8221;, built heavily on the first day&#8217;s lessons and focused on techniques and constructs that are of use when designing dashboards.  First up was the problem that the term &#8220;dashboard&#8221; is used for all manner of products.  <a href="http://www.perceptualedge.com" target="_blank">Stephen</a> defines a dashboard as &#8220;<em>a visual display of the most important information needed to achieve one or more objectives that has been consolidated on a single computer screen so it can be monitored and understood at a glance</em>&#8221; and states that &#8220;<em>dashboards are not comprehensive tools for analysis, decision making or management</em>&#8220;.  The monitoring requirement suggests that to some extent there must be a &#8220;live&#8221; element to the screen, while their not being comprehensive tools suggests that there should not be an abundance of controls to facilitate filtering, etc.  In my opinion <a href="http://www.perceptualedge.com" target="_blank">Stephen</a> is potentially limiting his audience with this, as most of what he presents under the context of dashboard design is just as valuable to report design and data presentation and/or analysis applications in general.</p>
<p>We started by focussing on the common mistakes made in dashboard design, such as introducing meaningless variety, arranging data poorly, misusing or overusing colour and introducing useless decoration.  Unfortunately, many of these problems appear to stem from vendors.  They are (understandably) assumed to be experts, yet their examples are usually little more than marketing fluff, so their designs are usually more concerned with graphical glitz than the actual intended purpose of a dashboard: communication.</p>
<p>Moving on to considering the techniques and practices that will improve dashboard design, the core idea was once again <a href="http://www.edwardtufte.com/tufte/" target="_blank">Tufte</a>&#8216;s &#8220;data-ink ratio&#8221; argument: &#8220;<em>reduce the non-data ink; enhance the data ink</em>&#8220;.  A number of objectives specifically for the visual design of dashboards were also prescribed: eliminate clutter and distraction, group data into logical sections, highlight what&#8217;s most important, support meaningful comparisons and discourage meaningless comparisons.  Each of 6 categories of dashboard display mechanisms (graphs, icons, text, images, drawings and organisers) was considered with the aim of achieving these goals.  The most time was spent addressing graphs; re-iterating some of the previous day&#8217;s content and introducing a couple of graph types more specifically designed for the dashboard context: <a href="http://en.wikipedia.org/wiki/Bullet_graph" target="_blank">bullet graphs</a> (see image below) and <a href="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&#038;topic_id=1" target="_blank">sparklines</a>.  <a href="http://en.wikipedia.org/wiki/Bullet_graph" target="_blank">Bullet graphs</a> are <a href="http://www.perceptualedge.com" target="_blank">Stephen Few</a>&#8216;s own <a href="http://www.perceptualedge.com/articles/misc/Bullet_Graph_Design_Spec.pdf" target="_blank">development</a> to address the requirement (unfortunately) usually fulfilled using gauges, i.e. the display of a single quantitative value against one or more comparative measures within the context of some qualitative ranges, e.g. poor, satisfactory, good.  The benefits that bullet graphs have over gauges are numerous, but in particular they take up significantly less space and are more conducive to the aforementioned objectives.  <a href="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&#038;topic_id=1" target="_blank">Sparklines</a>, on the other hand, were introduced by <a href="http://www.edwardtufte.com/tufte/" target="_blank">Tufte</a> in his book <a href="http://www.amazon.co.uk/Visual-Display-Quantitative-Information/dp/0961392142/ref=sr_1_2?ie=UTF8&#038;s=books&#038;qid=1277909297&#038;sr=8-2" target="_blank">The Visual Display of Quantitative Information</a>, and are designed to present trends or variations in a simple, space-saving way.</p>
<p><a href="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/06/bullet_graph.png"><img src="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/06/bullet_graph.png" alt="" title="bullet_graph" width="642" height="218" class="aligncenter size-full wp-image-304" /></a></p>
<p>After touching on the <a href="http://www.jnd.org/dn.mss/CH01.pdf" target="_blank">importance of the aesthetics</a> of the design (it <a href="http://www.alistapart.com/articles/indefenseofeyecandy" target="_blank">should look appealing</a> without impeding the aforementioned visual design objectives), we moved to critiqueing dashboard examples submitted by attendees.  This proved to be a good exercise of the day&#8217;s lessons both for the submitters and class as a whole.</p>
<p><span style="font-size: 1.2em; font-weight: bold">Now You See It</span></p>
<p>The final day, titled &#8220;Simple Visualisation Techniques for Quantitative Analysis&#8221;, was quite different to the preceeding days as it was focused on how to gain an understanding of and insights into data sets, rather than the communication of existing understanding.  As a basis for the rest of the day&#8217;s material, the power of sight compared to our other senses was introduced and used as the argument for why data visualisation is a vital tool for exploring and understanding data sets.  This was followed by a brief history of data visualisation, from the first evidence of tabular arrangement of data in the 2nd Century, through <a href="http://en.wikipedia.org/wiki/William_Playfair" target="_blank">William Playfair</a>&#8216;s invention of line charts, bar charts and pie charts, to the spread of home computers in the 1980s and beyond.  </p>
<p>The traits of a skilled data analyst and characteristics of good data were considered before emphasising the necessity for a solid understanding of visual perception and cognition to be able to take advantage of those traits and characteristics through visual analysis.  Consequently, some time was then spent introducing a number of core aspects of visual perception and cognition.  As during the previous classes, it was highlighted that visual perception is selective, meaning that we must encode data in such a way that what is potentially interesting or meaningful pops out by contrasting with the norm.  <a href="http://www.infovis-wiki.net/index.php/Preattentive_processing" target="_blank">Pre-attentive visual attributes</a> were again introduced as the means by which this can be achieved, with length, 2-dimensional position, width, size and colour intensity able to encode quantitative values and shape and colour hue ideal for indicating categorisation.  The limitations of perception were highlighted, with particular emphasis on the issue of <a href="http://en.wikipedia.org/wiki/Inattentional_blindness" target="_blank">inattentional blindness</a> (the fun <a href="http://psyclab1.psych.ubc.ca/~viscoglab/demonstrations/" target="_blank">examples</a> caught most of us out).  Finally, some attention was given to the meaningful characteristics of data: trends, patterns and outliers; how to highlight those characteristics; and, which patterns and comparisons in data are meaningful, e.g. steep vs gradual and random vs repeating.</p>
<p>The final stretch of the class focused on techniques for performing meaningful data analysis by attempting to bring the characteristics and patterns introduced in the preceeding material to the fore.  First we considered the various types of useful analytical interactions, such as comparing, filtering, aggregating, drilling and zooming/panning.  Specific analysis techniques were then introduced for each of 7 categories of data analysis: time series, ranking and part-to-whole, deviation, distribution, correlation, multivariate and geospatial.  <a href="http://www.perceptualedge.com" target="_blank">Stephen</a> used a number of different analytical tools &#8211; <a href="" target="_blank">Spotfire</a>, <a href="" target="_blank">Tableau</a> and <a href="" target="_blank">Panopticon</a> &#8211; to demonstrate not only some of these techniques, but also the state of what he considers to be the best of the current crop of data analysis tools.  This crossed over into discussion of what the ultimate data analysis tool would provide: a tool that provides the appropriate set of visualisations and aforementioned analytical interactions that has no distracting lag between seeing something, thinking about it and manipulating it.</p>
<p><span style="font-size: 1.2em; font-weight: bold">Closing Thoughts</span></p>
<p>My overall reaction to the workshops is definitely positive.  <a href="http://www.perceptualedge.com" target="_blank">Stephen Few</a> is an engaging presenter who is able to eloquently convey many practical techniques and principles for information visualisation.  The workshops appropriately complement the corresponding books by presenting similar material in a different way, with the group exercises and interactivity of the classes more actively re-inforcing the concepts.</p>
<p>The minor negative I would highlight about both his books and the workshops is that they appear to overly target the <a href="http://en.wikipedia.org/wiki/Business_intelligence" target="_blank">business intelligence</a> domain.  This in itself is not a problem, but I think it potentially sells short some of the ideas and information in the material, as I believe they are potentially much further reaching.  Many of the fundemental concepts he teaches are too frequently ignored or simply not appreciated by those producing even the most basic of data visualisations.  Moreover, visualisation and visual perception are key to other areas such as <a href="http://en.wikipedia.org/wiki/User_experience" target="_blank">user experience</a> and <a href="http://en.wikipedia.org/wiki/Human%E2%80%93computer_interaction" target="_blank">human-computer interaction</a>, so it is unsurprising that most of his lessons cross over to such areas.</p>
<p>For those who like the sound of this course, it is being run again later in the year in <a href="http://info.marketingqed.com/Information_Visualisation_Courses_Brochure.pdf" target="_blank">London</a>, as well as in the <a href="http://www.perceptualedge.com" target="_blank">States and Australasia</a>.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2010/06/stephen-few-data-visualisation-workshop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex Sparkline</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2010/02/flex-sparkline/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2010/02/flex-sparkline/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 15:58:41 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Visualisation]]></category>
		<category><![CDATA[Charts]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=90</guid>
		<description><![CDATA[Sparklines are described by their inventor, Edward Tufte, as &#8220;data-intense, design-simple, word-sized graphics&#8221;. They are an ideal tool for displaying trends for single entries within large data sets, for example, stock prices. As well as the standard miniature line series, Tufte&#8217;s original specification introduces a ternary sparkline, a.k.a. win-loss sparkline, where small columns are used [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2010%252F02%252Fflex-sparkline%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Flex%20Sparkline%22%20%7D);"></div>
<p><a href='http://en.wikipedia.org/wiki/Sparkline'>Sparklines</a> are described by their inventor, <a href='http://www.edwardtufte.com/tufte/'>Edward Tufte</a>, as &#8220;data-intense, design-simple, word-sized graphics&#8221;.  They are an ideal tool for displaying trends for single entries within large data sets, for example, <a href='http://www.scottlogic.co.uk/market_overview/'>stock prices</a>.  As well as the standard miniature line series, <a href='http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&#038;topic_id=1'>Tufte&#8217;s original specification</a> introduces a ternary sparkline, a.k.a. win-loss sparkline, where small columns are used to indicate &#8220;win&#8221; or &#8220;loss&#8221; and no column to indicate &#8220;draw&#8221;.</p>
<p>This article is intended to present, and distribute, <a href='http://www.adobe.com/products/flex/'>Flex</a> <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/Sparkline.zip'>implementations of sparklines, win-loss sparklines and another common variation, column sparklines</a>.  The Flex 3 version of the code and documentation can be obtained from <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/Sparkline.zip'>here</a>, while the Flex 4 version can be found <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/04/Sparkline.zip'>here</a>.  The following is an example showing some of the variations available:</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="sparklines" width="445" height="85" align="center">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/SparklineApp.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/SparklineApp.swf" width="445" height="85" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<p>The <code>Sparkline</code>, <code>TernarySparkline</code> and <code>ColumnSparkline</code> classes are all implemented using core <a href=''>Flex</a> functionality, i.e. there are no dependencies.  They all implement <a href='http://livedocs.adobe.com/flex/3/langref/mx/controls/listClasses/IListItemRenderer.html'>IListItemRenderer</a> and <a href='http://livedocs.adobe.com/flex/3/langref/mx/controls/listClasses/IDropInListItemRenderer.html'>IDropInListItemRenderer</a> interfaces, so can readily be used as standalone components or as item renderers in a <a href='http://livedocs.adobe.com/flex/3/langref/mx/controls/DataGrid.html'>DataGrid</a> or other list control.  Based on the <a href='http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&#038;topic_id=1'>original specification</a>, the <code>Sparkline</code> allows the user to optionally show a normal range, x-axis min and max points and y-axis min and max points.  All of these features and the line itself can be styled.  Similarly, the <code>TernarySparkline</code> and <code>ColumnSparkline</code> allow the user to specify the &#8220;zero&#8221; value, and style positive, negative and zero styles independently.  A final feature of the sparklines is that they will update automatically based on <code>dataProvider</code> updates, as shown in the following example, which plots a constantly-updating, randomly generated series of numbers:</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_4" width="100" height="25" align="center">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/SparklineUpdatingApp.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/SparklineUpdatingApp.swf" width="100" height="25" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<p>It is worth noting that there are a number of alternative <a href='http://www.adobe.com/products/flex/'>Flex</a> implementations available.  However, they all have further dependencies, potentially making them more heavyweight.  For example, <a href='http://www.brightpointinc.com/flexdemos/360flex/MicroChartsSample.html'>Tom Gonzalez</a> and <a href='http://www.insideria.com/2008/04/degrafa-data-part-2-the-sparkl.html'>Andrew Trice</a> both present implementations using the <a href='http://www.degrafa.org/'>Degrafa</a> graphics framework.  Because of their use of <a href='http://www.degrafa.org/'>Degrafa</a>, these implementations inherently allow users to easily use any number of extravagant styling.  Although potentially initially appealing, this goes against the good data visualisation practices suggested by experts such as <a href='http://www.perceptualedge.com'>Stephen Few</a> and <a href='http://www.edwardtufte.com/tufte/'>Tufte</a> himself; &#8220;eloquence through simplicity&#8221;[<a href='http://books.google.co.uk/books?id=NomqOzZfHqoC&#038;pg=PA96&#038;lpg=PA96&#038;dq=eloquence+through+simplicity&#038;source=bl&#038;ots=LQ2czEgImI&#038;sig=7lvX-7V8fjEI7rCsLhC1oKsuJVk&#038;hl=en&#038;ei=LzJwS5zpMYT60wT0wq3UBA&#038;sa=X&#038;oi=book_result&#038;ct=result&#038;resnum=3&#038;ved=0CBAQ6AEwAg#v=onepage&#038;q=eloquence%20through%20simplicity&#038;f=false'>ref</a>].  <a href='http://aheadofthewave.wordpress.com/2007/08/20/sparklines-in-flex/'>Lucas Pereira</a> and <a href='http://sherlockinformatics.com/wordpress/flex-code-examples/flex-sparklines'>Sherlock Informatics</a> both present implementations using the <a href='http://www.adobe.com/devnet/flex/articles/data_visualization.html'>Flex Data Visualization</a> library.  The charts contained in the library are wonderfully feature-rich and flexible.  However, this means that they are also rather heavyweight components and, therefore, using a large number of these as item renderers in an application is likely to use a lot of memory and/or make the application non-performant.  A final potential alternative are the micro-charts available in the <a href='http://code.google.com/p/birdeye/'>BirdEye</a> visualisation library.  Much like the examples using the <a href='http://www.adobe.com/devnet/flex/articles/data_visualization.html'>Flex Data Visualization</a> library, these can be perfect in situations where small numbers of instances are present, but again they introduce features that cause them to be more heavyweight than necessary.</p>
<p>The components are being made available under the <a href='http://www.gnu.org/licenses/gpl.html'>GNU General Public License</a> and can be obtained from <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2010/02/Sparkline.zip'>here (Flex 3)</a> or <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/04/Sparkline.zip'>here (Flex 4)</a>.  The zips also include some documentation and a pre-compiled swc of components, using the namespace <code>http://www.scottlogic.com/sparkline</code>.</p>
<p><strong>UPDATE 19/04/2011:</strong> I have created an updated version of the library that is Flex 4 compatible.  This is available <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2011/04/Sparkline.zip'>here</a> and a short article detailing the migratory changes can be found <a href="http://www.scottlogic.co.uk/blog/graham/2011/04/flex-sparkline-updated/" target="_blank">here</a>.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2010/02/flex-sparkline/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Missing values in Flex charts</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2009/04/missing-values-in-flex-charts/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2009/04/missing-values-in-flex-charts/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 17:08:16 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Charts]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=57</guid>
		<description><![CDATA[An oddness in default behaviour that can throw those new to Flex Charting is that segments in charts that should correspond to a data point are missing. By this I mean charts like those in the following example: When what is actually desired is the following: This is achieved by setting the filterData property on [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2009%252F04%252Fmissing-values-in-flex-charts%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Missing%20values%20in%20Flex%20charts%22%20%7D);"></div>
<p>An oddness in default behaviour that can throw those new to Flex Charting is that segments in charts that should correspond to a data point are missing.  By this I mean charts like those in the following example:<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="filterdataon" width="600" height="300" align="center" name="filterdataon">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/04/filterdataon.swf" />
      <param name="align" value="center" />
      <param name="name" value="filterdataon" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/04/filterdataon.swf" width="600" height="300" align="center" name="filterdataon">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
When what is actually desired is the following:<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="filterdataoff" width="600" height="300" align="center" name="filterdataoff">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/04/filterdataoff.swf" />
      <param name="align" value="center" />
      <param name="name" value="filterdataoff" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/04/filterdataoff.swf" width="600" height="300" align="center" name="filterdataoff">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
This is achieved by setting the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html#filterData" target="_blank">filterData</a> property on the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html" target="_blank">Series</a> to false, for example:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:LineSeries</span> <span style="color: #000066;">filterData</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>However, it is worth understanding the functionality that ties in with this property to appreciate the potential consequences.  Adobe states: </p>
<blockquote><p>
<em>When possible, set the filterData property to false. In the transformation from data to screen coordinates, the various series types filter the incoming data to remove any missing values that are outside the range of the chart; missing values would render incorrectly if drawn to the screen. For example, a chart that represents vacation time for each week in 2003 might not have a value for the July fourth weekend because the company was closed. If you know your data model will not have any missing values at run time, or values that fall outside the chart&#8217;s data range, you can instruct a series to explicitly skip the filtering step by setting its filterData property to false.</em> <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=performance_10.html" target="_blank">[ref]</a>
</p></blockquote>
<p>What is actually happening under the covers is that the series a collection of &#8220;all the data points&#8221; and a collection of &#8220;all the data points I think I want to draw&#8221;.  When <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html#filterData" target="_blank">filterData</a> is <em>true</em>, i.e. by default, the series creates the collection of &#8220;all the data points I think I want to draw&#8221; by iterating through the collection of &#8220;all the data points&#8221; and throwing away any that are <em>null</em> or <em>NaN</em> or that fall outside the axes minimum and maximum values.  By contrast, when <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html#filterData" target="_blank">filterData</a> is <em>false</em>, the two collections are identical.  Knowing this it is obvious why the segments are missing in the example above: with the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/series/LineSeries.html" target="_blank">LineSeries</a> if a data point is not to be drawn then the line segments to that data point will not be drawn; with the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/series/ColumnSeries.html" target="_blank">ColumnSeries</a> if a data point is not to be drawn then the column representing that data point will not be drawn.</p>
<p>Performance-wise, it is worth noting that performance gained by the removal of data point filtering step by setting the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html#filterData" target="_blank">filterData</a> property to false will be offset against the performance lost by drawing data points that have no bearing on the view of the chart, i.e. data points that are one or two data points removed from those around the axes maximums.  As such, the performance gain/loss and appearance gain/loss should be considered on a case by case basis.</p>
<p>An approach that can be used to get the best of both worlds is to extend the applicable series class and override the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html#updateFilter()" target="_blank">updateFilter</a> method to ensure that data points that have no bearing on the view of the chart are filtered out, but any others aren&#8217;t.  This could, for example, amount to filtering out any data points that do not lie in the range of the x-axis and that are not adjacent in the x-axis to a data point that does lie in the range of the x-axis.</p>
<p>An unfortunate note about the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html#filterData" target="_blank">filterData</a> property is that there is a bug when setting it to <em>false</em> on a <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/series/LineSeries.html" target="_blank">LineSeries</a> no data tips will show on the series (as can be seen in the example above).  The bug has been <a href="http://bugs.adobe.com/jira/browse/FLEXDMV-1899" target="_blank">filed with Adobe</a> and has recently been marked fixed, however, the fix has not yet been released.  The <a href="http://bugs.adobe.com/jira/browse/FLEXDMV-1899" target="_blank">bug report</a> details the relatively simple but somewhat nasty workaround that can be used in the meantime.</p>
<p>At <a href="http://www.scottlogic.co.uk" target="_blank">Scott Logic</a> the functionality relating to the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/Series.html#filterData" target="_blank">filterData</a> property as well as the property itself have been carefully manipulated to produce the various zooming and panning capabilities in our <a href="http://www.scottlogic.co.uk/tools/hindsight" target="_blank">Hindsight</a> application and the research charts available through our <a href="http://www.scottlogic.co.uk/market_overview" target="_blank">Market Overview</a> pages.</p>
<p>The <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/04/filterdata_source.zip'>source code</a> is now available.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2009/04/missing-values-in-flex-charts/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Custom data tips in stacked Flex charts</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2009/03/custom-data-tips-in-stacked-flex-charts/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2009/03/custom-data-tips-in-stacked-flex-charts/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 17:43:30 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Charts]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=24</guid>
		<description><![CDATA[The number of frustrating decisions in Flex&#8217;s charting API is minimal, but high up on my list is a strange decision that prevents developers from accessing information that is frequently desirable for custom data tips in stacked area, bar and column charts. The default data tips for stacked charts display, amongst other things, the total [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2009%252F03%252Fcustom-data-tips-in-stacked-flex-charts%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Custom%20data%20tips%20in%20stacked%20Flex%20charts%22%20%7D);"></div>
<p>The number of frustrating decisions in Flex&#8217;s charting API is minimal, but high up on my list is a strange decision that prevents developers from accessing information that is frequently desirable for custom data tips in stacked area, bar and column charts.  The default data tips for stacked charts display, amongst other things, the total of the values for all the series at a specific point along the x-axis and the percentage the highlighted segment forms of this total, as shown in the following example (<a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/chartsettotals.zip'>source code</a>):<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="stacked_default" width="400" height="300" align="center" name="stacked_default">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/chartsettotals.swf" />
      <param name="align" value="center" />
      <param name="name" value="stacked_default" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/chartsettotals.swf" width="400" height="300" align="center" name="stacked_default">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
If you wanted to customise the data tips and still include information such as the total and percentage values then you would be out of luck.  This why I consider the decision to give the necessary information protected scope in the relevant classes in the charting API as strange.  Fortunately circumnavigating this issue only requires a little bit of dirty work&#8230;</p>
<p>But first, a brief diversion to provide a little background&#8230;<br />
The code used to create a stacked column chart generally takes the following form:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:ColumnChart</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;stacked&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:series<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:ColumnSeries</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        ...
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:series<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:ColumnChart<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This is in fact a shortcut syntax.  The ColumnChart automatically wraps the array of series into a ColumnSet with type &#8220;stacked&#8221;, as it is the ColumnSet class that takes care of the stacking and associated behaviour rather than the ColumnChart class.  The same pattern occurs in stacked AreaChart or BarChart.  Consequently, the following MXML produces the same end result:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:ColumnChart<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:series<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:ColumnSet</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;stacked&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mx:ColumnSeries</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            ...
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:ColumnSet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:series<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mx:ColumnChart<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>When wanting to create more complex combinations of stacking, clustering and overlaying in charts, this can only be achieved by explicitly introducing (and nesting) sets &#8211; as in the second code snippet.  For further details on this see Adobe&#8217;s <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_displayingdata_11.html" target="_blank">Stacking Charts</a> article.<br />
Diversion over&#8230;</p>
<p>To be able to display customised data tips that include information relating to the stacking in a stacked ColumnChart, BarChart or AreaChart we can take one of two approaches.  Both approaches involve extending the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/series/ColumnSet.html" target="_blank">ColumnSet</a>, <a href="" target="_blank">BarSet</a> or <a href="" target="_blank">AreaSet</a> class (depending on the desired chart type) as it is the protected-scoped <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/StackedSeries.html#negTotalsByPrimaryAxis" target="_blank">negTotalsByPrimaryAxis</a>, <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/StackedSeries.html#posTotalsByPrimaryAxis" target="_blank">posTotalsByPrimaryAxis</a>, <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/StackedSeries.html#stackedMaximum" target="_blank">stackedMaximum</a> and <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/StackedSeries.html#stackedMinimum" target="_blank">stackedMinimum</a> properties that contain the interesting information.  The first approach is to override the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/StackedSeries.html#formatDataTip()" target="_blank">formatDataTip</a> method in the extended class, resulting in something along the following lines:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #3f5fbf;">/**
 * ColumnSet extension to introduce custom data tips.
 */</span>
<span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> ColumnSet <span style="color: #0033ff; font-weight: bold;">extends</span> mx<span style="color: #000066; font-weight: bold;">.</span>charts<span style="color: #000066; font-weight: bold;">.</span>series<span style="color: #000066; font-weight: bold;">.</span>ColumnSet
<span style="color: #000000;">&#123;</span>
    <span style="color: #3f5fbf;">/**
     * @inheritDoc
     */</span>
    override <span style="color: #0033ff; font-weight: bold;">protected</span> <span style="color: #339966; font-weight: bold;">function</span> formatDataTip<span style="color: #000000;">&#40;</span>hd<span style="color: #000066; font-weight: bold;">:</span>HitData<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">String</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #009900; font-style: italic;">// build up the custom data tip</span>
        <span style="color: #6699cc; font-weight: bold;">var</span> tip<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;&quot;</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #000066; font-weight: bold;">...</span>
        <span style="color: #0033ff; font-weight: bold;">return</span> tip<span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>However, I think that this approach is slightly short-sighted because it means that for every customisation of the data tips you would create a new extension.  The other, and in my opinion more reusable, approach is to expose the aforementioned properties publicly in extensions to the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/series/ColumnSet.html" target="_blank">ColumnSet</a>, <a href="" target="_blank">BarSet</a> and <a href="" target="_blank">AreaSet</a> classes.  By creating these extensions, the standard approach to customising data tips can be used, i.e. a method with the appropriate signature is passed to the chart&#8217;s <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/ChartBase.html#dataTipFunction" target="_blank">dataTipFunction</a> property.  The classes resulting from this approach would be something along the following lines:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #3f5fbf;">/**
 * ColumnSet extension to expose the stack totals for public 
 * use, e.g. in a data tip function.
 */</span>
<span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> ColumnSet <span style="color: #0033ff; font-weight: bold;">extends</span> mx<span style="color: #000066; font-weight: bold;">.</span>charts<span style="color: #000066; font-weight: bold;">.</span>series<span style="color: #000066; font-weight: bold;">.</span>ColumnSet
<span style="color: #000000;">&#123;</span>        
    <span style="color: #3f5fbf;">/**
     * @see StackedSeries.posTotalsByPrimaryAxis
     */</span>
    <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> <span style="color: #0033ff; font-weight: bold;">get</span> positiveTotalsByAxis<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Dictionary</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0033ff; font-weight: bold;">return</span> posTotalsByPrimaryAxis<span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">...</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>The minor downside to this approach is that the shortcut syntax for achieving stacked series, as used in the first example and explained above, cannot be used.  The explicit syntax must be used to ensure that the extended version of the relevant <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/StackedSeries.html" target="_blank">StackedSeries</a> extension is used.</p>
<p>The following example uses the approach presented above to provide customised data tips in the chart.  The <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/chartsettotals1.zip'>source code</a> for the example includes the necessary extensions to the <a href="http://livedocs.adobe.com/flex/3/langref/mx/charts/series/ColumnSet.html" target="_blank">ColumnSet</a>, <a href="" target="_blank">BarSet</a> and <a href="" target="_blank">AreaSet</a> classes, so feel free to use them.<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="stacked_custom" width="400" height="300" align="center" name="stacked_custom">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/chartsettotalscustom.swf" />
      <param name="align" value="center" />
      <param name="name" value="stacked_custom" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/chartsettotalscustom.swf" width="400" height="300" align="center" name="stacked_custom">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
 </p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2009/03/custom-data-tips-in-stacked-flex-charts/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Save Flex chart as image</title>
		<link>http://www.scottlogic.co.uk/blog/graham/2009/03/save-flex-chart-as-image/</link>
		<comments>http://www.scottlogic.co.uk/blog/graham/2009/03/save-flex-chart-as-image/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 16:40:20 +0000</pubDate>
		<dc:creator>Graham Odds</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Charts]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/graham/?p=3</guid>
		<description><![CDATA[The ability to allow a user to save a Flex chart, or in fact any Flex UI component, as an image has popped up on my radar several times over the last few years.  Solutions to the problem have generally involved producing a pop-up window with the UI component as an image that the user [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fgraham%252F2009%252F03%252Fsave-flex-chart-as-image%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Save%20Flex%20chart%20as%20image%22%20%7D);"></div>
<p>The ability to allow a user to save a Flex chart, or in fact any Flex UI component, as an image has popped up on my radar several times over the last few years.  Solutions to the problem have generally involved producing a pop-up window with the UI component as an image that the user can then save, either by bouncing the information off a server (<a href="http://www.jamesward.com/blog/2006/08/16/flex-paint-flex-display-object-to-png/" target="_blank">James Ward &#8211; RIA Cowboy</a> and <a href="http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&amp;postId=5021&amp;productId=2&amp;loc=en_US" target="_blank">Flex Cookbook</a>) or interacting with JavaScript (<a href="http://dougmccune.com/blog/2007/06/03/save-a-snapshot-image-of-a-flex-app-without-a-server/" target="_blank">Doug McCune</a>).  However, additions made to the framework in Flex 3 combined with new features of Flash Player 10 have made these cumbersome techniques redundant.  It is now possible to provide this functionality directly from your Flex application in two simple steps.</p>
<p>The first step involves capturing the UI component&#8217;s bitmap information.  The Flex 3 API introduced the <a href="http://livedocs.adobe.com/flex/3/langref/mx/graphics/ImageSnapshot.html" target="_blank">ImageSnapshot class</a> specifically to simplify this process.  The following line of code is sufficient to capture the image data:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">ImageSnapshot<span style="color: #000066; font-weight: bold;">.</span>captureImage<span style="color: #000000;">&#40;</span>myChart<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>However, we are able to control the image capturing more precisely by using some of the method&#8217;s optional parameters.  These allow us to specify the target resolution in dots per inch and the image encoder to use (the Flex 3 API provides a <a href="http://livedocs.adobe.com/flex/3/langref/mx/graphics/codec/PNGEncoder.html" target="_blank">PNGEncoder</a> and a <a href="http://livedocs.adobe.com/flex/3/langref/mx/graphics/codec/JPEGEncoder.html" target="_blank">JPEGEncoder</a>).   So, for example, the following line of code would capture a chart as a PNG image at a  resolution of 300dpi:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">ImageSnapshot<span style="color: #000066; font-weight: bold;">.</span>captureImage<span style="color: #000000;">&#40;</span>myChart<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">300</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> PNGEncoder<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>Now that we have captured the image data all that remains is the second, and last, step: saving the image data to the user&#8217;s file-system.  Flash Player 10 introduced a number of changes to its security sandbox, principally the ability to programmatically prompt the user<br />
to save a file to their file-system.  This is done using the FileReference class, as shown in the following lines of code:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> file<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">FileReference</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">FileReference</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
file<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">save</span><span style="color: #000000;">&#40;</span>image<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">data</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #990000;">&quot;chart.png&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>So, putting the steps together results in a method along the lines of the following code snippet:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #3f5fbf;">/**
 * Attempts to save the chart to the user's file-system.
 */</span>
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> saveChart<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> image<span style="color: #000066; font-weight: bold;">:</span>ImageSnapshot = ImageSnapshot<span style="color: #000066; font-weight: bold;">.</span>captureImage<span style="color: #000000;">&#40;</span>myChart<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">300</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> PNGEncoder<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> file<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">FileReference</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">FileReference</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    file<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">save</span><span style="color: #000000;">&#40;</span>image<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">data</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #990000;">&quot;chart.png&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>The application below shows this code in action.  The values in the data grid can be changed,<br />
with the changes reflected in the chart (just to show that I&#8217;m not cheating).<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="savechartobj" width="600" height="500" align="center">
      <param name="movie" value="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/savechartimage.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/savechartimage.swf" width="600" height="500" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
</p>
<p>The <a href='http://www.scottlogic.co.uk/blog/graham/wp-content/uploads/2009/03/SaveChartImage.zip'>source code</a> is now available.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/graham/2009/03/save-flex-chart-as-image/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		</item>
	</channel>
</rss>

