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 a 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.
2 comments:
Your post has been really helpful. I am trying to draw some charts, and this gave me good insight. Thanks. I have the basic graph down, but I am still struggling with how to make my graph scalable like yours. Can you explain :
Point point = (Point)(sender as Border).DataContext;
How does this work?
Happy to see posts about drawing charts, this really helps inexperienced WPF Charts developers!
Post a Comment