Degrafa Skin ChartLetztes Jahr sah ich ein hübsches Beispiel, wie man Diagramme in Flex mithilfe von Degrafa ansprechend gestalten kann. Das Beispiel war ein Diagramm im Stil der Nike+ Website. Man kann es sich hier anschauen: Nike+ Beispiel.

Endlich habe ich die Zeit gefunden, mich näher mit dem Beispiel beschäftigen. Damit man besser versteht, worin der eigentliche Kern des Diagramm-Skinnings mit Degrafa liegt, habe ich alles "Unwichtige" aus dem Original geworfen.

Den Source-Code gibt es am Ende des Beitrags zum Herunterladen.

Kurzinfo: Was ist Degrafa

Wer Degrafa noch nicht kennt: Ich hatte es Anfang 2008 im Artikel Degrafa, ein Grafik-Framework für Flex, mit den folgenden Worten vorgestellt:

Es handelt sich dabei um deklaratives Grafik-Framework. Mithilfe von MXML-Beschreibungen können Formen gezeichnet, komplexe Grafiken erstellt oder Skins samt CSS-Support geschaffen werden.

Skinning-Beispiel anschauen

Meine ausgedünnte und etwas veränderte Flexanwendung sieht folgermaßen aus:

Im Wesentlichen handelt es sich um eine ColumnChart-Komponente. Die X- und Y-Achse wurden quasi entfernt und die Balken mit Degrafa gestaltet.

Ein LinearGradientFill sorgt für den blauen Verlauf als Füllung des Balkens. Der Balken selbst ist ein RoundedRectangleComplex mit abgerundeten Ecken.

Eine weiße Kontur (SolidStroke) wird als Trennlinie eingesetzt und mithilfe des HorizontalLineRepeater regelmäßig wiederholt.

Quellcode

Der Quellcode besteht aus zwei Teilen: der Hauptapplikation und dem Skin für die Balken des Diagramms.

Zuerst das Degrafa-Skin:

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2.   xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://www.degrafa.com/2007">
  3.     :Script>
  4.        
  5.             [Bindable]
  6.             private var awidth:Number=0;
  7.  
  8.             [Bindable]
  9.             private var aheight:Number=0;
  10.            
  11.             override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
  12.                 super.updateDisplayList(unscaledWidth, unscaledHeight);
  13.                 awidth = unscaledWidth;
  14.                 aheight = unscaledHeight;
  15.                 }
  16.         ]]>
  17.     :Script>
  18.  
  19.     >
  20.        
  21.           id="myFill" angle="90">
  22.              alpha=".9" color="#00A0E3"/>
  23.              alpha="1" color="#095570"/>
  24.          >      
  25.     >
  26.  
  27.  
  28.    >
  29.      
  30.       id="myStroke" color="#FFF" alpha=".2"/>
  31.    >
  32.    
  33.     >   
  34.        
  35.           fill="{myFill}" width="{awidth}" height="{aheight}"
  36.             bottomLeftRadius="20" bottomRightRadius="20" topLeftRadius="20" topRightRadius="20">   
  37.                                    
  38.                        
  39.            
  40.                 y="{aheight+1}"
  41.                 x="0"
  42.                 x1="{awidth}"
  43.                 moveOffsetY="-25"
  44.                 count="{aheight/20}"
  45.                 stroke="{myStroke}"
  46.             />
  47.         >   
  48.     >
  49.    
  50.    
  51.    
  52.     >
  53.         .filters:BevelFilter id='bevelFilter' xmlns:flash.filters='flash.filters.*'
  54.               angle='45' distance='4' highlightAlpha='0.3'
  55.               blurX='3' blurY='3' highlightColor='#ffffff'  knockout='false'         
  56.               quality='1' shadowAlpha='0.2' shadowColor='#000000'  strength='1' type='inner'              
  57.          />
  58.     >
  59. >

Und hier die Hauptanwendung:

XML:
  1. <?xml version="1.0"?>
  2. :Application backgroundGradientColors="[0xFCF2B2, 0xFCF2B2]" backgroundGradientAlphas="[1,1]"
  3.                 xmlns:mx="http://www.adobe.com/2006/mxml">
  4.                
  5.   :Script>
  6.     
  7.      import mx.collections.ArrayCollection;
  8.      
  9.      [Bindable]
  10.      public var myData:ArrayCollection = new ArrayCollection([
  11.         {Tag:"Mo", Wert:2000},
  12.         {Tag:"Di", Wert:1700},
  13.         {Tag:"Mi", Wert:2000},
  14.         {Tag:"Do", Wert:1800},
  15.         {Tag:"Fr", Wert:1600},
  16.         {Tag:"Sa", Wert:1800},
  17.         {Tag:"So", Wert:1600} ]);       
  18.   ]]>
  19. :Script>
  20.  
  21.    
  22.     :Canvas backgroundColor="0xffffff" width="450" height="225" verticalScrollPolicy="off">
  23.    
  24.    
  25.     :ColumnChart id="myCChart" width="400" height="200" dataProvider="{myData}"
  26.                     columnWidthRatio=".8" top="10"
  27.                   backgroundElements="{new Array()}"
  28.                   horizontalCenter="0"
  29.                   seriesFilters="[]">
  30.                            
  31.        
  32.         :series>     
  33.            :ColumnSeries itemRenderer="barChartRenderer" xField="Tag" yField="Wert" />
  34.         :series>                  
  35.                   
  36.                   
  37.            
  38.         :horizontalAxis>
  39.            :CategoryAxis id="c1" dataProvider="{myData}" categoryField="Tag" />
  40.         :horizontalAxis>
  41.        
  42.        
  43.         :horizontalAxisRenderers>
  44.              :AxisRenderer axis="{c1}" showLabels="true" tickLength="0" showLine="false" />
  45.          :horizontalAxisRenderers>
  46.        
  47.        
  48.         :verticalAxis>
  49.               :LinearAxis id="c2" padding="20" maximum="2000" minimum="0" interval="10" autoAdjust="false"/>
  50.         :verticalAxis>
  51.        
  52.                
  53.         :verticalAxisRenderers>
  54.             :AxisRenderer axis="{c2}" showLabels="false" tickLength="0" showLine="false"/>
  55.         :verticalAxisRenderers>
  56.              
  57.  
  58.        
  59.      :ColumnChart>     
  60.     :Canvas>   
  61. :Application>

Gleiches Chart ohne Degrafa

Zum Schluss noch einen Blick auf das Original-Chart. Entfernt man den itemRenderer mit dem Degrafa-Skin barChartRenderer, sieht das Diagramm so aus:

Chart ohne Degrafa

Link: Degrafa
Download: Quellcode (.zip)
Link: Nike+ graph using Degrafa/Flex 3