search
Japanese Chinese Nederlands Espanol Italiano Deutsch Francais Twitter Rss Feeds
MicrosoftArticlesForumsFAQs
C# .NET
VB.NET
Visual Studio .NET
ADO.NET
Xml / Xslt
VB 6.0
.NET CF
GDI+
LINQ
Deployment
Security
FoxPro
Silverlight / WPF
Entity Framework
RIA Services

Web ProgrammingArticlesForumsFAQs
JavaScript
ASP
ASP.NET
Web Services

Non-MicrosoftArticlesForumsFAQs
NHibernate
Perl
PHP
Ruby
Java
Linux / Unix
Apple
Open Source

DatabasesArticlesForumsFAQs
SQL Server
Access
Oracle
MySQL
Other Databases

OfficeArticlesForumsFAQs
Excel
Word
Powerpoint
Outlook
Publisher
Money

Operating SystemsArticlesForumsFAQs
Windows 7
Windows Server
Windows Vista
Windows XP
Windows Update
MAC
Linux / UNIX

Server PlatformsArticlesForumsFAQs
BizTalk
Site Server
Exhange Server
IIS

Graphic DesignArticlesForumsFAQs
Macromedia Flash
Adobe PhotoShop
Expression Blend
Expression Design
Expression Web

OtherArticlesForumsFAQs
Subversion / CVS
Ask Dr. Dotnetsky
Active Directory
Networking
Uninstall Virus
Job Openings
Product Reviews
Search Engines
Resumes

 

View Other C# .NET Posts   Ask New Question 
How to draw a bar chart in SilverLight?
Eswaran Radhakrishnan posted at Thursday, November 13, 2008 10:56 PM

Hi all,

How to draw a bar chart in silver Light the values should be taken from an xml file.? I need to know the what are the steps to follow for that.

It's very urgent.

Thanks

 R Eswaran


 
  re
Web star replied to Eswaran Radhakrishnan at Thursday, November 13, 2008 11:12 PM
   There are three steps to create the control:
  • Load the data from a .XAML
  • Initialize the needed components
  • Set their properties so that they arrange according to the size of the control.

Each time the control is resized we only perform the last step. But if you want to load new data after you loaded some you will have to initialize the control as a new. 

We perform the last two steps separately for the two distinguishing objects:

  • Chart
  • Legend

For the chart andthe legend we have a structure that contains all their components. 

The control is built using a few classes that extend framework classes:
Bar, BarGroup, MovableCanvas, MovableFramedCanvas. Let’s take a look at them. 

Bar – extendedCanvas with additionalTextBlock value centered on top of it.

 

public class Bar: Canvas
{
private TextBlock value;

public Bar():base()
{

    value = new TextBlock();
    this.Children.Add( value );
}

private void Refresh()
{
    value.SetValue( TopProperty, - value.ActualHeight );
    value.SetValue( LeftProperty, this.Width / 2 - value.ActualWidth / 2 );
}
 

public double ValueFontSize
{
    get { return value.FontSize; }
    set { this.value.FontSize = value; Refresh(); }
}
 

public String Value
{
    get { return this.value.Text; }
    set { this.value.Text = value; Refresh(); }
}
 

public new virtual double Width
{
    get { return base.Width; }
    set{ base.Width = value; Refresh(); }
}

public new virtual double Height
{
    get { return base.Height; }
    set { base.Height = value; Refresh(); }
}
}

 

