Custom PointMark

9 posts, 0 answers
  1. Chris
    Chris avatar
    51 posts
    Member since:
    Sep 2010

    Posted 17 Nov 2010 Link to this post

    Hi,

    I have a situation where I need to style Line Chart point marks within the same series differently in order to flag up values within the series that are null.

    Looking at potential ways to implement this I can use the PointMarkItemStyle and implement some custom logic within the style definition based on the bound point data.

    What I would like to do is change the shape of the point marker from a circle to a triangle, and also change the colour of the shape. Within the theming XAML I can see two style definitions against a point mark for the Line chart type, PointMarkItemStyle which I can set but also PointMarkShapeStyle, which I can't appear to set and would need to set this in order to change the shape?

    Could you please offer some advice on the best way to approach this. I have a boolean property on each object bound to the chart in order to determine whether or not the value of the object is null.

    Regards,
    Chris
  2. Velin
    Admin
    Velin avatar
    391 posts

    Posted 22 Nov 2010 Link to this post

    Hello Chris,

    Unfortunately, the current implementation does not allow customization of the point mark shape using the MVVM approach. I have logged this as a bug report in our issue tracking system so you can expect a resolution in a future version.

    We are really sorry for the inconvenience caused.

    Regards,
    Ryan
    the Telerik team
    Browse the videos here>> to help you get started with RadControls for Silverlight
  3. sachin
    sachin avatar
    11 posts
    Member since:
    Nov 2008

    Posted 23 Nov 2010 Link to this post

    Ryan,

    This may be the same question as already asked by Chris but for further understanding, Can we customize selective data point to some different style in line series.

    My requirement is showing data as line series some of whose data points (which satisfies some condition) should be shown as Red Circle.

    Any pointers for implementing this would be helpful.

    Thanks,
    Sachin
  4. Chris
    Chris avatar
    51 posts
    Member since:
    Sep 2010

    Posted 23 Nov 2010 Link to this post

    Hi Ryan,

    I can show you what I ended up implementing as solution to this issue if it helps:

    1) Styles define in XAML for the null data point marks and their associated labels. The converters used simply convert the boolean value IsNull, a property on my bound data item, to the true/false brush value defined by the converter and this is ued to colour the point marks/labels background:

    <Converters:BoolToBrushConverter x:Key="IsNullToBackgroundBrushConverter" TrueValue="Red" FalseValue="#FFE59200" />
            <Style x:Key="NullLabel_Style" TargetType="telerikCharting:SeriesItemLabel">
                <Setter Property="Template" >
                    <Setter.Value>
                        <ControlTemplate TargetType="telerikCharting:SeriesItemLabel">
                            <Canvas x:Name="PART_MainContainer">
                                <Border
                                    x:Name="PART_TextContainer"
                                    Style="{TemplateBinding LabelStyle}"
                                    Background="{Binding DataItem.IsNull, Converter={StaticResource IsNullToBackgroundBrushConverter}}">
                                    <TextBlock Text="{TemplateBinding Content}" />
                                </Border>
                            </Canvas>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <Converters:BoolToBrushConverter x:Key="IsNullToFillBrushConverter" TrueValue="Red" FalseValue="White" />
            <Style x:Key="NullPointMark_Style" TargetType="telerikCharting:PointMark">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="telerikCharting:PointMark">
                            <Canvas>
                                <Path x:Name="PART_PointMarkPath"
                                      Canvas.Left="{TemplateBinding PointMarkCanvasLeft}"
                                      Canvas.Top="{TemplateBinding PointMarkCanvasTop}"
          Style="{TemplateBinding ShapeStyle}" 
          Width="{TemplateBinding Size}" 
                                      Height="{TemplateBinding Size}"
                                      Fill="{Binding DataItem.IsNull, Converter={StaticResource IsNullToFillBrushConverter}}"
          Stretch="Fill">
                                    <Path.Data>
                                        <PathGeometry x:Name="PART_PointMarkPathGeometry" />
                                    </Path.Data>
                                </Path>
                            </Canvas>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>

    2) Code behind simply sets the styles against the series mapping:

    seriesMapping.SeriesDefinition.SeriesItemLabelStyle = Application.Current.Resources["NullLabel_Style"as Style;
    seriesMapping.SeriesDefinition.PointMarkItemStyle = Application.Current.Resources["NullPointMark_Style"as Style;

    3) Not required, but additionally I update the label and tooltip content of each point accoding to its value:

    chart.DataBound += (o, e) =>
                    {
                        var dataSeries = chart.DefaultView.ChartArea.DataSeries.FirstOrDefault();

                        if (dataSeries != null)
                        {
                            // Ensure null value points have the correct labels/tooltips
                            foreach (var point in dataSeries.ToList())
                            {
                                if (PointIsNull(point.DataItem))
                                {
                                    // Null value so set labels + tooltips
                                    point.Tooltip = Common.Resources.GetValueFromResource("Missing");
                                    point.Label = Common.Resources.GetValueFromResource("Missing");
                                }
                            }
                        }
                    };





    See the attached screen shot for the result of the above changes....


  5. sachin
    sachin avatar
    11 posts
    Member since:
    Nov 2008

    Posted 24 Nov 2010 Link to this post

    Hi Chris,

    I went through your post and it does give me some leads in solving my issue. My scenario is an empty pointmarkstyle if its a normal datapoint else a custom style if it is a special datapoint. I am using these styles using XamlReader inside a converter class. This converter class is giving me runtime error as "Invalid attribute value chart:PointMark for property TargetType". I have pasted the class file code for the reference. Can you please check what could be the issue.

    Thanks,
    Sachin

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Data;
    using System.Windows.Markup;
    using chart = Telerik.Windows.Controls.Charting;
     
     
    namespace Common
    {
        public class DataPointStyleConverter : IValueConverter
        {
     
            private static Style DefaultDataPointStyle = XamlReader.Load(@"
                                                <Style TargetType=""chart:PointMark""
                                                xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                                                xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
                                                >
                                                <Setter Property=""Size"" Value=""10"" />
                                                <Setter Property=""Template"">
                                                    <Setter.Value>
                                                        <ControlTemplate TargetType=""chart:PointMark"">
                                                            <Canvas>
                                                                <TextBlock ></TextBlock>
                                                            </Canvas>
                                                        </ControlTemplate>
                                                    </Setter.Value>
                                                </Setter>
                                            </Style>") as Style;
     
            private static Style SignalDataPointStyle = XamlReader.Load(@"
                                                <Style TargetType=""chart:PointMark""
                                                    xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                                                    xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
                                                    >
                                                    <Setter Property=""Size"" Value=""20"" />
                                                    <Setter Property=""Template"">
                                                    <Setter.Value>
                                                        <ControlTemplate TargetType=""chart:PointMark"">
                                                            <Canvas>
                                                                <Path x:Name=""PART_PointMarkPath""
                                                                      Canvas.Left=""{TemplateBinding PointMarkCanvasLeft}""
                                                                      Canvas.Top=""{TemplateBinding PointMarkCanvasTop}""
                                                                      Style=""{TemplateBinding ShapeStyle}""
                                                                      Width=""{TemplateBinding Size}""
                                                                      Height=""{TemplateBinding Size}""
                                                                      Fill=""{}""
                                                                      Stretch=""Fill"">
                                                                    <Path.Data>
                                                                        <PathGeometry x:Name=""PART_PointMarkPathGeometry"" />
                                                                    </Path.Data>
                                                                </Path>
                                                            </Canvas>
                                                        </ControlTemplate>
                                                    </Setter.Value>
                                                </Setter>") as Style;
     
     
            #region IValueConverter Members
     
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                bool IsSignal = (bool)value;
                Style Pointstyle = IsSignal ? SignalDataPointStyle : DefaultDataPointStyle;           
                return Pointstyle;
     
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                Style pointStyle = (Style)value;
                if (pointStyle.Equals(DefaultDataPointStyle))
                    return false;
                else if (pointStyle.Equals(SignalDataPointStyle))
                    return true;
                else
                    return false;
            }
     
            #endregion
        }
    }

  6. Chris
    Chris avatar
    51 posts
    Member since:
    Sep 2010

    Posted 24 Nov 2010 Link to this post

    Hi,

    I think you are misunderstanding how the XamlReader parses and loads a XAML string. You have defined a using statement for chart = Telerik.... but this will not be picked up by the XamlReader. You need to identify each assembly/namespace required within your XAML explicitly i.e. within your example you need the following xlmns addition:

    xmlns:chart="clr-namespace:Telerik.Windows.Controls.Charting;assembly=Telerik.Windows.Controls.Charting"

    Hope this helps...

    Regards,
    Chris
  7. sachin
    sachin avatar
    11 posts
    Member since:
    Nov 2008

    Posted 25 Nov 2010 Link to this post

    Thanks Chris. It did really helped and worked. But I some how cannot figure out if I can assign the converter to assign 'PointMarkItemStyle' at runtime. My dataobject is having a bool property IsSignal on which I want converter to work. I am using the below code snippet for the XAML code but this is giving me bad XAML runtime error 'AG_E_PARSER_BAD_PROPERTY_VALUE'. 

    Do you have any pointers how to resolve this?

    <control:RadChart.SeriesMappings>
                    <chart:SeriesMapping CollectionIndex="0">
                        <chart:SeriesMapping.SeriesDefinition>
                            <chart:LineSeriesDefinition PointMarkItemStyle="{Binding IsSignal,Converter={StaticResource pointStyleConverter}}" ShowItemLabels="False" ></chart:LineSeriesDefinition>
                        </chart:SeriesMapping.SeriesDefinition>
                        <chart:SeriesMapping.ItemMappings>
                            <chart:ItemMapping FieldName="value" DataPointMember="YValue"></chart:ItemMapping>
                            <chart:ItemMapping FieldName="key" DataPointMember="XValue"></chart:ItemMapping>
                        </chart:SeriesMapping.ItemMappings>
                    </chart:SeriesMapping>
    </control:RadChart.SeriesMappings>


    Thanks,
    Sachin
  8. Chris
    Chris avatar
    51 posts
    Member since:
    Sep 2010

    Posted 25 Nov 2010 Link to this post

    Hi Sachin,

    This error suggests there is an issue somewhere in your XAML. The full error message should detail the exact line/column number, which should show you exactly what the parser has a problem with. Remeber that XAML is case sensitive so ensure that your converter resource is named pointStyleConverter and not PointStyleConverter and this will cause the error described.

    Regards,
    Chris
  9. Velin
    Admin
    Velin avatar
    391 posts

    Posted 26 Nov 2010 Link to this post

    Hi Sachin,

    Just in case the issue you had is still present, could you send us a sample application demonstrating it ? Thanks.

    Best wishes,
    Ryan
    the Telerik team
    Browse the videos here>> to help you get started with RadControls for Silverlight
Back to Top