private static bool IsNumericalAxisInverse(CartesianSeries series)
        {
            NumericalAxis axis = series.VerticalAxis as NumericalAxis;

            if (axis != null)
            {
                return(axis.IsInverse);
            }

            axis = ((RadCartesianChart)series.Chart).VerticalAxis as NumericalAxis;
            if (axis != null)
            {
                return(axis.IsInverse);
            }

            axis = series.HorizontalAxis as NumericalAxis;
            if (axis != null)
            {
                return(axis.IsInverse);
            }

            axis = ((RadCartesianChart)series.Chart).HorizontalAxis as NumericalAxis;
            if (axis != null)
            {
                return(axis.IsInverse);
            }

            return(false);
        }
        private static bool TryRunStackedBarsAnimtation(CartesianSeries series)
        {
            Canvas renderSurface         = Telerik.Windows.Controls.ChildrenOfTypeExtensions.FindChildByType <Canvas>(series);
            List <FrameworkElement> bars = new List <FrameworkElement>();

            foreach (FrameworkElement uiElement in renderSurface.Children)
            {
                Border           bar = uiElement as Border;
                ContentPresenter cp  = uiElement as ContentPresenter;
                if ((bar != null && (bar.DataContext is CategoricalDataPoint)) ||
                    (cp != null && cp.Content is CategoricalDataPoint))
                {
                    bars.Add(uiElement);
                }
            }

            Storyboard        storyboard = new Storyboard();
            RadCartesianChart chart      = (RadCartesianChart)series.Chart;
            int      initialDelay        = (int)(BarAnimationDuration.TimeSpan.Milliseconds * chart.Series.IndexOf(series));
            TimeSpan?beginTime           = TimeSpan.FromMilliseconds(initialDelay);

            for (int i = 0; i < bars.Count; i++)
            {
                var animation = BuildStackedBarAnimation(bars[i], beginTime, BarAnimationDuration, series);
                storyboard.Children.Add(animation);
                beginTime = new TimeSpan(0, 0, 0, 0, initialDelay + (BarDelayInMilliseconds * (i + 1)));
            }

            return(Run(storyboard, series));
        }
Beispiel #3
0
 /// <summary>
 /// Sets the visibility of the cursor and adjusts visibility of axis labels accordingly
 /// </summary>
 /// <param name="series"></param>
 /// <param name="visible"></param>
 private void SetCursorVisibility(CartesianSeries series, bool visible)
 {
     if (visible)
     {
         CursorVisible = true;
         if (series.AxisX is LinearAxis x)
         {
             x.ShowLabels = false;
         }
         if (series.AxisY is LinearAxis y)
         {
             y.ShowLabels = false;
         }
     }
     else
     {
         CursorVisible = false;
         if (series.AxisX is LinearAxis x)
         {
             x.ShowLabels = true;
         }
         if (series.AxisY is LinearAxis y)
         {
             y.ShowLabels = true;
         }
     }
 }
        private static double CalculateSeriesMiddle(CartesianSeries series, Func <DataPoint, double> position)
        {
            double min = double.PositiveInfinity;
            double max = double.NegativeInfinity;

            IList <DataPoint> dataPoints = GetDataPoints(series);

            foreach (DataPoint dp in dataPoints)
            {
                if (dp.IsInPlotRange)
                {
                    double pos = position(dp);
                    if (pos < min)
                    {
                        min = pos;
                    }
                    if (max < pos)
                    {
                        max = pos;
                    }
                }
            }

            return((min + max) / 2);
        }
        private static TimeSpan?CalculateBeginTime(CartesianSeries series)
        {
            RadCartesianChart chart = (RadCartesianChart)series.Chart;

            if (chart.Series.Count == 1)
            {
                return(null);
            }

            int delay = DelayInMilliseconds * chart.Series.IndexOf(series) / chart.Series.Count;

            return(new TimeSpan(0, 0, 0, 0, delay));
        }
        private static void CartesianAnimationChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
        {
            CartesianSeries series = (CartesianSeries)target;

            if ((CartesianAnimation)args.NewValue == CartesianAnimation.None)
            {
                series.Loaded -= ChartSeries_Loaded;
                series.DataBindingComplete -= ChartSeries_DataBindingComplete;
            }

            if ((CartesianAnimation)args.OldValue == CartesianAnimation.None)
            {
                series.Loaded += ChartSeries_Loaded;
                series.DataBindingComplete += ChartSeries_DataBindingComplete;
            }
        }