BarGroup – a list of Bar objects that are contained in a Canvas, with an additional TextBlock centered under the canvas. This class is not a great example of OOP but is good enough to save some writing so we use it anyway. Think of it as a list of Bar objects, but arranged in a Canvas. HereRefresh()distributes the bars in the main canvas leaving some space(margin) in the left and right end, and no space between them:

 

    public class BarGroup: Canvas
    {
        private System.Collections.Generic.List<Bar> bar = new System.Collections.Generic.List<Bar>();
        private double margin;
        private double fontSizeCoefficient = 0.33;
        private TextBlock label = new TextBlock();
        public BarGroup(){…}
        public void RemoveBar( int index )
        public void AddBar( double height, String text )
        private void InitializeColors()
        public String Label
        public double Margin
        public double Count
        public new double Width
        public new double Height
        public Bar this[ int index ]   // Indexer declaration
        {
            get
            {
                // Check the index limits.
                if ( index < 0 || index >= bar.Count )
                    return null;
                else
                    return bar[ index ];
            }
        }

        private void Refresh()
        {
            double w = ( this.Width - 2 * margin ) / bar.Count;
            label.FontSize = Math.Pow( w * w, fontSizeCoefficient );
            for ( int count = bar.Count, i = 0 ; i < count ; i++ )
            {
                bar[ i ].Width = w;
                bar[ i ].ValueFontSize = Math.Pow( w * w, fontSizeCoefficient );
                bar[ i ].SetValue( Canvas.TopProperty, this.Height - bar[ i ].Height );
                bar[ i ].SetValue( Canvas.LeftProperty, margin + w * i );
                bar[ i ].SetValue( Canvas.TagProperty, margin + w * i );
            }
        }

        private void AlignLabel()
        {
                label.SetValue( Canvas.TopProperty, this.Height );
                label.SetValue( Canvas.LeftProperty, ( this.Width - label.ActualWidth ) / 2 );
        }
    }

 

MovableCanvas utilizes the mouse events to easily create, as because its name explains, a movable canvas. As you can see in the second part of the figure we add the change of mouse position to the canvas coordinates.

 

public class MovableCanvas: Canvas
{
    private Point draggingStartPoint = new Point();
    private bool isDragging = false;
    public MovableCanvas()
    {
            this.MouseLeftButtonDown += new MouseEventHandler( MoveableFrameCanvas_MouseLeftButtonDown );
            this.MouseMove +=
                new
MouseEventHandler( MoveableFrameCanvas_MouseMove );
            this.MouseLeftButtonUp += new MouseEventHandler( MoveableFrameCanvas_MouseLeftButtonUp );
    }

. . .

void MoveableFrameCanvas_MouseMove( object sender, MouseEventArgs e )
{
    if ( isDragging )
    {
        Canvas o = sender as Canvas;
        if ( o != null )
        {
        o.SetValue( Canvas.LeftProperty,
            ( double )o.GetValue( Canvas.LeftProperty ) + e.GetPosition( ( System.Windows.UIElement )this.Parent ).X - draggingStartPoint.X );
        o.SetValue( Canvas.TopProperty,
            ( double )o.GetValue( Canvas.TopProperty ) + e.GetPosition( ( System.Windows.UIElement )this.Parent ).Y - draggingStartPoint.Y );
 

        draggingStartPoint =
            e.GetPosition( ( System.Windows.UIElement )this.Parent );
        }
        else
            throw new NullReferenceException();
    }
}

 

MovableFramedCanvas – simply adds four lines in the ends of its canvas.

We use MovableFramedCanvas as foundation for the legend and chart.

 

public class MovableFramedCanvas: MovableCanvas
{
    Line[] frame = new Line[ 4 ];
    Color frameColor;
    double frameThickness;

    public MovableFramedCanvas()
    {
        for ( int i = 0 ; i < 4 ; i++ )
        {
            frame[ i ] = new Line();
            this.Children.Add( frame[ i ] );
        }

        frame[ 0 ].X1 = -5;
        frame[ 1 ].X1 = -5;
        frame[ 2 ].Y1 = -5;
        frame[ 3 ].Y1 = -5;
    }

    private void AdjustFrameHeight()
    {
        frame[ 1 ].Y1 = this.Height;
        frame[ 1 ].Y2 = this.Height;
        frame[ 2 ].Y2 = this.Height + 5;
        frame[ 3 ].Y2 = this.Height + 5;
    }

