Wednesday, 14 August 2013

WPF - Create a Custom Bar chart using the Grid control with animation



    In this article we are going to see a topic of drawing a custom bar chart in WPF. Get the Values from user and bind to the control,generates the new color for each bar value. User can enter the bar value and the name to display in bar diagram. Additionally an animation is done on Load of bar chart  On Loading Chart will plot the bar from 0 to the value by slide up.

Now Let we see how we can create a animated barchart in WPF.

Bar chart :



User Input :


 List<Bar> _bar = new List<Bar>();
            _bar.Add(new Bar() { BarName="Rajesh",Value=80});
            _bar.Add(new Bar() { BarName = "Suresh", Value = 60 });
            _bar.Add(new Bar() { BarName = "Dan", Value = 40 });
            _bar.Add(new Bar() { BarName = "Sevenx", Value = 67 });
            _bar.Add(new Bar() { BarName = "Patel", Value = 15 });
            _bar.Add(new Bar() { BarName = "Joe", Value = 70 });
            _bar.Add(new Bar() { BarName = "Bill", Value = 90 });
            _bar.Add(new Bar() { BarName = "Vlad", Value = 23 });
            _bar.Add(new Bar() { BarName = "Steve", Value = 12 });
            _bar.Add(new Bar() { BarName = "Pritam", Value = 100 });
            _bar.Add(new Bar() { BarName = "Genis", Value = 54 });
            _bar.Add(new Bar() { BarName = "Ponnan", Value = 84 });
            _bar.Add(new Bar() { BarName = "Mathew", Value = 43 });
           

XAML Code:
 Make a Itemspanel Template and Item Template to define the formation of bar chart,For each value of bar random color will generate.


<Window x:Class="Custom_Bar.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Custom_Bar"
        Title="Bar Chart" Height="350" Width="525">   
    <Grid>
        <ItemsControl ItemsSource="{Binding}">
           
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"></StackPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
           
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="10,10,10,80" VerticalAlignment="Bottom">
                        <Border Name="br" Margin="3,10,3,10"  CornerRadius="5" 
                                Background="{Binding Color}"
                                Width="20" BorderBrush="{Binding Color}"  
                                BorderThickness="3" 
                                Height="{Binding Data}">
                            <Border.Triggers>
                                <EventTrigger RoutedEvent="Border.Loaded">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation From="0"  
                                                             Storyboard.TargetName="br" 
                                 Storyboard.TargetProperty="(FrameworkElement.Height)" 
                                                              Duration="0:0:02.0">
                                               
                                            </DoubleAnimation>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Border.Triggers>
                        </Border>                       
                        <TextBlock HorizontalAlignment="Center" FontWeight="Bold" 
                                   FontFamily="Latha" Text="{Binding Data}">
                            <TextBlock.RenderTransform>
                                <TranslateTransform Y="-30"/>
                            </TextBlock.RenderTransform>
                        </TextBlock>
                        <TextBlock HorizontalAlignment="Center" Foreground="{Binding Color}"
                                   FontWeight="Bold" FontFamily="Latha" 
                                   Text="{Binding Name}">
                            <TextBlock.RenderTransform>
                                <TranslateTransform Y="-20"/>
                            </TextBlock.RenderTransform>
                        </TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
           
        </ItemsControl>
    </Grid>
</Window>




C# Code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Reflection;

namespace Custom_Bar
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            List<Bar> _bar = new List<Bar>();
            _bar.Add(new Bar() { BarName="Rajesh",Value=80});
            _bar.Add(new Bar() { BarName = "Suresh", Value = 60 });
            _bar.Add(new Bar() { BarName = "Dan", Value = 40 });
            _bar.Add(new Bar() { BarName = "Sevenx", Value = 67 });
            _bar.Add(new Bar() { BarName = "Patel", Value = 15 });
            _bar.Add(new Bar() { BarName = "Joe", Value = 70 });
            _bar.Add(new Bar() { BarName = "Bill", Value = 90 });
            _bar.Add(new Bar() { BarName = "Vlad", Value = 23 });
            _bar.Add(new Bar() { BarName = "Steve", Value = 12 });
            _bar.Add(new Bar() { BarName = "Pritam", Value = 100 });
            _bar.Add(new Bar() { BarName = "Genis", Value = 54 });
            _bar.Add(new Bar() { BarName = "Ponnan", Value = 84 });
            _bar.Add(new Bar() { BarName = "Mathew", Value = 43 });
            this.DataContext = new RecordCollection(_bar);
        }
    }
   
    class RecordCollection:ObservableCollection<Record>
    {
     
        public RecordCollection(List<Bar> barvalues)
        {
            Random rand = new Random();
            BrushCollection brushcoll=new BrushCollection();

            foreach (Bar barval in barvalues)
            {
                int num = rand.Next(brushcoll.Count/3);
                Add(new Record(barval.Value,brushcoll[num], barval.BarName));               
            }            
        }
       
    }

    class BrushCollection:ObservableCollection<Brush>
    {
        public BrushCollection()
        {
            Type _brush = typeof(Brushes);
            PropertyInfo []props=  _brush.GetProperties();
            foreach (PropertyInfo prop in props)
            {
                Brush _color = (Brush)prop.GetValue(null, null);
                if ( _color!=Brushes.LightSteelBlue && _color != Brushes.White && 
                     _color != Brushes.WhiteSmoke && _color!=Brushes.LightCyan &&      
                     _color!=Brushes.LightYellow && _color!=Brushes.Linen)
                Add(_color);
            }
        }
    }

    class Bar
    {
       
        public string BarName { set; get; }

        public int Value { set; get; }

    }

    class Record:INotifyPropertyChanged
    {
        public Brush Color { set; get; }

        public string Name { set; get; }

        private int _data;
        public int Data
        {
            set
            {
                if (_data != value)
                {
                    _data = value;
                  
                }
            }
            get
            {
                return _data;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public Record(int value,Brush color,string name)
        {
            Data = value;
            Color = color;
            Name = name;
        }

        protected void PropertyOnChange(string propname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propname));
            }
        }
    }
}



From the above article you can learn how to make a animated bar chart in WPF.