Beispiel #7
0
        private static bool TryRunSeriesAnimation(ChartSeries series)
        {
            if (!HasDataPointsInPlotRange(series))
            {
                return(false);
            }

            int count = (int)series.GetValue(ChartAnimationUtilities.RunningAnimationsCountProperty);

            if (count > 0)
            {
                return(false);
            }

            bool started = false;

            CartesianSeries cartesianSeries = series as CartesianSeries;

            if (cartesianSeries != null)
            {
                CartesianAnimation animation = GetCartesianAnimation(cartesianSeries);
                if (animation == CartesianAnimation.Drop || animation == CartesianAnimation.DropWithDelay)
                {
                    bool useDelay = animation == CartesianAnimation.DropWithDelay;
                    started |= TryRunDropAnimtation(cartesianSeries, useDelay);
                }
                if (animation == CartesianAnimation.Rise || animation == CartesianAnimation.RiseWithDelay)
                {
                    bool useDelay = animation == CartesianAnimation.RiseWithDelay;
                    started |= TryRunRiseAnimtation(cartesianSeries, useDelay);
                }
                if (animation == CartesianAnimation.Stretch)
                {
                    started |= TryRunStretchAnimtation(cartesianSeries);
                }
                if (animation == CartesianAnimation.StackedBars)
                {
                    started |= TryRunStackedBarsAnimtation(cartesianSeries);
                }
            }


            return(started);
        }
Beispiel #8
0
        private void GenerateSeries(string seriesType)
        {
            CategoricalAxis horizontalAxis = new CategoricalAxis();
            LinearAxis      verticalAxis   = new LinearAxis();

            verticalAxis.AxisType = Telerik.Charting.AxisType.Second;

            for (int i = 0; i < 2; i++)
            {
                CartesianSeries series = null;

                if (seriesType == "Area")
                {
                    series = new AreaSeries();
                }
                else if (seriesType == "Line")
                {
                    series = new LineSeries();
                }
                else if (seriesType == "Stepline")
                {
                    series = new SteplineSeries();
                }

                series.PointSize      = new SizeF(5, 5);
                series.HorizontalAxis = horizontalAxis;
                series.VerticalAxis   = verticalAxis;
                series.BorderWidth    = 2;
                series.CategoryMember = "Month";
                series.ValueMember    = "Revenue";
                series.DataSource     = i == 0 ? collection1 : collection2;
                //series.ShowLabels = showLabels;
                //series.CombineMode = selectedCombineMode;

                this.radChartView1.ThemeName = "VisualStudio2012Dark";
                this.radChartView1.Series.Add(series);
            }
        }
        private static bool TryRunStretchAnimtation(CartesianSeries series)
        {
            RadRect plotAreClip = series.Chart.PlotAreaClip;

            bool           isHorizontal = IsSeriesHorizontal(series);
            ScaleTransform transform    = new ScaleTransform();

            transform.ScaleX  = isHorizontal ? 1 : 0;
            transform.ScaleY  = isHorizontal ? 0 : 1;
            transform.CenterX = isHorizontal ? 0 : CalculateHorizontalSeriesMiddle(series);
            transform.CenterY = isHorizontal ? CalculateVerticalSeriesMiddle(series) : 0;

            if (!IsValidNumber(transform.CenterX) || !IsValidNumber(transform.CenterY))
            {
                return(false);
            }

            series.RenderTransform = transform;

            DoubleAnimation animation = new DoubleAnimation();

            animation.From           = 0;
            animation.To             = 1;
            animation.Duration       = AnimationDuration;
            animation.EasingFunction = new CircleEase()
            {
                EasingMode = EasingMode.EaseOut,
            };
            DependencyProperty prop = isHorizontal ? ChartAnimationUtilities.SeriesScaleTransformYProperty : ChartAnimationUtilities.SeriesScaleTransformXProperty;

            Storyboard.SetTargetProperty(animation, new PropertyPath(prop));
            Storyboard.SetTarget(animation, series);

            Storyboard storyboard = new Storyboard();

            storyboard.Children.Add(animation);
            return(Run(storyboard, series));
        }