    private void AdjustFrameWidth()
    {
        frame[ 0 ].X2 = this.Width + 5;
        frame[ 1 ].X2 = this.Width + 5;
        frame[ 3 ].X1 = this.Width;
        frame[ 3 ].X2 = this.Width;
    }
 
}

Here is a visual explaination for some of the variаbles in the project.

 

Legend

Our legend is actually a MovableFramedCanvas with the colors and their meanings added to it as child elements. For clarity let’s name the pair color and text (corresponding to a bar) to be a label. Then they are named labelCanvas and labelText respectively. Those three elements are grouped into the structure named LEGEND.  

 
also read this is good for barchart
Web star replied to Eswaran Radhakrishnan at Thursday, November 13, 2008 11:14 PM

http://adamkinney.com/blog/306/default.aspx

http://silverlight.net/forums/t/11364.aspx

 
See this
Sujit Patil replied to Eswaran Radhakrishnan at Thursday, November 13, 2008 11:18 PM

Hi,

Just go thr these links which will tell you abt the charts in SilverLight............

http://www.codeproject.com/KB/silverlight/PathToReusableXAML.aspx

http://petermcg.wordpress.com/2008/05/18/silverlight-20-pie-chart/

http://www.silverlightshow.net/items/Bar-Chart-control-in-Silverlight-1.1.aspx

 
  Re :: Draw a bar chart in Silverlight
Sanjay Verma replied to Eswaran Radhakrishnan at Thursday, November 13, 2008 11:32 PM

Hi,

 

Silverlight 2 Charts : Building Charts using Silverlight 2 Toolkit

Another milestone in Silverlight journey, Release of excellent Toolkit for Silverlight on Codeplex, to know more about it, do visit at :

http://www.codeplex.com/Silverlight

There are few new controls added to the Silverlight Arena as :

    • AutoCompleteBox
    • ButtonSpinner
    • Chart
    • DockPanel
    • Expander
    • HeaderedItemControl
    • HeaderedContentControl
    • ImplicitStyleManager
    • Label
    • NumericUpDown
    • TreeView
    • ViewBox
    • WrapPanel
    I guess rest are very much easy and some are familiar to Web Developers which are relevent to some of the controls in AJAX Control Toolkit e.g AutoCompleteBox,NumericUpDown etc.
    Silverlight Toolkit which exclusively supports Silverlight 2 RTW and easily installable too, To download the bits, you need to visit :

http://www.codeplex.com/Silverlight/Release/ProjectReleases.aspx?ReleaseId=18804

I personally recommend to copy all the DLL files from the Toolkit to C:\Program Files\Microsoft Silverlight\2.0.31005.0\..

This will ease to add to project as reference,and it will be like central repository of all main dll files.This is just for convenience.

Step 1 : Install Silverlight Toolkit by adding reference to DLLs inside Toolkit.

Process is very similar the way we implement for AJAX Control Toolkit, Once you do that successfully, All the controls will be available on Toolbox.

Step 2 : Implement LINQ to SQL to get data for Graph.

Step 3 : Write a Silverlight Enabled WCF service to fetch data.

For Step 2 & 3 , kindly follow my old article step-by-step :

http://pendsevikram.blogspot.com/2008/10/silverlight-2-grid-with-silverlight.html

and

http://pendsevikram.blogspot.com/2008/10/silverlight-2-grid-linq-to-sql.html

Step 4 : Configure the Chart Control and Bind it with Data.

Here I am showing first demo of Pie Chart with List<> [Collection] and then I will show it with service.

XAML Code :

<Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <charting:Chart Height="250" Width="400" Title="PUG –Silverlight Forum Monthly Activity" x:Name="MyPieChart" >
                <charting:Chart.Series>
                    <charting:PieSeries ItemsSource="{Binding}"
                                        IndependentValueBinding="{Binding ProductName}"
                                        DependentValueBinding="{Binding Sales                    </charting:PieSeries>
                </charting:Chart.Series>
            </charting:Chart></StackPanel>
   </Grid>

C# Code :

public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            GetProductSales();
         }

        public void GetProductSales()
        {
            List<ProductSales> PieData = new List<ProductSales>();
            PieData.Add(new ProductSales() { ProductName = "Vikram Pendse", Sales = 10.5 });
            PieData.Add(new ProductSales() { ProductName = "Rashi Agarwal", Sales = 20.2 });
            PieData.Add(new ProductSales() { ProductName = "Prachi Oke", Sales = 30.2 });
            PieData.Add(new ProductSales() { ProductName = "Ekta Shetty", Sales = 40.1 });
            MyPieChart.DataContext = PieData;
            MyPieChart.LegendTitle = "User Activity on forums in %";
         }
    }

    public class ProductSales
    {
        public string ProductName { get; set; }
        public double Sales { get; set; }
    }

