使用WPF Toolkit Line Series的实时图表

时间:2014-08-18 04:00:58

标签: c# wpf wpftoolkit

我有一个来自WPF Toolkit的Chart控件。绑定到图表中使用的线系列的数据集是动态的,即,当我接收数据时,新点被添加到集合中。我注意到,因此,内存消耗正在增加。因此,我将行系列中显示的点数限制为20.以下是代码。

代码背后:

public partial class MainWindow : Window
{
    ObservableCollection<ChartData> lineSeries1Data;
    Thread MyThread;
    LineSeries lineSeries;
    ChartData objChartData;
    Random r = new Random();
    LineSeries temp;

    public MainWindow()
    {
        InitializeComponent();
        objChartData = new ChartData();
        lineSeries1Data = new ObservableCollection<ChartData>();
        AddLineSeries();
        InitializeDataPoints();
        MyThread = new Thread(new ThreadStart(StartChartDataSimulation));

    }

    private void AddLineSeries()
    {
        lineSeries = AddLineSeries(Brushes.Tomato);
        lineSeries.DependentValuePath = "Value";
        lineSeries.IndependentValuePath = "Name";
        lineSeries.ItemsSource = lineSeries1Data;
        simChart.Series.Add(lineSeries);
    }

    private LineSeries AddLineSeries(Brush lineColor)
    {
        temp = new LineSeries()
        {
            PolylineStyle = this.FindResource("PolylineStyle") as Style,
            DataPointStyle = this.FindResource("LineDataPointStyle") as Style,
            Style = this.FindResource("CommonLineSeries") as Style,
            Tag = lineColor
        };
        return temp;
    }

    private void InitializeDataPoints()
    {
        lineSeries1Data.Add(new ChartData() { Name = DateTime.Now, Value = 0.0 });
        Thread.Sleep(1000);
        for (int i = 0; i < 2; i++)
        {
            lineSeries1Data.Add(new ChartData() { Name = DateTime.Now, Value = new Random().NextDouble() * 10 });
            Thread.Sleep(1000);
        }

    }

    public void StartChartDataSimulation()
    {
        int i = 0;
        while (true)
        {
            Dispatcher.Invoke(new Action(() =>
            {
                objChartData.Name = DateTime.Now;
                objChartData.Value = r.NextDouble() * 50;
                lineSeries1Data.Add(objChartData);
                if (lineSeries1Data.Count > 20)
                {
                    lineSeries1Data.RemoveAt(0);
                }
            }));
            Thread.Sleep(500);
        }
    }


    private void btnStartCharting_Click(object sender, RoutedEventArgs e)
    {
        if (MyThread.ThreadState != ThreadState.Running)
        {
            MyThread.Start();
        }
    }

}

public class ChartData
{
    DateTime _Name;
    double _Value;

    public DateTime Name
    {
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
        }
    }

    public double Value
    {
        get
        {
            return _Value;
        }
        set
        {
            _Value = value;
        }
    }

}

XAML:

<Window x:Class="WpfChartExample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:chrt="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
    xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
    Title="WPF Toolkit Dynamic Line Chart Example" Height="333" Width="1000" Closing="Window_Closing">
<Window.Resources>
    <Style x:Key="PolylineStyle" TargetType="Polyline">
        <Setter Property="StrokeThickness" Value="5" />
    </Style>

    <Style x:Key="LineDataPointStyle" TargetType="chrt:LineDataPoint">
        <!--<Setter Property="Background" Value="#0077CC" />-->
        <Setter Property="Background" >
            <Setter.Value>
                <Binding Path="Tag" RelativeSource="{RelativeSource AncestorType={x:Type chrt:LineSeries}}" />
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="White" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="Height" Value="10" />
        <Setter Property="Width" Value="10" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="chrt:LineDataPoint">
                    <Grid x:Name="Root" Opacity="1">
                        <ToolTipService.ToolTip>
                            <StackPanel Margin="2,2,2,2">
                                <ContentControl Content="{TemplateBinding IndependentValue}" ContentStringFormat="X-Value: {0:HH:mm:ss}"/>
                                <ContentControl Content="{TemplateBinding DependentValue}" ContentStringFormat="Y-Value: {0:###.###}"/>
                            </StackPanel>
                        </ToolTipService.ToolTip>
                        <Ellipse StrokeThickness="{TemplateBinding BorderThickness}" Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="CommonLineSeries" TargetType="chrt:LineSeries" BasedOn="{StaticResource {x:Type chrt:LineSeries}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="chrt:LineSeries">
                    <Canvas x:Name="PlotArea">
                        <Polyline Points="{TemplateBinding Points}" Stroke="{Binding Tag, RelativeSource={RelativeSource AncestorType={x:Type chrt:LineSeries}}}" Style="{TemplateBinding PolylineStyle}"/>
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <Style x:Key="LinearAxisStyle" TargetType="chrt:LinearAxis">
        <Setter Property="GridLineStyle">
            <Setter.Value>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="#20000000" />
                </Style>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="NonLinearAxisStyle" TargetType="chrt:DateTimeAxis">
        <Setter Property="GridLineStyle">
            <Setter.Value>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="#20000000" />
                </Style>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="DateTimeAxisLabelStyle" TargetType="chrt:DateTimeAxisLabel">
        <Setter Property="StringFormat" Value="{}{0:mm:ss}" />
    </Style>

    <Style x:Key="ChartTitleStyle" TargetType="datavis:Title">
        <Setter Property="Visibility" Value="Collapsed"/>
    </Style>
</Window.Resources>
<Grid Name="grdMain">
    <Grid.RowDefinitions>
        <RowDefinition Height="6*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <chrt:Chart x:Name="simChart"  TitleStyle="{StaticResource ResourceKey=ChartTitleStyle}">
        <chrt:Chart.LegendStyle>
            <Style TargetType="datavis:Legend">
                <Setter Property="Width" Value="0" />
            </Style>
        </chrt:Chart.LegendStyle>
        <chrt:Chart.Axes>
            <chrt:DateTimeAxis Name="xAxis" ShowGridLines="True" Orientation="X" Style="{StaticResource ResourceKey=NonLinearAxisStyle}" AxisLabelStyle="{StaticResource ResourceKey=DateTimeAxisLabelStyle}" />
            <chrt:LinearAxis Orientation="Y" ShowGridLines="True" Style="{StaticResource ResourceKey=LinearAxisStyle}" />
        </chrt:Chart.Axes>

        <!--<chrt:LineSeries IsSelectionEnabled="True" PolylineStyle="{StaticResource ResourceKey=PolylineStyle}" 
                         DataPointStyle="{StaticResource ResourceKey=LineDataPointStyle}" 
                         ItemsSource="{Binding}"
                         IndependentValueBinding="{Binding Name}" 
                         DependentValueBinding="{Binding Value}"
                         Tag="Red" Style="{StaticResource CommonLineSeries}">

        </chrt:LineSeries>-->
    </chrt:Chart>
    <Button Name="btnStartCharting" 
            Grid.Row="1" 
            Width="Auto" 
            HorizontalAlignment="Right" 
            Margin="5"
            Click="btnStartCharting_Click">
        Start Charting
    </Button>
</Grid>

在上面的代码中,当我删除第一个点时,图形刷新会受到影响。刷新变慢,有时会停止刷新。较旧的数据点也可以在图表上看到。有人可以指导我使用WPF Toolkit制作动态图表吗?

0 个答案:

没有答案