Change Ortientation of XYAxisBar/XYStackedBar/XYGroupedBar

Charts for WPF Forum

Posted 4 months ago by Rudi Buss
Version: 22.1.5
Avatar

I've got a simple Stacked Bar Chart and I'd like to change the orientation by clicking on a button.

When the stacked bar has the StackKind "Percentage", it's working fine.

When the stacked bar has the StackKind "None" or "Normal", it gives me an error and my application crashes.

What am I doing wrong?

I'm changing the XAxes and YAxes and also the XPath, YPath and Orientation of each BarSeries.

Here's an example project: StackedBar with Orientation

Comments (3)

Posted 4 months ago by Rudi Buss
Avatar

Alternatively here's the code:

MainWindow.xaml

<Window x:Class="StackedBar.MainWindow"
        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"
        xmlns:charts="http://schemas.actiprosoftware.com/winfx/xaml/charts" 
        xmlns:local="clr-namespace:StackedBar"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="20"/>
        </Grid.RowDefinitions>
        <charts:XYChart GridLineMajorVisibility="Y" GridLineMinorVisibility="Y" Background="Transparent" x:Name="pltActi"/>
        <Button Content="change" Grid.Row="1" Click="Button_Click"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;

namespace StackedBar
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new DataViewModel(pltActi);

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if(this.DataContext is DataViewModel dvm)
            {
                dvm.Change();
            }
        }
    }
}

DataViewModel.cs

using ActiproSoftware.Windows.Controls.Charts;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Controls;

namespace StackedBar
{
    internal class DataViewModel : NotifyPropertyChangedBase
    {
        private List<BarSeries> series;

        public List<BarSeries> Series
        {
            get { return series; }
            set { series = value; OnPropertyChanged(); }
        }

        public XYChart PltActi { get; }


        public DataViewModel(XYChart pltActi)
        {
            this.PltActi = pltActi;

            Series = new List<BarSeries>();

            //Custom Style
            PltActi.YAxes.Clear();
            PltActi.YAxes.Add(new XYDoubleAxis() { });
            PltActi.XAxes.Clear();
            PltActi.XAxes.Add(new XYGroupedAxis() { LabelAngle = -45 });

            for (int i = 0; i < 5; i++)
            {
                string name;
                int index;

                name = "XAxisName";
                index = 1;

                Data data = new Data(name, "", (i + 1) * 100, index);

                BarSeries series = new BarSeries()
                {
                    ItemsSource = new ObservableCollection<Data>()
                    {
                        data
                    },
                    XPath = "Name",
                    YPath = "Value",
                    LabelVisibility = LabelVisibility.PointerAxis,
                    StackKind = XYSeriesStackKind.Normal, //Percentage works??
                    Orientation = Orientation.Horizontal
                };

                Series.Add(series);
            }

            pltActi.Series.AddRange(Series);
        }

        internal void Change()
        {
            PltActi.Series.BeginUpdate();
            PltActi.Series.Clear();
            foreach (var serie in Series)
            {
                serie.Orientation = serie.Orientation == Orientation.Vertical ? Orientation.Horizontal : Orientation.Vertical;
                serie.XPath = serie.Orientation == Orientation.Vertical ? "Value" : "Name";
                serie.YPath = serie.Orientation == Orientation.Vertical ? "Name" : "Value";
                serie.StackKind = XYSeriesStackKind.Normal;
            }

            if (Series.Exists(x => x.Orientation == Orientation.Horizontal))
            {
                PltActi.YAxes.Clear();
                PltActi.YAxes.Add(new XYGroupedAxis() { });
                PltActi.XAxes.Clear();
                PltActi.XAxes.Add(new XYDoubleAxis() {  });
            }
            else
            {
                PltActi.YAxes.Clear();
                PltActi.YAxes.Add(new XYDoubleAxis() { });
                PltActi.XAxes.Clear();
                PltActi.XAxes.Add(new XYGroupedAxis() { LabelAngle = -45 });
            }
            Series = new List<BarSeries>(Series);
            PltActi.Series.AddRange(Series);
            PltActi.Series.EndUpdate();
        }
    }
}

NotifyPropertyChangedBase.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace StackedBar
{
    public class NotifyPropertyChangedBase : INotifyPropertyChanged
    {
        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
Posted 4 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

I was trying some things and found that if you make this your Change method logic, it seems to work to rotate things:

var newSeries = new List<BarSeries>();
foreach (var serie in Series)
{
    newSeries.Add(new BarSeries() {
        Orientation = serie.Orientation == Orientation.Vertical ? Orientation.Horizontal : Orientation.Vertical,
        XPath = serie.Orientation == Orientation.Horizontal ? "Value" : "Name",
        YPath = serie.Orientation == Orientation.Horizontal ? "Name" : "Value",
        LabelVisibility = LabelVisibility.PointerAxis,
        StackKind = XYSeriesStackKind.Normal,
        ItemsSource = serie.ItemsSource,
    });
}
Series = newSeries;

PltActi.Series.BeginUpdate();
PltActi.Series.Clear();
PltActi.Series.AddRange(Series);
PltActi.Series.EndUpdate();


Actipro Software Support

Posted 3 months ago by Rudi Buss
Avatar

Thanks, your solution works! :)

The latest build of this product (v24.1.2) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.