And output will be something like this :

SLPieUData

Next Step is to bind it with Service and this time I am using Bar charts along with Pie Chart.

XAML Code :

<Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <charting:Chart Height="250" Width="400" Title="ABC Ltd.- Q2 Business Development Report" x:Name="MyPieChart" >
                <charting:Chart.Series>
                   <charting:PieSeries ItemsSource="{Binding}"
                                        IndependentValueBinding="{Binding Salesperson}"
                                        DependentValueBinding="{Binding Percentage}" >
                    </charting:PieSeries>
                </charting:Chart.Series>
            </charting:Chart>
            <charting:Chart Height="250" Width="400" Title="ABC Ltd.- Q2 Business Development Report" x:Name="MyBarChart">
                <charting:Chart.Series>
                    <charting:ColumnSeries ItemsSource="{Binding}" Title="Sales"
                                        IndependentValueBinding="{Binding Salesperson}"
                                        DependentValueBinding="{Binding Percentage}" >
                    </charting:ColumnSeries>
                </charting:Chart.Series>
            </charting:Chart>
            </StackPanel>
    </Grid>

C# Code :

Service Code :

public class MySvc
    {
        [OperationContract]
        public List<MonthlySale> GetSalesData()
        {
            MyDatabaseDataContext db = new MyDatabaseDataContext();
            var temp = from sales in db.MonthlySales
                       where sales.Salesperson.Length > 0
                       select sales;
            return temp.ToList();
        }

    }

[Note : I have created a Table MonthlySales in Northwind Database for testing purpose.]

C# Code with Proxy of the Service after consumption :

public partial class Page : UserControl
   {
       public Page()
       {
           InitializeComponent();
           this.Loaded += new RoutedEventHandler(Page_Loaded);
       }

       void Page_Loaded(object sender, RoutedEventArgs e)
       {
           Proxy.MySvcClient svc = new Proxy.MySvcClient();
           svc.GetSalesDataCompleted += new EventHandler<SL_SilverlightToolkit.Proxy.GetSalesDataCompletedEventArgs>(svc_GetSalesDataCompleted);
           svc.GetSalesDataAsync();
       }

       void svc_GetSalesDataCompleted(object sender, SL_SilverlightToolkit.Proxy.GetSalesDataCompletedEventArgs e)
       {
           MyPieChart.DataContext = e.Result;
           MyPieChart.LegendTitle = "Business Generated in %";

           MyBarChart.DataContext = e.Result;
           MyBarChart.LegendTitle = "Business Generated in %";
       }

   }

And the result will look like :

SLFinalCharts

This is how we can implement Charts in Silverlight 2 using Silverlight Toolkit, Soon I will post more interesting demos in coming days with more and more controls and unique ideas, Hope this will help you to start doing development with Silverlight Toolkit.

 

Hope this helps.

 
Re :: Draw a bar chart in Silverlight (Articles)
Sanjay Verma replied to Eswaran Radhakrishnan at Thursday, November 13, 2008 11:35 PM

See the following forum discussion where you can find some more links to the articles

http://silverlight.net/forums/p/11364/53904.aspx

Hope it helps.

 
Hi Sanjay Verma, I am getting error in ur code... Could you reply for that?
Eswaran Radhakrishnan replied to Sanjay Verma at Friday, November 14, 2008 5:39 AM

Hi Sanjay Verma,

I used ur code but I getting error in Xaml file. the error is displaying

<Grid x:Name="LayoutRoot" Background="White" >

<StackPanel>

<charting:Chart Height="250" Width="400" Title="ABC Ltd.- Q2 Business Development Report" x:Name="MyBarChart"> --------------> I am gettting error here

<charting:Chart.Series>

<charting:ColumnSeries ItemsSource="{Binding}" Title="Sales"

IndependentValueBinding="{Binding Salesperson}"

DependentValueBinding="{Binding Percentage}" >

</charting:ColumnSeries>

</charting:Chart.Series>

</charting:Chart>

</StackPanel>

</Grid>

Any Idea about that?

Thanks

R. Eswaran.