动画效果曲线图形--玄酷动态效果曲线

<UserControl x:Class="CoolCharting.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
    xmlns:local="clr-namespace:CoolCharting">
    <UserControl.Resources>
        <local:CoolConverter x:Key="CoolConverter"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">

        <toolkit:Chart x:Name="LineChart" BorderThickness="1" RenderTransformOrigin="1,0">
            <toolkit:Chart.RenderTransform>
                <ScaleTransform x:Name="LineChartScale"/>
            </toolkit:Chart.RenderTransform>

            <!-- Line series -->
            <toolkit:LineSeries
                    ItemsSource="{Binding Converter={StaticResource CoolConverter}}"
                   
                    IndependentValuePath="X"
                    DependentValuePath="Y"
                    TransitionDuration="0">
                <toolkit:LineSeries.DataPointStyle>
                    <Style TargetType="toolkit:LineDataPoint">
                        <Setter Property="Background" Value="#ff3070ff"/>
                        <Setter Property="Width" Value="10"/>
                        <Setter Property="Height" Value="10"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="toolkit:LineDataPoint">
                                    <Grid>
                                        <Ellipse
                                                Stroke="Black"
                                                StrokeThickness="1"
                                                Fill="{TemplateBinding Background}"/>
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </toolkit:LineSeries.DataPointStyle>
            </toolkit:LineSeries>

            <!-- Axes -->
            <toolkit:Chart.Axes>
                <toolkit:LinearAxis Orientation="Y" Minimum="0.5" Maximum="9.5" Interval="1" />
                <toolkit:LinearAxis Orientation="X" Minimum="-0.01" Maximum="1.01"/>
            </toolkit:Chart.Axes>

        </toolkit:Chart>

        <Button Content="刷新玄酷曲线" Click="BtnRefresh" Foreground="Black" HorizontalAlignment="Left" VerticalAlignment="Top"></Button>

    </Grid>
</UserControl>

 

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Animation;

namespace CoolCharting
{
    public partial class MainPage : UserControl
    {
        #region 成员对象
        private Random _rand = new Random();
        #endregion

        #region 构造函数
        public MainPage()
        {
            InitializeComponent();

            GenerateNewData();
        }
        #endregion

        #region 方法
        /// <summary>
        /// 创建新的数据源
        /// </summary>
        private void GenerateNewData()
        {
            var count = 25;
            var items = new Collection<Point>();
            var last = 5.0;
            for (var i = 0; i < count; i++)
            {
                //每一个新数据将产生在其上一数据附近
                var min = Math.Max(1, last - 1);
                var max = Math.Min(9, last + 1);

                //而且必须在图形范围以内
                var rand = last + ((_rand.NextDouble() * (max - min)) - (last - min));

                //将数据加入集合
                items.Add(new Point((double)i / (count - 1), rand));
                last = rand;
            }

            //绑定集合到图形上
            DataContext = items;
        }
        #endregion

        #region 事件
        /// <summary>
        /// 点击刷新按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnRefresh(object sender, RoutedEventArgs e)
        {
            GenerateNewData();
        }
        #endregion
    }

    /// <summary>
    /// 创建玄酷效果的关键转换类
    /// </summary>
    public class CoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // 空数据则退出
            if (null == value)
            {
                return null;
            }

            // 检查输入类型,不符合要求则抛出异常
            var originalPoints = value as ICollection<Point>;
            if (null == originalPoints)
            {
                throw new NotImplementedException("Cool Converter only supports value type ICollection<T>.");
            }

            // 预备参数
            var duration = TimeSpan.FromSeconds(0.5);
            var delay = TimeSpan.FromSeconds(0.5);
            var ease = new ElasticEase { Oscillations = 1 };

            // 预备故事
            var count = originalPoints.Count;
            var CoolPoints = new List<CoolPoint>(count);
            var storyboard = new Storyboard();
            var propertyPath = new PropertyPath("Y");
            var i = 0;

            foreach (var originalItem in originalPoints)
            {
                //添加相对应的玄酷数据点
                var CoolPoint = new CoolPoint { X = originalItem.X, Y = 0 };//关键
                CoolPoints.Add(CoolPoint);

                //创建一个动画效果
                var animation = new DoubleAnimationUsingKeyFrames();
                Storyboard.SetTarget(animation, CoolPoint);
                Storyboard.SetTargetProperty(animation, propertyPath);

                //配置初延时和玄酷行为
                var thisDelay = TimeSpan.FromSeconds(delay.TotalSeconds * ((i + 1.0) / count));
                animation.KeyFrames.Add(new LinearDoubleKeyFrame
                {
                    KeyTime = thisDelay,
                    Value = 0
                });
                animation.KeyFrames.Add(new EasingDoubleKeyFrame
                {
                    KeyTime = thisDelay + duration,
                    Value = originalItem.Y,
                    EasingFunction = ease
                });

                //添加动画效果到故事板
                animation.Duration = thisDelay + duration;
                storyboard.Children.Add(animation);
                i++;
            }

            //播放玄酷曲线效果
            storyboard.Begin();
            return CoolPoints;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public class CoolPoint : DependencyObject, INotifyPropertyChanged
        {
            public static readonly DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(double), typeof(CoolPoint), new PropertyMetadata(YPropertyChanged));
            private static PropertyChangedEventArgs _yPropertyChangedEventArgs = new PropertyChangedEventArgs("Y");
            public event PropertyChangedEventHandler PropertyChanged;

            public double X { get; set; }
            public double Y
            {
                get { return (double)GetValue(YProperty); }
                set { SetValue(YProperty, value); }
            }

            private static void YPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
            {
                var CoolPoint = (CoolPoint)o;
                var handler = CoolPoint.PropertyChanged;
                if (null != handler)
                {
                    handler.Invoke(CoolPoint, _yPropertyChangedEventArgs);
                }
            }
        }
    }
}

posted on 2010-07-02 15:20  chuncn  阅读(1185)  评论(0编辑  收藏  举报

导航