Beispiel #10
0
        private void FillBarSeries(CartesianSeries series)
        {
            SortedDictionary <double, DataPointElement> dictionary = new SortedDictionary <double, DataPointElement>();

            for (int i = 0; i < series.Children.Count; i++)
            {
                DataPointElement childElement = (DataPointElement)series.Children[i];
                double           volume       = (double)childElement.DataPoint.Label;
                dictionary.Add(volume, childElement);
            }

            int j = 0;

            foreach (DataPointElement childElement in dictionary.Values)
            {
                childElement.BackColor   = KnownPalette.Warm.GetEntry(series.Family, j).Fill;
                childElement.BorderColor = KnownPalette.Warm.GetEntry(series.Family, j).Stroke;
                if (++j > 7)
                {
                    j = 7;
                }
            }
        }
        private static bool TryRunRiseAnimtation(CartesianSeries series, bool useDelay)
        {
            RadRect plotAreClip = series.Chart.PlotAreaClip;

            bool isHorizontalBar = !IsSeriesHorizontal(series);
            bool isInverse = IsNumericalAxisInverse(series);

            double centerX = 0;
            double centerY = 0;
            if (isHorizontalBar)
            {
                centerX = isInverse ? plotAreClip.Right : plotAreClip.X;
            }
            else
            {
                centerY = isInverse ? plotAreClip.Y : plotAreClip.Bottom;
            }

            var scaleTransform = new ScaleTransform();
            scaleTransform.ScaleX = isHorizontalBar ? 0 : 1;
            scaleTransform.ScaleY = isHorizontalBar ? 1 : 0;
            scaleTransform.CenterX = centerX;
            scaleTransform.CenterY = centerY;

            series.RenderTransform = scaleTransform;

            TimeSpan? beginTime = useDelay ? CalculateBeginTime(series) : null;

            DoubleAnimation animation = new DoubleAnimation();
            animation.From = 0;
            animation.To = 1;
            animation.Duration = AnimationDuration;
            if (beginTime != null)
            {
                animation.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut, };
            }
            else
            {
                animation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseOut, };
            }

            Storyboard.SetTarget(animation, series);
            if (isHorizontalBar)
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.SeriesScaleTransformXProperty));
            }
            else
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.SeriesScaleTransformYProperty));
            }

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(animation);
            if (beginTime != null)
            {
                storyboard.BeginTime = beginTime;
            }
            return Run(storyboard, series);
        }
 private static double CalculateVerticalSeriesMiddle(CartesianSeries series)
 {
     return(CalculateSeriesMiddle(series, dp => dp.LayoutSlot.Center.Y));
 }
        private static bool TryRunStackedBarsAnimtation(CartesianSeries series)
        {
            Canvas renderSurface = Telerik.Windows.Controls.ChildrenOfTypeExtensions.FindChildByType<Canvas>(series);
            List<FrameworkElement> bars = new List<FrameworkElement>();
            foreach (FrameworkElement uiElement in renderSurface.Children)
            {
                Border bar = uiElement as Border;
                ContentPresenter cp = uiElement as ContentPresenter;
                if ((bar != null && (bar.DataContext is CategoricalDataPoint)) ||
                    (cp != null && cp.Content is CategoricalDataPoint))
                {
                    bars.Add(uiElement);
                }
            }

            Storyboard storyboard = new Storyboard();
            RadCartesianChart chart = (RadCartesianChart)series.Chart;
            int initialDelay = (int)(BarAnimationDuration.TimeSpan.Milliseconds * chart.Series.IndexOf(series));
            TimeSpan? beginTime = TimeSpan.FromMilliseconds(initialDelay);
            for (int i = 0; i < bars.Count; i++)
            {
                var animation = BuildStackedBarAnimation(bars[i], beginTime, BarAnimationDuration, series);
                storyboard.Children.Add(animation);
                beginTime = new TimeSpan(0, 0, 0, 0, initialDelay + (BarDelayInMilliseconds * (i + 1)));
            }

            return Run(storyboard, series);
        }
        private static DoubleAnimation BuildStackedBarAnimation(FrameworkElement bar, TimeSpan? beginTime, Duration duration, CartesianSeries series)
        {
            bool isHorizontalBar = !IsSeriesHorizontal(series);
            bool isInverse = IsNumericalAxisInverse(series);
            
            double centerX = 0;
            double centerY = 0;
            DataPoint dp = bar.DataContext as DataPoint;
            if (dp == null)
            {
                dp = (DataPoint)((bar as ContentPresenter).Content);
            }

            if (isHorizontalBar)
            {
                centerX = isInverse ? dp.LayoutSlot.Width : 0;
            }
            else
            {
                centerY = isInverse ? 0 : dp.LayoutSlot.Height;
            }

            var scaleTransform = new ScaleTransform();
            scaleTransform.ScaleX = isHorizontalBar ? 0 : 1;
            scaleTransform.ScaleY = isHorizontalBar ? 1 : 0;
            scaleTransform.CenterX = centerX;
            scaleTransform.CenterY = centerY;

            bar.RenderTransform = scaleTransform;

            DoubleAnimation animation = new DoubleAnimation();
            animation.From = 0;
            animation.To = 1;
            animation.Duration = duration;
            if (beginTime != null)
            {
                animation.BeginTime = beginTime;
            }

            Storyboard.SetTarget(animation, bar);
            if (isHorizontalBar)
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.BarScaleTransformXProperty));
            }
            else
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.BarScaleTransformYProperty));
            }

            return animation;
        }
        private static DoubleAnimation BuildStackedBarAnimation(FrameworkElement bar, TimeSpan?beginTime, Duration duration, CartesianSeries series)
        {
            bool isHorizontalBar = !IsSeriesHorizontal(series);
            bool isInverse       = IsNumericalAxisInverse(series);

            double    centerX = 0;
            double    centerY = 0;
            DataPoint dp      = bar.DataContext as DataPoint;

            if (dp == null)
            {
                dp = (DataPoint)((bar as ContentPresenter).Content);
            }

            if (isHorizontalBar)
            {
                centerX = isInverse ? dp.LayoutSlot.Width : 0;
            }
            else
            {
                centerY = isInverse ? 0 : dp.LayoutSlot.Height;
            }

            var scaleTransform = new ScaleTransform();

            scaleTransform.ScaleX  = isHorizontalBar ? 0 : 1;
            scaleTransform.ScaleY  = isHorizontalBar ? 1 : 0;
            scaleTransform.CenterX = centerX;
            scaleTransform.CenterY = centerY;

            bar.RenderTransform = scaleTransform;

            DoubleAnimation animation = new DoubleAnimation();

            animation.From     = 0;
            animation.To       = 1;
            animation.Duration = duration;
            if (beginTime != null)
            {
                animation.BeginTime = beginTime;
            }

            Storyboard.SetTarget(animation, bar);
            if (isHorizontalBar)
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.BarScaleTransformXProperty));
            }
            else
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.BarScaleTransformYProperty));
            }

            return(animation);
        }
        private static TimeSpan? CalculateBeginTime(CartesianSeries series)
        {
            RadCartesianChart chart = (RadCartesianChart)series.Chart;

            if (chart.Series.Count == 1)
            {
                return null;
            }

            int delay = DelayInMilliseconds * chart.Series.IndexOf(series) / chart.Series.Count;
            return new TimeSpan(0, 0, 0, 0, delay);
        }
        private static bool TryRunDropAnimtation(CartesianSeries series, bool useDelay)
        {
            IList <DataPoint> dataPoints = GetDataPoints(series);

            bool isInverse = IsNumericalAxisInverse(series);

            double offsetY = isInverse ? double.PositiveInfinity : double.NegativeInfinity;

            foreach (DataPoint dp in dataPoints)
            {
                if (isInverse && dp.IsInPlotRange && dp.LayoutSlot.Center.Y < offsetY)
                {
                    offsetY = dp.LayoutSlot.Center.Y;
                }
                else if (!isInverse && dp.IsInPlotRange && offsetY < dp.LayoutSlot.Center.Y)
                {
                    offsetY = dp.LayoutSlot.Center.Y;
                }
            }

            if (!IsValidNumber(offsetY))
            {
                return(false);
            }

            RadRect plotAreClip = series.Chart.PlotAreaClip;

            offsetY = (isInverse ? 1 : -1) * (plotAreClip.Height / 2);
            TranslateTransform transform = new TranslateTransform();

            transform.Y            = offsetY;
            series.RenderTransform = transform;

            TimeSpan?beginTime = useDelay ? CalculateBeginTime(series) : null;

            series.Opacity = 0;

            DoubleAnimation transformAnimation = new DoubleAnimation();

            transformAnimation.From           = offsetY;
            transformAnimation.To             = 0;
            transformAnimation.Duration       = AnimationDuration;
            transformAnimation.EasingFunction = new CircleEase()
            {
                EasingMode = EasingMode.EaseOut,
            };
            Storyboard.SetTargetProperty(transformAnimation, new PropertyPath(ChartAnimationUtilities.SeriesTranslateTransformYProperty));
            Storyboard.SetTarget(transformAnimation, series);

            DoubleAnimation opacityAnimation = new DoubleAnimation();

            opacityAnimation.From           = 0;
            opacityAnimation.To             = 1;
            opacityAnimation.Duration       = AnimationDuration;
            opacityAnimation.EasingFunction = new CircleEase()
            {
                EasingMode = EasingMode.EaseOut,
            };
            Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(ChartSeries.OpacityProperty));
            Storyboard.SetTarget(opacityAnimation, series);

            Storyboard storyboard = new Storyboard();

            storyboard.Children.Add(transformAnimation);
            storyboard.Children.Add(opacityAnimation);

            if (beginTime != null)
            {
                storyboard.BeginTime = beginTime;
            }

            Action completed = () => series.Opacity = 1;
            bool   started   = Run(storyboard, series, completed);

            if (!started)
            {
                completed();
            }
            return(started);
        }
        private static bool TryRunRiseAnimtation(CartesianSeries series, bool useDelay)
        {
            RadRect plotAreClip = series.Chart.PlotAreaClip;

            bool isHorizontalBar = !IsSeriesHorizontal(series);
            bool isInverse       = IsNumericalAxisInverse(series);

            double centerX = 0;
            double centerY = 0;

            if (isHorizontalBar)
            {
                centerX = isInverse ? plotAreClip.Right : plotAreClip.X;
            }
            else
            {
                centerY = isInverse ? plotAreClip.Y : plotAreClip.Bottom;
            }

            var scaleTransform = new ScaleTransform();

            scaleTransform.ScaleX  = isHorizontalBar ? 0 : 1;
            scaleTransform.ScaleY  = isHorizontalBar ? 1 : 0;
            scaleTransform.CenterX = centerX;
            scaleTransform.CenterY = centerY;

            series.RenderTransform = scaleTransform;

            TimeSpan?beginTime = useDelay ? CalculateBeginTime(series) : null;

            DoubleAnimation animation = new DoubleAnimation();

            animation.From     = 0;
            animation.To       = 1;
            animation.Duration = AnimationDuration;
            if (beginTime != null)
            {
                animation.EasingFunction = new CubicEase()
                {
                    EasingMode = EasingMode.EaseOut,
                };
            }
            else
            {
                animation.EasingFunction = new CircleEase()
                {
                    EasingMode = EasingMode.EaseOut,
                };
            }

            Storyboard.SetTarget(animation, series);
            if (isHorizontalBar)
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.SeriesScaleTransformXProperty));
            }
            else
            {
                Storyboard.SetTargetProperty(animation, new PropertyPath(ChartAnimationUtilities.SeriesScaleTransformYProperty));
            }

            Storyboard storyboard = new Storyboard();

            storyboard.Children.Add(animation);
            if (beginTime != null)
            {
                storyboard.BeginTime = beginTime;
            }
            return(Run(storyboard, series));
        }
        private static double CalculateSeriesMiddle(CartesianSeries series, Func<DataPoint, double> position)
        {
            double min = double.PositiveInfinity;
            double max = double.NegativeInfinity;

            IList<DataPoint> dataPoints = GetDataPoints(series);
            foreach (DataPoint dp in dataPoints)
            {
                if (dp.IsInPlotRange)
                {
                    double pos = position(dp);
                    if (pos < min)
                    {
                        min = pos;
                    }
                    if (max < pos)
                    {
                        max = pos;
                    }
                }
            }

            return (min + max) / 2;
        }
        private static bool TryRunStretchAnimtation(CartesianSeries series)
        {
            RadRect plotAreClip = series.Chart.PlotAreaClip;

            bool isHorizontal = IsSeriesHorizontal(series);
            ScaleTransform transform = new ScaleTransform();
            transform.ScaleX = isHorizontal ? 1 : 0;
            transform.ScaleY = isHorizontal ? 0 : 1;
            transform.CenterX = isHorizontal ? 0 : CalculateHorizontalSeriesMiddle(series);
            transform.CenterY = isHorizontal ? CalculateVerticalSeriesMiddle(series) : 0;

            if (!IsValidNumber(transform.CenterX) || !IsValidNumber(transform.CenterY))
            {
                return false;
            }

            series.RenderTransform = transform;

            DoubleAnimation animation = new DoubleAnimation();
            animation.From = 0;
            animation.To = 1;
            animation.Duration = AnimationDuration;
            animation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseOut, };
            DependencyProperty prop = isHorizontal ? ChartAnimationUtilities.SeriesScaleTransformYProperty : ChartAnimationUtilities.SeriesScaleTransformXProperty;
            Storyboard.SetTargetProperty(animation, new PropertyPath(prop));
            Storyboard.SetTarget(animation, series);

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(animation);
            return Run(storyboard, series);
        }
        private static bool TryRunDropAnimtation(CartesianSeries series, bool useDelay)
        {
            IList<DataPoint> dataPoints = GetDataPoints(series);

            bool isInverse = IsNumericalAxisInverse(series);

            double offsetY = isInverse ? double.PositiveInfinity : double.NegativeInfinity;
            foreach (DataPoint dp in dataPoints)
            {
                if (isInverse && dp.IsInPlotRange && dp.LayoutSlot.Center.Y < offsetY)
                {
                    offsetY = dp.LayoutSlot.Center.Y;
                }
                else if (!isInverse && dp.IsInPlotRange && offsetY < dp.LayoutSlot.Center.Y)
                {
                    offsetY = dp.LayoutSlot.Center.Y;
                }
            }

            if (!IsValidNumber(offsetY))
            {
                return false;
            }

            RadRect plotAreClip = series.Chart.PlotAreaClip;
            offsetY = (isInverse ? 1 : -1) * (plotAreClip.Height / 2);
            TranslateTransform transform = new TranslateTransform();
            transform.Y = offsetY;
            series.RenderTransform = transform;

            TimeSpan? beginTime = useDelay ? CalculateBeginTime(series) : null;

            series.Opacity = 0;

            DoubleAnimation transformAnimation = new DoubleAnimation();
            transformAnimation.From = offsetY;
            transformAnimation.To = 0;
            transformAnimation.Duration = AnimationDuration;
            transformAnimation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseOut, };
            Storyboard.SetTargetProperty(transformAnimation, new PropertyPath(ChartAnimationUtilities.SeriesTranslateTransformYProperty));
            Storyboard.SetTarget(transformAnimation, series);

            DoubleAnimation opacityAnimation = new DoubleAnimation();
            opacityAnimation.From = 0;
            opacityAnimation.To = 1;
            opacityAnimation.Duration = AnimationDuration;
            opacityAnimation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseOut, };
            Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(ChartSeries.OpacityProperty));
            Storyboard.SetTarget(opacityAnimation, series);

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(transformAnimation);
            storyboard.Children.Add(opacityAnimation);

            if (beginTime != null)
            {
                storyboard.BeginTime = beginTime;
            }

            Action completed = () => series.Opacity = 1;
            bool started = Run(storyboard, series, completed);
            if (!started)
            {
                completed();
            }
            return started;
        }
        private static bool IsSeriesHorizontal(CartesianSeries series)
        {
            NumericalAxis axis = series.VerticalAxis as NumericalAxis;
            if (axis != null)
            {
                return true;
            }

            axis = ((RadCartesianChart)series.Chart).VerticalAxis as NumericalAxis;
            if (axis != null)
            {
                return true;
            }

            return false;
        }
        private static bool IsNumericalAxisInverse(CartesianSeries series)
        {
            NumericalAxis axis = series.VerticalAxis as NumericalAxis;
            if (axis != null)
            {
                return axis.IsInverse;
            }

            axis = ((RadCartesianChart)series.Chart).VerticalAxis as NumericalAxis;
            if (axis != null)
            {
                return axis.IsInverse;
            }

            axis = series.HorizontalAxis as NumericalAxis;
            if (axis != null)
            {
                return axis.IsInverse;
            }

            axis = ((RadCartesianChart)series.Chart).HorizontalAxis as NumericalAxis;
            if (axis != null)
            {
                return axis.IsInverse;
            }

            return false;
        }
 private static double CalculateVerticalSeriesMiddle(CartesianSeries series)
 {
     return CalculateSeriesMiddle(series, dp => dp.LayoutSlot.Center.Y);
 }