<?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>Saturnboy &#187; data viz</title>
	<atom:link href="http://saturnboy.com/tag/data-viz/feed/" rel="self" type="application/rss+xml" />
	<link>http://saturnboy.com</link>
	<description>Code, Work, and Life</description>
	<lastBuildDate>Wed, 28 Jul 2010 13:20:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Interactive Visualization with Axiis</title>
		<link>http://saturnboy.com/2009/11/interactive-visualization-with-axiis/</link>
		<comments>http://saturnboy.com/2009/11/interactive-visualization-with-axiis/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 21:34:39 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[axiis]]></category>
		<category><![CDATA[data viz]]></category>
		<category><![CDATA[degrafa]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=785</guid>
		<description><![CDATA[Continuing my Quest for Cool, one of my favorite aspects of data visualization is user interaction. Interactive visualizations are not only cool, but they can be extremely useful getting information to the user. Here is a screenshot from Google Analytics showing the main line chart of visitors: When you rollover one of the points, you [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing my <a href="http://saturnboy.com/2009/10/axiis-quest-for-cool/">Quest for Cool</a>, one of my favorite aspects of data visualization is user interaction.  Interactive visualizations are not only cool, but they can be extremely useful getting information to the user.</p>
<p>Here is a screenshot from <a href="http://www.google.com/analytics/">Google Analytics</a> showing the main line chart of visitors:</p>
<div class="span-14 last" style="min-height:164px;">
<img src="http://saturnboy.com/wp-content/uploads/2009/11/google-analytics-rollover.png" alt="google-analytics" title="google-analytics" width="364" height="144" /></div>
<p>When you rollover one of the points, you get a popup telling you the exact number of visitors on that date.  This simple rollover, while cool, is not particularly useful to me.  If I wanted to know exact numbers, I&#8217;d look at an Excel printout.  Thankfully, we can use <a href="http://www.axiis.org/">Axiis</a> to provide something much better.</p>
<h5>Column Stack Chart</h5>
<p class="bottom">I&#8217;ll use Axiis to show two different visualization options for the same data.  I made some artificial visitor data per day.  Here it is as a vanilla line chart I grabbed from Excel:</p>
<div class="span-14 last" style="min-height:185px;">
<img src="http://saturnboy.com/wp-content/uploads/2009/11/line-chart-data.png" alt="data" title="data" width="494" height="165" /></div>
<p class="bottom">Not very exciting, but the classic weekend lulls make our dataset a little hard to follow.  In XML, it looks like this:</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;visitors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;week</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;A&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Sun&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;0.2&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Mon&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;1.6&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Tue&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Wed&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;2.4&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Thu&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;1.8&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Fri&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;1.6&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Sat&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;0.4&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/week<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;week</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;B&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Sun&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;0.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;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Mon&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;1.2&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;day</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;Tue&quot;</span> <span style="color: #000066;">val</span>=<span style="color: #ff0000;">&quot;1.8&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        ...
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/week<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    ...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/visitors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p class="bottom">Since the data per day is a little annoying, let&#8217;s try to smooth it out by collecting up the day data into weeks.  This is easy to do in Axiis by using the <code>ColumnStack</code> layout.  Recall that <code>Layout</code>s in Axiis specify how incoming data will be rendered to the display.  Here&#8217;s an abbreviated snippet of code showing the relevant parts:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:DataCanvas</span> id=<span style="color: #ff0000;">&quot;dc&quot;</span> ...<span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:HBoxLayout</span> id=<span style="color: #ff0000;">&quot;myLayout&quot;</span> ...<span style="color: #7400FF;">&gt;</span></span>
&nbsp;
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:ColumnStack</span> id=<span style="color: #ff0000;">&quot;myStack&quot;</span> ...</span>
<span style="color: #000000;">                    dataProvider=<span style="color: #ff0000;">&quot;{myLayout.currentDatum.day}&quot;</span></span>
<span style="color: #000000;">                    dataField=<span style="color: #ff0000;">&quot;val&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:drawingGeometries</span> ... <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:HBoxLayout</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:DataCanvas</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>First, we use an <code>HBoxLayout</code> layout to render our weeks into columns (the <code>dataProvider</code> is the <code>visitors.week</code> array), and inside that we use a <code>ColumnStack</code> layout to render our days stacked one on top of another (the <code>dataProvider</code> is the current week&#8217;s <code>day</code> array).</p>
<p class="bottom">Here is the result (view source enabled):</p>
<div id="flashcontent-axiis-column-stack">
Flash is required.  <a href="http://www.adobe.com/go/getflashplayer">Get it here!</a>
</div>
<p></p>
<p>The column stack chart is nice because it enables us to distinguish the macro trend over the weeks, traffic is obviously dying off from week A to week H.  But it does a poor job illuminating intra-week data.  For example, it&#8217;s hard to tell how Monday of week A compares to Monday of week B.</p>
<h5>Interactive Column-in-Column Chart</h5>
<p>Another option to visualize our simulated visitor data is empower the user.  Start with a super simple column chart of the aggregated week data, and allow the user to drill down into the day data via some interaction.  The implementation I&#8217;ve chosen below uses an inset column chart to show the day data when the user mouses over a week column.</p>
<p class="bottom">In order to display week data, we first need to pre-process our day data to aggregate it into weeks.  Axiis makes this trivial with <code>DataSet</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span> ds:DataSet = <span style="color: #000000; font-weight: bold;">new</span> DataSet<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
ds.<span style="color: #006600;">processXmlString</span><span style="color: #66cc66;">&#40;</span>myXML.<span style="color: #006600;">toXMLString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
ds.<span style="color: #006600;">aggregateData</span><span style="color: #66cc66;">&#40;</span>ds.<span style="color: #0066CC;">data</span>.<span style="color: #0066CC;">object</span>.<span style="color: #006600;">visitors</span>, <span style="color: #ff0000;">&quot;week.day&quot;</span>, <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;val&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>The <code>aggregateDate()</code> method walks our XML hierarchy and rolls up aggregates of <code>day.val</code> at every level.  When processing is complete, <code>visitors</code> has a new <code>aggregates</code> object that contains <code>day_val_sum</code> (and min, max, and average) for all the days in the entire data set.  And one level down, <code>week</code> also has a new <code>aggregates</code> object that contains <code>day_val_sum</code> for just the days in that week.</p>
<p class="bottom">Next, we construct our visualization using a pair of <code>DataCanvas</code> objects and a pair of <code>BaseLayout</code> layouts, one for the main column chart showing aggregated week data, and the other for an inset column chart showing just the current week&#8217;s day data.  Here I&#8217;m using the same column-chart-the-long-way code as I used <a href="http://saturnboy.com/2009/10/axiis-quest-for-cool/">last post</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:DataCanvas</span> id=<span style="color: #ff0000;">&quot;dc&quot;</span> ...<span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:BaseLayout</span> id=<span style="color: #ff0000;">&quot;myLayout&quot;</span> ...</span>
<span style="color: #000000;">            itemMouseOver=<span style="color: #ff0000;">&quot;mouseOverHandler(event)&quot;</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:drawingGeometries</span><span style="color: #7400FF;">&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:RegularRectangle</span> id=<span style="color: #ff0000;">&quot;myBar&quot;</span> ... <span style="color: #7400FF;">/&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:RasterText</span> id=<span style="color: #ff0000;">&quot;myBarLabel&quot;</span>... <span style="color: #7400FF;">/&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:drawingGeometries</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:referenceRepeater</span> ... <span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:states</span><span style="color: #7400FF;">&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:State</span></span>
<span style="color: #000000;">                    enterStateEvent=<span style="color: #ff0000;">&quot;mouseOver&quot;</span></span>
<span style="color: #000000;">                    exitStateEvent=<span style="color: #ff0000;">&quot;mouseOut&quot;</span> ... <span style="color: #7400FF;">/&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:states</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:BaseLayout</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:DataCanvas</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:DataCanvas</span> id=<span style="color: #ff0000;">&quot;dc2&quot;</span> ...<span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:BaseLayout</span> id=<span style="color: #ff0000;">&quot;myLayout2&quot;</span> ...<span style="color: #7400FF;">&gt;</span></span>
&nbsp;
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:drawingGeometries</span><span style="color: #7400FF;">&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:RegularRectangle</span> ... <span style="color: #7400FF;">/&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:RasterText</span> ... <span style="color: #7400FF;">/&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:drawingGeometries</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:referenceRepeater</span> ... <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:BaseLayout</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:DataCanvas</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>The interaction is achieved by the <code>itemMouseOver</code> event on the main column chart&#8217;s layout.  Note that we are <b>not</b> listening for events on the columns themselves, rather we listen on the parent <code>BaseLayout</code>.  The layout is responsible for attaching individual listeners to all of its children as they are rendered to the display.  Layouts have events for all possible mouse interactions, including click, double-click, mouse over, mouse out, etc.  This is one of the nicest features of Axiis.  Since user interaction is managed by the layout and not by the rendered geometry, I change whatever I want about the geometry or how it is rendered and user interactions are preserved.  The code is also pleasantly clean.</p>
<p>What&#8217;s more, the main column chart uses an Axiis <code>State</code> to create a visual rollover effect on the columns.  The <code>State</code> is used to trigger some visual changes (column stroke weight is increased and label font is bolded) on <code>mouseOver</code> and then reverts the changes on <code>mouseOut</code>.</p>
<p class="bottom">Here is the event handler attached to the <code>itemMouseOver</code> event on the layout:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> mouseOverHandler<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:LayoutItemEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #808080; font-style: italic;">//change dataset to current mouseOver'd column</span>
    myLayout2.<span style="color: #006600;">dataProvider</span> = <span style="color: #0066CC;">e</span>.<span style="color: #006600;">item</span>.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">day</span>;
&nbsp;
    <span style="color: #808080; font-style: italic;">//set color</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #0066CC;">color</span>:uint = myPalette.<span style="color: #006600;">colors</span><span style="color: #66cc66;">&#91;</span><span style="color: #0066CC;">e</span>.<span style="color: #006600;">item</span>.<span style="color: #0066CC;">index</span><span style="color: #66cc66;">&#93;</span>;
    myPalette2.<span style="color: #006600;">colorFrom</span> = <span style="color: #0066CC;">color</span>;
    myPalette2.<span style="color: #006600;">colorTo</span> = PaletteUtils.<span style="color: #006600;">darker</span><span style="color: #66cc66;">&#40;</span>PaletteUtils.<span style="color: #006600;">darker</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">color</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
    <span style="color: #808080; font-style: italic;">//hide text</span>
    insetText.<span style="color: #0066CC;">visible</span> = <span style="color: #000000; font-weight: bold;">false</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The <code>LayoutItemEvent</code> event contains all kinds of useful information when it arrives at our handler.  First, we set the <code>dataProvider</code> of our inset chart using the day data from the highlighted week column.  Next, we use some <a href="http://www.degrafa.org/">Degrafa</a> color magic to set the colors of the inset&#8217;s columns from the color of the highlighted week column.  And finally, we hide the reminder text.</p>
<p class="bottom">Here is the result (view source enabled):</p>
<div id="flashcontent-axiis-column-in-column">
Flash is required.  <a href="http://www.adobe.com/go/getflashplayer">Get it here!</a>
</div>
<p></p>
<p>The end result is a fairly cool visualization that does a good job initially hiding unnecessary information, but later reveals it upon user interaction.  For example, toggle back and forth between week B and week C.  You can easily see a shift in traffic to the first half of week C compared to week B.</p>
<h5>Postscript</h5>
<p>I recently discovered another amazing data visualization framework.  <a href="http://vis.stanford.edu/protovis/">Protovis</a> is an awesome Javascript library created by some <a href="http://vis.stanford.edu/">hella smart dudes</a> at Stanford.  If I ever needed to do any visualizations on the web, and was banned from using Flex, I&#8217;d definitely use Protovis.</p>
<h5 style="padding-top:10px;">Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/axiis/axiis_column_stack/axiis_column_stack.html">AxiisColumnStack</a> (<a href="http://saturnboy.com/proj/axiis/axiis_column_stack/srcview/axiis_column_stack.zip">download</a>)</li>
<li><a href="http://saturnboy.com/proj/axiis/axiis_column_in_column/axiis_column_in_column.html">AxiisColumnInColumn</a> (<a href="http://saturnboy.com/proj/axiis/axiis_column_in_column/srcview/axiis_column_in_column.zip">download</a>)</li>
</ul>
<div>
<script type="text/javascript">
swfobject.embedSWF('http://saturnboy.com/proj/axiis/axiis_column_stack/axiis_column_stack.swf', 'flashcontent-axiis-column-stack', '440', '230', '9.0.28', 'playerProductInstall.swf', false, { bgColor:'#dddddd', base:'.' });
swfobject.embedSWF('http://saturnboy.com/proj/axiis/axiis_column_in_column/axiis_column_in_column.swf', 'flashcontent-axiis-column-in-column', '440', '230', '9.0.28', 'playerProductInstall.swf', false, { bgColor:'#dddddd', base:'.' });
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2009/11/interactive-visualization-with-axiis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Axiis and the Quest for Cool</title>
		<link>http://saturnboy.com/2009/10/axiis-quest-for-cool/</link>
		<comments>http://saturnboy.com/2009/10/axiis-quest-for-cool/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 05:50:32 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[axiis]]></category>
		<category><![CDATA[data viz]]></category>
		<category><![CDATA[degrafa]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=748</guid>
		<description><![CDATA[Axiis is an advanced data visualization framework built on top of Degrafa. And when I say advanced, I mean really advanced. I found my way to Axiis because I wanted the maximum amount of visual control that I could get. Axiis is designed to support any kind of visualization you could possibly imagine, but I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.axiis.org/">Axiis</a> is an advanced data visualization framework built on top of <a href="http://www.degrafa.org/">Degrafa</a>. And when I say advanced, I mean <a href="http://www.flexjunk.com/examples/SmithChartExample/SmithChartExample.html">really advanced</a>.  I found my way to Axiis because I wanted the maximum amount of visual control that I could get.  Axiis is designed to support any kind of visualization you could possibly imagine, but I don&#8217;t really care about that part of the framework.  Instead, I just want to take your average boring graph and make it way cool.</p>
<p>Lately, I&#8217;ve been working on a project at <a href="http://www.gorillalogic.com/">work</a> that places a real premium on cool.  This post has nothing to do with that project, of course.  It&#8217;s all about the quest for cool and my personal journey with Axiis.</p>
<h5>Simple Ass Column Chart</h5>
<p>In the beginning, I had a simple data set and just wanted create a basic column chart.  I tried to follow the <a href="http://www.insideria.com/2009/07/axiis---an-introduction-and-tu.html">Intro and Tutorial</a>, but I must admit I got a little lost the first time through.  Hopefully, this will be an even easier introduction to the Axiis framework.</p>
<p class="bottom">Here is our data in MXML:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:XML</span> id=<span style="color: #ff0000;">&quot;myXML&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;">&lt;columns<span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;A&quot;</span> val=<span style="color: #ff0000;">&quot;10&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;B&quot;</span> val=<span style="color: #ff0000;">&quot;9&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;C&quot;</span> val=<span style="color: #ff0000;">&quot;7&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;D&quot;</span> val=<span style="color: #ff0000;">&quot;5.5&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;E&quot;</span> val=<span style="color: #ff0000;">&quot;6&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;F&quot;</span> val=<span style="color: #ff0000;">&quot;3&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;G&quot;</span> val=<span style="color: #ff0000;">&quot;4&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;">&lt;col label=<span style="color: #ff0000;">&quot;H&quot;</span> val=<span style="color: #ff0000;">&quot;2.5&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;">&lt;/columns<span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/mx:XML</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>We want to render this data to the screen as a bunch of columns (aka <code>RegularRectangle</code>s).  So, the next thing that we need to do is process our data and feed it into an Axiis <code>Layout</code>.  A <code>Layout</code> is the main element in any Axiis chart; it takes incoming data and renders it to the display.</p>
<p class="bottom">Here we process our data and set our <code>Layout</code>&#8216;s <code>dataProvider</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> complete<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> ds:DataSet = <span style="color: #000000; font-weight: bold;">new</span> DataSet<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
    ds.<span style="color: #006600;">processXmlString</span><span style="color: #66cc66;">&#40;</span>myXML.<span style="color: #006600;">toXMLString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    myLayout.<span style="color: #006600;">dataProvider</span> = ds.<span style="color: #0066CC;">data</span>.<span style="color: #0066CC;">object</span>.<span style="color: #006600;">columns</span>.<span style="color: #006600;">col</span>;
    dc.<span style="color: #006600;">invalidateDisplayList</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p class="bottom">And here is the basic shell of our entire application:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;">&lt;?xml version=<span style="color: #ff0000;">&quot;1.0&quot;</span> encoding=<span style="color: #ff0000;">&quot;utf-8&quot;</span>?<span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;mx:Application</span> ...<span style="color: #7400FF;">&gt;</span></span>
    ...
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:LinearScale</span> id=<span style="color: #ff0000;">&quot;vScale&quot;</span> <span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:DataCanvas</span> id=<span style="color: #ff0000;">&quot;dc&quot;</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:BaseLayout</span> id=<span style="color: #ff0000;">&quot;myLayout&quot;</span><span style="color: #7400FF;">&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:drawingGeometries</span><span style="color: #7400FF;">&gt;</span></span>
                    <span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:RegularRectangle</span> id=<span style="color: #ff0000;">&quot;myBar&quot;</span>... <span style="color: #7400FF;">/&gt;</span></span>
                    <span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:RasterText</span> id=<span style="color: #ff0000;">&quot;myBarLabel&quot;</span> ... <span style="color: #7400FF;">/&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:drawingGeometries</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:referenceRepeater</span><span style="color: #7400FF;">&gt;</span></span>
                    <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:GeometryRepeater</span><span style="color: #7400FF;">&gt;</span></span>
                        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:geometry</span><span style="color: #7400FF;">&gt;</span></span>
                            <span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:RegularRectangle</span> ... <span style="color: #7400FF;">/&gt;</span></span>
                        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:geometry</span><span style="color: #7400FF;">&gt;</span></span>
                        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:modifiers</span><span style="color: #7400FF;">&gt;</span></span>
                            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:PropertyModifier</span> ... <span style="color: #7400FF;">/&gt;</span></span>
                        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:modifiers</span><span style="color: #7400FF;">&gt;</span></span>
                    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:GeometryRepeater</span><span style="color: #7400FF;">&gt;</span></span>
                <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:referenceRepeater</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:BaseLayout</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:layouts</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:backgroundGeometries</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:VAxis</span> ... <span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:backgroundGeometries</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:DataCanvas</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/mx:Application</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p class="bottom">Stepping through the code element by element, we see:</p>
<ol>
<li><b>LinearScale</b> &#8211;  We use a <code>LinearScale</code> to convert from data values to screen values (aka pixels).  So a data value of 5.5 might translate into 11 pixels, 42 pixels, or 55 pixels depending on the scale.</li>
<li><b>DataCanvas</b> &#8211; The <code>DataCanvas</code> contains all Axiis graph elements.  This is analogous to Flex 4&#8242;s <code>Graphic</code> container for FXG elements, and Degrafa&#8217;s <code>Surface</code> container for drawing elements.</li>
<li><b>Layout</b> &#8211; <code>BaseLayout</code> is the parent of all layouts and the most flexible.</li>
<li><b>drawingGeometries</b> &#8211; We draw each column as a <code>RegularRectangle</code> and each label as a <code>RasterText</code>.  Positioning and sizing is guided by the reference geometry created by the <code>referenceRepeater</code>.  Column height is computed using the current value of the data from the <code>Layout</code> converted to screen coordinates by the <code>LinearScale</code>.</li>
<li><b>referenceRepeater</b> &#8211; The reference geometry and repeated property combine to <i>create</i> a visualization for the data.  So, repeating rectangles horizontally gives a column chart, repeating rectangles vertically gives a bar chart, repeating line segments horizontally given a line chart, etc.</li>
<li><b>VAxis</b> &#8211; Draw a vertical axis underneath our graph layer by using the <code>backgroundGeometries</code> layer of the <code>DataCanvas</code>.  I like to use a negative x value to shift the axis left to get it out from underneath the chart (and compensate by shifting the entire <code>DataCanvas</code> right with a positive x value).</li>
</ol>
<p>That&#8217;s it for the high-level stuff, the dirty little details are in the code.  A little trial-and-error went a long way to teach me what the hell each of the various parameters actually did.  The <a href="http://www.insideria.com/2009/07/axiis---an-introduction-and-tu.html">Intro and Tutorial</a> article does a good job covering some of the details and tricks like the vertical flip trick, and I also recommend <a href="http://www.twgonzalez.com/blog/?p=267">Tom&#8217;s session</a> from AdobeMAX.</p>
<h5>User Interaction Coolness</h5>
<p>Last, we&#8217;ll add a little dash of coolness to our application with a simple rollover effect on our columns.  Using an Axiis <code>State</code>, we modify a few properties of our <code>drawingGeometries</code> on the <code>mouseOver</code> event to create a rollover effect.</p>
<p class="bottom">The <code>State</code> code:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:BaseLayout</span> id=<span style="color: #ff0000;">&quot;myLayout&quot;</span> ...<span style="color: #7400FF;">&gt;</span></span>
    ...
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:states</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:State</span> enterStateEvent=<span style="color: #ff0000;">&quot;mouseOver&quot;</span></span>
<span style="color: #000000;">                exitStateEvent=<span style="color: #ff0000;">&quot;mouseOut&quot;</span></span>
<span style="color: #000000;">                targets=<span style="color: #ff0000;">&quot;{[barFill,barStroke,myBarLabel]}&quot;</span></span>
<span style="color: #000000;">                properties=<span style="color: #ff0000;">&quot;{['alpha','weight','fontWeight']}&quot;</span></span>
<span style="color: #000000;">                values=<span style="color: #ff0000;">&quot;{[1,2,'bold']}&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:states</span><span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/axiis:BaseLayout</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<h5>Cool Colors</h5>
<p>Using Degrafa geometry to build our chart gives us total control of the shape and design, but if we really want something cool, we need to use color.  For our column chart, we&#8217;ll use an Axiis <code>LayoutAutoPalette</code> element to create a smooth color gradient for each bar.</p>
<p class="bottom">Here is the code:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;axiis:LayoutAutoPalette</span> id=<span style="color: #ff0000;">&quot;myPalette&quot;</span> layout=<span style="color: #ff0000;">&quot;{myLayout}&quot;</span></span>
<span style="color: #000000;">        colorFrom=<span style="color: #ff0000;">&quot;0xFF99FF&quot;</span></span>
<span style="color: #000000;">        colorTo=<span style="color: #ff0000;">&quot;0x6699FF&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;degrafa:SolidFill</span> id=<span style="color: #ff0000;">&quot;barFill&quot;</span> color=<span style="color: #ff0000;">&quot;{myPalette.currentColor}&quot;</span> <span style="color: #7400FF;">/&gt;</span></span></pre></div></div>

<p>The <code>LayoutAutoPalette</code> interpolates from a starting color to an ending color for each data value in the <code>Layout</code>.  We then feed the palette&#8217;s current color into a standard Degrafa <code>SolidFill</code>.  Lastly, the fill is applied to the <code>RegularRectangle</code> in the <code>drawingGeometries</code> section of our <code>Layout</code> to create a pretty gradient of bars from left to right.  Note that color is <i>not</i> proportional to the data value, but Axiis certainly provides the functionality to make a column chart with bars colored by height.</p>
<h5>The Result</h5>
<p class="bottom">Here it is, rollover effect and all (view source enabled):</p>
<div id="flashcontent-axiis-simple-column">
Flash is required.  <a href="http://www.adobe.com/go/getflashplayer">Get it here!</a>
</div>
<h5 style="padding-top:10px;">Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/axiis/axiis_simple_column/axiis_simple_column.html">AxiisSimpleColumn</a> (<a href="http://saturnboy.com/proj/axiis/axiis_simple_column/srcview/axiis_simple_column.zip">download</a>)</li>
</ul>
<div>
<script type="text/javascript">
swfobject.embedSWF('http://saturnboy.com/proj/axiis/axiis_simple_column/axiis_simple_column.swf', 'flashcontent-axiis-simple-column', '440', '230', '9.0.28', 'playerProductInstall.swf', false, { bgColor:'#dddddd', base:'.' });
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2009/10/axiis-quest-for-cool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
