RIA Dashboards with SilverlightAuthors: Jason Beres, Devin Rader, David Negley Web Site:
http://www.infragistics.com Expression Newsletter,
subscribe nowto get yours. Silverlight can be a game-changer when the need arises to communicate rich data in an effective, graphical way in your Web 2.0 applications. Using the right controls to effectively display data can make the difference in your application, as is evidenced by the faceOut CRM Dashboard application shown in Figure 1. In this article, we are going to look at the types of controls that can be used to create effective dashboards, and we will focus on the Map control as one of the tools for effective, interactive dashboards. .png)
Figure 1. An interactive Silverlight CRM dashboard created in Silverlight (
http://labs.infragistics.com/silverlight/faceOut/) Importance of DashboardsThe Silverlight platform is well equipped for building dashboards. It brings high-fidelity graphics to a web browser, with the added benefit of a rich, client side interaction model that brings a truly interactive experience to the end user. As business needs are evolving and the ability to visualize data in a useful and interactive format for dashboards and KPIs (key performance indicators) is becoming increasingly important. For an effective dashboard, we can target several key controls: - Charts: As most of the world is focused on the economy, the emphasis on clearly describing information has become a goal of web sites and newspapers alike in recent months. Charts help communicate large sets of data visually, usually to establish a relationship between data points through comparison and, especially, contrast. Probably the most commonly seen and used chart is the pie chart, although simple line and bar charts follow close on its heels.
- Gauges (Radial and Linear): When we think about digital dashboards—those fancy web pages laden with various displays showing KPI and metric data—we think of gauge controls, a heads up display packed with critical information similar to an automobile or airplane dashboard. A gauge can come in multiple forms: it can be in a radial or rounded form, it can be a digital display of textual data, or it can be a linear graphic, like a thermometer. Using these various ways of visualizing monitoring any activity, gauges, when used appropriately, can add that extra something that can make a dashboard come alive and be relatable.
- Maps: With the ever-increasing popularity of location-based services and geo-spatial services like Live Maps from Microsoft or Google Maps, users are beginning to expect analytics and business intelligence data presented in rich and interactive maps featuring advanced functionality such as panning, zooming, mouse-over effects and tooltips. The days or presenting regional sales data or population data in a tabular are grid are over.
There are infovisual experts such as Stephen Few and Edward Tufte who argue against the use of simple line, pie, and bar charts due to the ink to information ratio. Certainly this argument holds true in certain scenarios, but sometimes a pie chart is what you need to communicate the data and make the visual impact that you’re looking for. Sometimes you want to watch the movie rather than read the book, and these simple charts are extremely familiar and usually very easy to understand. As dashboards become more advanced, the controls like a Chart or Gauge become less important (or maybe less prominent) as would something like a Map control. Geospatial Data with MapsTo create dashboards that demonstrate geospatial data, you can use the xamWebMap control from Infragistics. This control is in the NetAdvantage Silverlight Data Visualization product, which can be downloaded from
Infragistics.com. The xamWebMap control enables you to render industry standard ESRI SHP (pronounced “shape”) files in the browser via the Silverlight plug-in (see Figure 2). The SHP format includes a binary file that contains spatial information such as polygons, polylines, and points that are used to render the shapes on the map, as well as a DBF database file that contains additional information about the SHP file. This might be things like population, square miles, average income, average home value, etc. The xamWebMap will read the SHP file and the DBF file, and let you decide how you want to display or use the data that in the DBF file that describes the map. You can also wire up external data sources to the SHP file though a key-value pair mapping. This makes the control perfect for interactive data analysis. .png)
Figure 2. Chloropleth xamWebMap showing Global Oil Production Step-By-Step – Creating an Interactive Map DashboardTo get started working with data in the xamWebMap, you’ll need to give the map a SHP file to read the polygon/polyline information from so it can render the shape. Along with that, a DBF file will be read which contains additional information that you will display on the map. In this example, we are going create a single map layer that imports a shape file containing a map of the United States. This particular SHP file, “usa_st.shp”, contains the information about the boundaries of the states in the USA. To get started, you need to create a Silverlight project namedMapDashboard . If you use Visual Studio 2008 to create a new Silverlight application, you will get the associated Web application along with the Silverlight application. If you just use Expression Blend to create the Silverlight 2 application, you’ll need to know the location of the deployment ClientBin directory. This is where you need to deploy the “usa_st.shp” file so the map can read it on the client side. For the steps to complete the exercises to get the map rendering properly, you can use Expression Blend or Visual Studio 2008. We’ll be adding C# code, so either way, you’ll be using Visual Studio 2008 or Notepad to get it all wired up. Once the solution is created, you’ll need to add three assembly references to enable the MapDashboard Silverlight project for use in your application: - Infragistics.Silverlight.DataVisualization.Controls.v9.1.dll
- Infragistics.Silverlight.DataVisualization.Map.v9.1.dll
- Infragistics.Silverlight.DataVisualization.Gauge.v9.1.dll
- Infragistics.Silverlight.DataVisualization.v9.1.dll
Note: These assemblies are installed after you install the trial version of the NetAdvantage for Silverlight Data Visualization product. They are located in \%Program Files%\Infragistics\NetAdvantage for .NET 2009.1\Data Visualization\Bin. Once these are added, you can see the xamWebMap control and the other controls in the assemblies that can be used in conjunction with the xamWebMap in the Asset Library, as Figure 3 demonstrates. .png)
Figure 3. Asset Library with the custom controls loaded Next, drag the xamWebMap control onto the design surface. You should see something like Figure 4:
.jpg) (click image to zoom) Figure 4. Blend design surface with xamWebMap control added If you switch to the XAML view, you’ll notice the namespaces were added to the root, as well as the following XAML for the map: < igMap : XamWebMap >
</ igMap : XamWebMap > You’ll notice that you don’t exactly see a map yet, so let’s look the ways you can get render a shape and read data into the xamWebMap. The map works on the concept of Layers. Each layer represents a SHP file. This means you can render multiple layers, or SHP files, on top of each other to perform drill-down and data analysis. To add a Layers Collection to the Map, add this XAML: <igMap:XamWebMap> <igMap:XamWebMap.Layers> </igMap:XamWebMap.Layers> </igMap:XamWebMap> This Map.Layers collection can contain an unlimited number of MapLayer items. To render a .SHP file, you set the Reader property on the MapLayer, which maps to the ShapeFileReader class that reads the appropriate Uri that contains the SHP file and loads the file asynchronously into the MapLayer. <igMap:XamWebMap> <igMap:XamWebMap.Layers> <igMap:MapLayer> <igMap:MapLayer.Reader> <igMap:ShapeFileReader Uri="usa_st" DataMapping="Name=STATE_FIPS; Caption=STATE_NAME; Value=POP1997" /> </igMap:MapLayer.Reader> </igMap:MapLayer> </igMap:XamWebMap.Layers> </igMap:XamWebMap> In this case, the file “usa_st.shp” is located in the ClientBin directory of the ASP.NET web application. The Uri property of the ShapeFileReader class will look at the specified URI for a valid SHP file and its accompanying DBF file. The DBF contains fields like the STATE _FIPS(state FIPS code), STATE _NAME(state name) and POP1997(population for 1997). To drill into the exact fields of the DBF file, you can open it up in Excel. In the case of this .SHP file, there are 52 fields in it, which is a ton of information on each state. The xamWebMap can consume and use all of the data in the DBF file via the DataMapping property. A DataMapping will pair fields in the DBF with properties on the MapElement class such as Name, ToolTip, Caption, and Value, as shown in the above XAML. To see the results of this map, you can hit F5 to run the application. You should see something like Figure 5:
.jpg) (click image to zoom) Figure 5. Map data displaying State names So in this case, we are mapping the map elements Name , CaptionandValue properties from three columns in the dbf file. Another cool thing about the DataMappingsproperty is its ability to map data source columns to new properties on the Map Element. This means that we are not limited to mapping values from our data source just to existing properties, but can treat the Map Element essentially like a property bag, dumping all types of information (including complex objects like entire controls) into it that we might want to use later in our application. To map new properties, you simply provide a unique property name as theKeyin a DataMappingsKey/Value pair: < igMap : XamWebMap > < igMap : XamWebMap.Layers > < igMap : MapLayer ToolTip ="{} Population: {Value:n0}"> < igMap : MapLayer.Reader > < igMap : ShapeFileReader Uri ="usa_st" DataMapping="Name=STATE_FIPS; Caption=STATE_ABBR;Value=POP1997; Abbreviation=STATE_ABBR; Area=AREA;SubRegion=SUB_REGION" /> </ igMap : MapLayer.Reader > </ igMap : MapLayer > </ igMap : XamWebMap.Layers > </ igMap : XamWebMap > Now, not only are we mapping columns in the dbf to existing map element properties, but we're adding three new "properties" to the map element, mapping the state's Abbreviation, Area and Sub-region. Later, if we want to retrieve these values from a map element, we can simply use the object's GetProperty method and pass it the Key of the property value we want. You will also notice we added a Tooltip property to display the Population of the item. Using theTooltip property, you can format any of the data from DBF file, or from an external data source for display. Binding to Collections of DataThe second means of getting data into the xamWebMapis by using standard Silverlight data binding on theMapLayerobject, which exposes a DataSourceproperty. Like the ShapeFileReader, the MapLayerobject also exposes its own DataMapping property that enables you to map values from an arbitrary data source such as a collection, to properties of the MapElementobject. There is one important difference between the ShapeFileReaderand the MapLayerand the assumptions they each make about their data source. TheShapeFileReader, which knows that it will only be reading shp and dbf files, anticipates the order of records in the dbf will match exactly the order of the shape features contained in the SHP file, as dictated by the shape file format specification. A database or collection, on the other hand, generally has no limits regarding the order of its members, which can be ordered in completely random ways. TheMapLayer data source, however, needs to have a mapping between its records and MapElements explicitly defined. You can do this using the MapLayer's DataMapping property by adding a Key/Value mapping where the key is theMapElementsName property and the value is some member in the data source. When the MapLayer enumerates through its data source, it will automatically try to find MapElements with the Name property value that match the Name member designated in the layer’s DataMappings. To bind data to MapElements using the MapLayer's DataSource property, you can simply assign some object that implementsIEnumerableto the property, either in XAML or in code, then define the appropriate mappings using the MapLayer'sDataMappingsproperty. As an example, we have defined a class called StateUsage, which will contain data about the energy consumption per person for each state in the year 2001 (The data is from the US Energy Information Administration, available on the US Census bureau’s website). namespace MapDashboard { public partialclass Page : UserControl { public Page() { InitializeComponent(); } private void LayoutRoot_Loaded(object sender, RoutedEventArgs e) { this.xamWebMap1.Layers["usa_st"].DataSource = EnergyUse.EnergyUseByState; } } public classStateUsage { public string State { get; set; } public int Units { get; set; } public int Rank { get; set; } } } We expose a simple List collection of StateUsage objects which we can then assign to the MapLayers data source property: We next set up a DataMapping on the layer. In this case we are mapping the three properties exposed by the StateUsage class to properties of the Map Element. We are also giving the assigning the xamWebMap a Name, as well as the Layer: < igMap : XamWebMap x : Name ="xamWebMap1"> < igMap : XamWebMap.Layers > < igMap : MapLayer x : Name ="usa_st" ToolTip="{} Population: {Value:n0}"> < igMap : MapLayer.Reader > < igMap : ShapeFileReader Uri ="usa_st" DataMapping="Name=State, Value=Units, Caption=Rank" /> </ igMap : MapLayer.Reader > </ igMap : MapLayer > </ igMap : XamWebMap.Layers > </ igMap : XamWebMap > Finally, we reconfigure the ShapeFileReaders data mappings so that we can associate the MapElement with StateUsage objects by using the state name value: < igMap : ShapeFileReader Uri ="usa_st" DataMapping ="Name=STATE_NAME" /> Once we have data mapped to a shape element, the map allows us to use these properties as tokens when setting other map properties. For example, in the previous sample, we replaced theMapElements original string captions with the state energy usage Rank, but it would be nice if we could display both the state name and energy usage rank in the caption. To do this, we can set the Caption property on the map layer as shown below: < igMap : MapLayer x : Name ="usa_st" DataMapping="Name=State;Value=Units;Rank=Rank;" Caption="{}{Name} ({Rank})"> < igMap : MapLayer DataMapping ="Name=State;Value=Units;Rank=Rank;" Caption="{}{Name} ({Rank})" x:Name="usa_st"> Notice that a couple of things have changed in the MapLayer. First, we altered the MapLayer’s DataMapping property so that instead of the Rank property exposed by the StateUseage object being mapped to the Caption, it is now mapped to a property of the MapElement called Rank. Next, we define the MapLayer's Caption property, and for its value we are using two data tokens that represent properties of the MapElement. The extra empty set of leading brackets is required in order to escape the use of the property token braces in XAML. Now when you run the sample, you can see that the MapElement captions have changed to show each state’s energy usage rank. Creating Thematic, Data-Bound MapsNow that we’ve looked at how you can bind data to the map, let’s look at actually using that data to create a chloropleth map. A chloropleth map is a thematic map in which areas of the map are shaded or patterned in proportion to the measurement of the statistical variable being displayed on the map, such as population density or per-capita income. In this example we will show you how to use color shading to display the data of a chloropleth map. To start creating the map, the first thing we have to do is tell the MapLayer that we want to change the way it fills its MapElements with color. By default, map layers are configured to fill their MapElements by randomly selecting colors from the layer's Brushes collection, but in the case of a chloropleth map we want the map layer to use the MapElement fill color to visually represent its value, so selecting colors randomly is not appropriate. To change MapLayers default fill behavior, we can set its FillMode property. While we are there, we can also provide it with a collection of brushes that it should use when calculating the MapElements’ fill colors. < igMap : MapLayer x : Name ="usa_st" FillMode ="Chloropleth" Brushes="Orange Yellow" ToolTip="{} Population: {Value:n0}"> Next, we need to add a scale to the map layer so that the map can calculate how each value in the data set is related proportionally to other values. The xamWebMap includes three different scale types: Linear, Logarithmic, and Distribution. We can add a LinearScale to the MapLayer by assigning it to the ValueScale property: < igMap : MapLayer.ValueScale > < igMap : LinearScale /> </ igMap : MapLayer.ValueScale > By default, the LinearScale automatically determines the range of the map layer's values and calculates an appropriate number of value stops. You can also use the scale’s properties to configure these options manually. Finally, we can add a ColorSwatchPane, which is a legend that shows the distribution of the values. < igMap : MapColorSwatchPane igMap:XamWebDock.Edge="InsideBottom" LayerName="usa_st" Width="400" Height="50"DisplayMode="Swatch"/> That’s it. Running the sample results in a chloropleth map (Figure 6) being generated that shows via color how states’ energy usages are proportionally related to one another:
.jpg) (click image to zoom) Figure 6. Map Showing Population Distribution Chloropleth Viewing the data in the Chloropleth map makes it quite easy to evaluate the data visually, rather than having to resort to a tabular grid view. Adding an Interactive GaugeTo add an additional piece of information to this dashboard, we can add a gauge control that represents some other piece of data that we want to represent. In this case, we’ll add the Gauge control and generate a random number to set its value. Earlier, you added a Reference to the Gauge assembly, so you can simply drag the xamWebGauge control from the Asset Library onto your Page. Once you have the Gauge on the page, switch over to XAML and update the Scales, Needles and LabelGroups: < igGauge : XamWebRadialGauge x : Name ="xamGauge1" Height ="134" HorizontalAlignment="Right" Margin="0,0,28,32" VerticalAlignment="Bottom" Width="131"> < igGauge : XamWebRadialGauge.Scales > < igGauge : RadialGaugeScale StartValue ="1" EndValue ="10"> < igGauge : RadialGaugeScale.Needles > < igGauge : RadialGaugeNeedle Value ="5" AllowDrag ="True" /> </igGauge:RadialGaugeScale.Needles> <igGauge:RadialGaugeScale.LabelGroups> <igGauge:RadialGaugeLabelGroup Interval="1" /> </igGauge:RadialGaugeScale.LabelGroups> </igGauge:RadialGaugeScale> </igGauge:XamWebRadialGauge.Scales> </ igGauge : XamWebRadialGauge > Once added, you should see something like Figure 7 in Blend:
.jpg) (click image to zoom) Figure 7.xamWebGauge in Expression Blend Now, to add some interaction code on the map, scroll up to the XAML and add the ElementHover event to the igMap:XamWebMap open element: < igMap : XamWebMap x : Name ="xamWebMap1" ElementHover ="xamWebMap1_ElementHover" > Next, in the code behind, add the following code: private void xamWebMap1_ElementHover(object sender, Infragistics.Silverlight.Map.MapElementHoverEventArgs e) { Random random = new Random(); this.xamGauge1.Scales[0].Needles[0].Value = random.Next(1, 10); } Now, when you run the application, you can hover over the individual States and the Gauge control value will change to a random number between 1 and 10 (see Figure 8). If you combine this with the previous example of external data, or if you even look at the data in the DBF file of the SHP file, you should start to see the power of bringing a very RIA experience to dashboards with Silverlight.
.jpg) (click image to zoom) Figure 8. Map Hovering and Gauge Updating in RIA Dashboard SummaryUsing Silverlight, the RIA possibilities for creating hi-fidelity, interactive dashboards is pretty exciting. Using traditional dashboarding controls like charts and gauges is very attractive, but adding new experiences with modern data visualization controls like maps and even timeline controls make the prospect for the next generation of dashboards very interesting.
|