Do Your Free WPF Line Chart Yourself

There are some free WPF charting controls around the web but, sometimes what you get is a limited version of something that soon will not be free, that’s why develop your own controls is a great idea and thanks to WPF is not so difficult.

In order to do this we will use the Polyline class and an ItemsControl to draw the grid lines.

XAML:

<Window x:Class=”PolylineTest.Window1″

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

Title=”Polyline Test” Height=”700″ Width=”700″>

<Viewbox Stretch=”Fill”>

<Grid x:Name=”myGrid”>

<ItemsControl x:Name=”itemsControl” ItemsSource=”{Binding}”>

<ItemsControl.ItemsPanel>

<ItemsPanelTemplate>

<StackPanel IsItemsHost=”True” Orientation=”Horizontal”/>

</ItemsPanelTemplate>

</ItemsControl.ItemsPanel>

<ItemsControl.ItemTemplate>

<DataTemplate>

<Border BorderBrush=”LightGray” BorderThickness=”0.1″ Width=”10″ Loaded=”Border_Loaded”/>

</DataTemplate>

</ItemsControl.ItemTemplate>

</ItemsControl>

</Grid>

</Viewbox>

</Window>

Code Behind:

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.Windows.Threading;

using System.Collections.ObjectModel;

namespace PolylineTest

{

/// <summary>

/// Interaction logic for Window1.xaml

/// </summary>

public partial class Window1 : Window

{

Polyline myPolyline;

DispatcherTimer timer = new DispatcherTimer();

Random gen = new Random(DateTime.Now.Millisecond);

int x = 0;

int step = 10;

ObservableCollection<Point> points = new ObservableCollection<Point>();

public Window1()

{

InitializeComponent();

myPolyline = new Polyline();

myPolyline.Stroke = System.Windows.Media.Brushes.SlateGray;

myPolyline.StrokeThickness = 1;

myPolyline.FillRule = FillRule.EvenOdd;

myGrid.Children.Add(myPolyline);

timer.Interval = TimeSpan.FromMilliseconds(500);

timer.Tick += new EventHandler(timer_Tick);

timer.Start();

this.DataContext = points;

}

private void timer_Tick(object sender, EventArgs e)

{

Point point = new Point(x, gen.Next(1000));

x += step;

points.Add(point);

}

private void Border_Loaded(object sender, RoutedEventArgs e)

{

Point point = (Point)(sender as Border).DataContext;

myPolyline.Points.Add(point);

}

}

}

Every 0.5 seconds an item is added to the source of the ItemsControl and then a Border is created, just after that we take the Point within the DataContext of the Border and add it to the Polyline. Easy! :)

Please, if this is helpful leave your comment. If there are any questions just fire away!

FeR.

6 Comments

  1. Ray Zhang said,

    July 30, 2008 at 7:47 am

    Hi Fernando,

    Do u know how to implement click event for a line in WPF?
    Thanks

    Regards
    Ray Zhang

  2. fernandojhoel said,

    July 30, 2008 at 1:07 pm

    Hi Ray!

    In that case would be better create the single lines and register the MouseLeftButtonDown event for these line objects.

    You can change the BorderLoaded handler to something like this:

    private void Border_Loaded(object sender, RoutedEventArgs e)
    {
    Point point = (Point)(sender as Border).DataContext;
    Line line = new Line();
    line.StrokeThickness = 1;
    line.Stroke = System.Windows.Media.Brushes.SlateGray;
    line.X1 = lastPoint.X;
    line.Y1 = lastPoint.Y;
    line.X2 = point.X;
    line.Y2 = point.Y;
    line.MouseLeftButtonDown += new MouseButtonEventHandler(line_MouseLeftButtonDown);
    myGrid.Children.Add(line);

    lastPoint = point;
    }

    as you can see, you must add a field (lastPoint) in order to have a reference of the previous point to set the initial point of the next line.

    This works for me, I hope for you too, let me know.

  3. Subramaniam said,

    December 13, 2008 at 1:56 pm

    Hi Its very useful for me, but for me the DispatcherTimer is not coming in the coding.Am at beginning level pls help me .
    Using System.Threading.DispatcherTimer is not in my system.
    How to get It..?
    Thanking in Advance.

  4. LEO said,

    January 29, 2009 at 9:01 pm

    Hi Fernando,

    The WPF line chart instructions was a great help! Thank-you.

    I did however find that the chart begins large and eventually crushes up small – Is there any way you can lock the size of the chart and have the line graph run off the screen like a dynamic graph.

    Regards Leon

  5. Thanos said,

    March 24, 2009 at 12:32 pm

    Great job , my friend!

    Your blog is really helpful

  6. Praveen Krishna R said,

    June 9, 2009 at 5:34 pm

    Hi Fernado,

    Thank you very much for providing, such a useful sample.


Post a Comment