Wednesday, May 23, 2012

Changing the color of Area Chart Fill without C#

After looking over several websites, googling like crazy, and finding all sorts of complicated code I took notes of and still just didn't understand, I finally figured out how to "easily" change the color of the area chart fill.

Below is the basic, every day area chart - default blue color:


Below is the code I wrote to create the chart (the points are set in the code behind, I didn't want to mess up this code with the points set inline):

<UserControl
    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:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
    xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
    xmlns:chartingPrimitivesToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting.Primitives;assembly=System.Windows.Controls.DataVisualization.Toolkit"
    xmlns:chartingPrimitives="clr-namespace:System.Windows.Controls.DataVisualization.Charting.Primitives;assembly=System.Windows.Controls.DataVisualization.Toolkit"
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
    mc:Ignorable="d"
    x:Class="XAMLTestingScreens.AreaChartExample"
    Width="640" Height="480">

    <Grid x:Name="LayoutRoot" Background="White">
        <Canvas>
            <toolkit:Chart Title="Area Series Fill" x:Name="AreaSeriesFill" BorderBrush="Transparent" Width="640" Height="480">
                <toolkit:Chart.Axes>
                    <toolkit:LinearAxis x:Name="AxisOne" Foreground="Black"
                                        Title="Width" ShowGridLines="True"
                                        Orientation="X" Minimum="0" Maximum="40" Interval="5"/>
                    <toolkit:LinearAxis x:Name="AxisTwo" Foreground="Black" Title="Height"
                                        ShowGridLines="True" Orientation="Y" Minimum="0" Maximum="40" Interval="5"/>
                </toolkit:Chart.Axes>
               
                <toolkit:AreaSeries Title="Change Color" x:Name="changecolor" ItemsSource="{Binding}"
                                    IndependentValueBinding="{Binding Width}" DependentValueBinding="{Binding Height}"/>
            </toolkit:Chart>
        </Canvas>
    </Grid>
</UserControl>

I want to have the area below the plotted line (the fill) in red, and of course the corresponding Legend Item in the same color.

Here is the updated chart with the new color.


Below is the section of updated code:

<toolkit:AreaSeries Title="Change Color" x:Name="changecolor"
                                    ItemsSource="{Binding}"
                                    IndependentValueBinding="{Binding Width}"
                                    DependentValueBinding="{Binding Height}">
                    <toolkit:AreaSeries.DataPointStyle>
                        <Style TargetType="toolkit:DataPoint">
                            <Setter Property="Background" Value="Red" />
                        </Style>
                    </toolkit:AreaSeries.DataPointStyle>
                </toolkit:AreaSeries>

The highlighted area is the updated code.
All I did was add the DataPointStyle and set the background color. However, the area is not solid, and looks pink (not what I wanted) so I have to update the Opacity as well.



Below is the code for the brighter chart:

<toolkit:AreaSeries Title="Change Color" x:Name="changecolor"
                                    ItemsSource="{Binding}"
                                    IndependentValueBinding="{Binding Width}"
                                    DependentValueBinding="{Binding Height}" IsHitTestVisible="False">
                    <toolkit:AreaSeries.DataPointStyle>
                        <Style TargetType="toolkit:DataPoint">
                            <Setter Property="Background" Value="Red" />
                            <Setter Property="Opacity" Value="1.0" />
                        </Style>
                    </toolkit:AreaSeries.DataPointStyle>
                    <toolkit:AreaSeries.Style>
                        <Style TargetType="toolkit:AreaSeries">
                            <Setter Property="PathStyle">
                                <Setter.Value>
                                    <Style TargetType="Path">
                                        <Setter Property="Opacity" Value="1.0" />
                                    </Style>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </toolkit:AreaSeries.Style>
                </toolkit:AreaSeries>

The opacity is set using the AreaSeries.Style - pointing to a PathStyle. 

I was SO HAPPY to find a much easier way to change the colors, I really was not looking forward to coding upteen too many lines.

Hope this is helpful to someone else too.


PS: Below is the VERY basic code behind that I used to create the points for this graph:

using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Ink;
using System.Globalization;
using System.Threading;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls.DataVisualization.Charting;
using System.Windows.Controls.DataVisualization;
using System.ComponentModel;
using System.Windows.Shapes;

namespace XAMLTestingScreens
{
    public partial class AreaChartExample : UserControl
    {
        public AreaChartExample()
        {
            // Required to initialize variables
            InitializeComponent();
           
            this.LayoutRoot.DataContext = this;
           
            this.Loaded += new RoutedEventHandler(UC_Loaded);
           
           
        }
       
        void UC_Loaded (object sender, RoutedEventArgs e)
        {
       
            List<ColorChangePoints> colorchange = new List<ColorChangePoints>();
            colorchange.Add(new ColorChangePoints() {Width=0,Height=0});
            colorchange.Add(new ColorChangePoints() {Width=5,Height=10});
            colorchange.Add(new ColorChangePoints() {Width=10,Height=20});
            colorchange.Add(new ColorChangePoints() {Width=15,Height=15});
            colorchange.Add(new ColorChangePoints() {Width=20,Height=30});
            colorchange.Add(new ColorChangePoints() {Width=25,Height=15});
            colorchange.Add(new ColorChangePoints() {Width=30,Height=35});
            colorchange.Add(new ColorChangePoints() {Width=35,Height=10});
            colorchange.Add(new ColorChangePoints() {Width=40,Height=20});
           
            AreaSeries changecolor = AreaSeriesFill.Series[0] as AreaSeries;
           
            changecolor.IndependentValuePath = "Width";
            changecolor.DependentValuePath = "Height";
            changecolor.ItemsSource = colorchange;
        }
       
        public class ColorChangePoints
        {
            public double Width {get; set;}
            public double Height {get; set;}
        }
    }
}
Nothing special, but it's easier for me than hard coding it into the XAML

I've uploaded a copy of the project for you to play around with.

No comments:

Post a Comment