Change properties of a point in chart

16 posts, 0 answers
  1. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 20 Jul 2010 Link to this post

    Hi,

    In my project, I have a RadGridView and a RadChart. my data have a boolean property, in my gridView it's represent by a checkbox.

    When the checkbox of a ligne are check, I want change the size, the color or the shape of the corresponding point in chart ( I use ScatterSerie)

    Edit : I would like to change the color of the checked rows in my gridView too.

    I wish to know if it's possible please.
  2. Dwight
    Admin
    Dwight avatar
    475 posts

    Posted 23 Jul 2010 Link to this post

    Hello guillaume,

    There is no out-of-the-box functionality that allows per-item customization of the scatter chart items at run-time. In order to achieve this, you will need to use the MVVM approach to handling this scenario.

    Best wishes,
    Joshua
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 05 Aug 2010 Link to this post

    Sorry for the response Time.

    For my points I used an ScatterSeries, it's easier than BubbleSeries.

    But I have a problem with MVVM approach.

    In my bubble chart, I want to draw ellipses, one for each group point.

    I create the series for ellipse from my class DatatemViewModel :
    SeriesDescription ySerie = _seriesList.First(series => !series.Equals("LABEL") && !series.Equals("GRP"));
     
    ObservableCollection<List<DataItemViewModel>> listSource = this.radChart.ItemsSource as ObservableCollection<List<DataItemViewModel>>;
     
    SeriesMapping seriesMapping = new SeriesMapping();
    BubbleSeriesDefinition bubbleDef = new BubbleSeriesDefinition();
    bubbleDef.ItemStyle = this.EllipseStyle;
    bubbleDef.ShowItemLabels = true;
    bubbleDef.ShowItemToolTips = false;
    ItemMapping itemMapX;
    ItemMapping itemMapY;
                         
    itemMapY = new ItemMapping(String.Concat("DrawnItem.",ySerie.Criterium),DataPointMember.YValue);
     
    seriesMapping.ItemMappings.Add(new ItemMapping(String.Concat("DataItem.Lbl", ySerie.Criterium), DataPointMember.Label));
     
    seriesMapping.ItemMappings.Add(itemMapY);
     
    itemMapX = new ItemMapping( String.Concat("DrawnItem.",this._xSeries.Criterium),DataPointMember.XValue);
     
    seriesMapping.ItemMappings.Add(itemMapX);
    seriesMapping.SeriesDefinition = bubbleDef;
     
    List<DataItemViewModel> items = new List<DataItemViewModel>();
     
    foreach (List<DataItemViewModel> list in listSource)
    {
       ObservableCollection<DataItem> listDataItem =
       new  ObservableCollection<DataItem>();
       foreach(DataItemViewModel model in list)
           listDataItem.Add(model.DataItem);
     
       List<double> avgMinMaxX = this.CalculAvgX(listDataItem);
       List<double> avgMinMaxY = this.CalculAvgY(listDataItem);
     
       double height = Math.Max(Math.Abs(avgMinMaxY[0] -
       avgMinMaxY[1]), Math.Abs(avgMinMaxY[0] - avgMinMaxY[2]));
     
       double width = Math.Max(Math.Abs(avgMinMaxX[0] -
       avgMinMaxX[1]), Math.Abs(avgMinMaxX[0] - avgMinMaxX[2]));
                            
       DataItem dataItem = new DataItem() { Height = height, Width = width };
       dataItem.SetElement(_xSeries.Criterium, avgMinMaxX[0]);
       dataItem.SetElement(ySerie.Criterium, avgMinMaxY[0]);
       dataItem.SetLblElement(ySerie.Criterium,
       String.Concat("Groupe ", list[0].DataItem.Grp));
     
       items.Add(new DataItemViewModel(dataItem, dataItem));
    }
     
    listSource.Add(items);
    seriesMapping.CollectionIndex = listSource.IndexOf(items);
    seriesMapping.LegendLabel = "Ellipse des groupes";
    this.radChart.SeriesMappings.Add(seriesMapping);



    and I have my style in XAML :
    <Style x:Name="EllipseStyle" TargetType="telerikCharting:Bubble">
     <Setter Property="Template">
       <Setter.Value>
         <ControlTemplate TargetType="telerikCharting:Bubble">
            <Canvas>
               <Ellipse x:Name="PART_BubbleElement"
                 Style="{TemplateBinding  ItemStyle}" 
                 Stroke="Black"
                 StrokeThickness="3"
                 Width="30"
                 Height="20"     
                 />
             </Canvas>
           </ControlTemplate>
         </Setter.Value>
       </Setter>
    </Style>

    When execute my project I see the ellipses in top of chart, not in the correct coord (ellipsesinchart.jpg).

  4. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 05 Aug 2010 Link to this post

    I found how to have my "Ellipses" in the correct coords :

    <Style x:Name="EllipseStyle" TargetType="telerikCharting:Bubble">
       <Setter Property="Template">
         <Setter.Value>
           <ControlTemplate TargetType="telerikCharting:Bubble">
             <Canvas>
               <Path  x:Name="PART_BubbleElement"
                      Data="{TemplateBinding ItemGeometry}"
                      Style="{TemplateBinding ItemStyle}" 
                      Stroke="Blue"
                      StrokeThickness="1"
                      Fill="Transparent"
               />
            </Canvas>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

    With that I have circles, but how have an Ellipse
    I can't replace Path Item by Ellipse because there aren't have a Data property.
  5. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 10 Aug 2010 Link to this post

    Hello guillaume cros,

    You can achieve the desired effect by creating custom EllipseBubble series type like this (you need to do this in order to create the EllipseGeometry properly):

    XAML
    <Grid x:Name="LayoutRoot">
        <Grid.Resources>
            <Style x:Key="CustomBubbleStyle" TargetType="telerik:Bubble">
                <Setter Property="Template" >
                    <Setter.Value>
                        <ControlTemplate TargetType="telerik:Bubble">
                            <Canvas RenderTransformOrigin="{TemplateBinding RelativeCenterPoint}" x:Name="PART_MainContainer">
     
                                <Path  x:Name="PART_BubbleElement"
                                    Style="{TemplateBinding ItemStyle}"
                                    Stroke="Blue"
                                    StrokeThickness="1"
                                    Fill="Transparent" />
     
                            </Canvas>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
     
        <telerik:RadChart x:Name="RadChart1" />
    </Grid>

    C#
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
     
            RadChart1.DefaultSeriesDefinition = new EllipseBubbleSeriesDefinition() { ItemStyle = this.LayoutRoot.Resources["CustomBubbleStyle"] as Style };
            RadChart1.ItemsSource = new int[] { 1, 5, 7, 2, 4 };
        }
    }
     
    public class EllipseBubbleSeriesDefinition : BubbleSeriesDefinition
    {
        public override IChartItem CreateChartItem()
        {
            return new EllipseBubble();
        }
    }
     
    public class EllipseBubble : Bubble
    {
        private Path BubbleElement
        {
            get
            {
                return this.GetTemplateChild("PART_BubbleElement") as Path;
            }
        }
     
        protected override Size ArrangeOverride(Size finalSize)
        {
            Size result = base.ArrangeOverride(finalSize);
     
            this.BubbleElement.Data = new EllipseGeometry()
            {
                RadiusX = 20,
                RadiusY = 10,
                Center = this.CenterPoint
            };
     
            return result;
        }
    }

    Hope this helps.


    Greetings,
    Freddie
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  6. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 11 Aug 2010 Link to this post

    Thank you Freddie for your awnser. It's perfect for ellipses placement.

    Now I would change ellipses Radius X and Radius Y.

    In my chart, I have 3 scatterPointsSeries. I would have an ellipse for each series. The ellipse must contains all of series points. See my example in exampleellipse.jpg.

    I have the value for RadiusX and Y in the data of radchart.ItemSource. It's possible to Binding this directly in EllipseBubble class?

    Like this :
    this.BubbleElement.Data = new EllipseGeometry()
    {
        RadiusX = this.Width,
        RadiusY = this.Height,
        Center = this.CenterPoint
    };

    But I don't see how to put the Width and Height in my BubblePoint.

    For create my bubblePoints I used SeriesMapping. But it's possible to used a dataseries with dataPoints.

    I continu to search that. If you have the solution in best time, I take it gladly :)


    Regards,
    Guillaume.
  7. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 11 Aug 2010 Link to this post

    I tried something.
    The ItemSource of radchart, I have DataItemViewModel class. I put in this class the width and height for each ellipse.

    I apply this code in my project :
    protected override Size ArrangeOverride(Size finalSize)
    {
      Size result = base.ArrangeOverride(finalSize);
     
      this.BubbleElement.Data = new EllipseGeometry()
      {
        RadiusX = (this.DataPoint.DataItem as DataItemViewModel).DataItem.Width,
        RadiusY = (this.DataPoint.DataItem as DataItemViewModel).DataItem.Height,
         Center = this.CenterPoint
      };
     
      return result;
    }
     and I have the result in screenshot.

     Visibly, ellipse Data not take the same scale as the graph :s
  8. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 16 Aug 2010 Link to this post

    Hi guillaume cros,

    Here is a modified code snippet that demonstrates the desired behavior (using RadiusX/RadiusY values from the original data item for the ellipse geometry):

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
     
            List<ChartData> data = new List<ChartData>();
            data.Add(new ChartData() { YValue = 1, RadiusX = 10, RadiusY = 20 });
            data.Add(new ChartData() { YValue = 5, RadiusX = 20, RadiusY = 10 });
            data.Add(new ChartData() { YValue = 7, RadiusX = 10, RadiusY = 15 });
            data.Add(new ChartData() { YValue = 2, RadiusX = 5, RadiusY = 30 });
            data.Add(new ChartData() { YValue = 4, RadiusX = 30, RadiusY = 10 });
     
            SeriesMapping sm = new SeriesMapping();
            sm.ItemMappings.Add(new ItemMapping("YValue", DataPointMember.YValue));
            sm.SeriesDefinition = new EllipseBubbleSeriesDefinition() { ItemStyle = this.LayoutRoot.Resources["CustomBubbleStyle"] as Style };
     
            RadChart1.SeriesMappings.Add(sm);
            RadChart1.ItemsSource = data;
        }
    }
     
    public class ChartData
    {
        public double YValue
        {
            get;
            set;
        }
     
        public double RadiusX
        {
            get;
            set;
        }
     
        public double RadiusY
        {
            get;
            set;
        }
    }
     
    public class EllipseBubbleSeriesDefinition : BubbleSeriesDefinition
    {
        public override IChartItem CreateChartItem()
        {
            return new EllipseBubble();
        }
    }
     
    public class EllipseBubble : Bubble
    {
        private Path BubbleElement
        {
            get
            {
                return this.GetTemplateChild("PART_BubbleElement") as Path;
            }
        }
     
        protected override Size ArrangeOverride(Size finalSize)
        {
            Size result = base.ArrangeOverride(finalSize);
     
            this.BubbleElement.Data = new EllipseGeometry()
            {
                RadiusX = (this.DataPoint.DataItem as ChartData).RadiusX,
                RadiusY = (this.DataPoint.DataItem as ChartData).RadiusY,
                Center = this.CenterPoint
            };
     
            return result;
        }
    }



    All the best,
    Freddie
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  9. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 17 Aug 2010 Link to this post

    Hi Freddi. Thank you for your awnser.

    I used your idea to put the correct RadiusX and RadiusY in my Ellipses. But in my previous post, i said that I have a problem with the chart scale.

    Your ChartData class are my DataItemViewModel class. I had calculate RadiusX and RadiusY, i checked my calculations and it's correct.
    The result are not exactly good :/ (see my attach file)
  10. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 19 Aug 2010 Link to this post

    Hi guillaume cros,

    Could you elaborate a bit more on the issue you are experiencing (with specific radius property values and how are you calculating them) as we are a bit unsure whether the problem is related to the chart control itself.


    Greetings,
    Freddie
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  11. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 24 Aug 2010 Link to this post

    Hi Freddie,

    In the attach file 'littleEllipses.jpg", we see in my chart the ellipses with RadiusX = 50 and RadiusY = 20.

    That not correspond to the chart scale.


    calculate values for my first ellipses "groupe 1" are :
       RadiusX : 8090.0
       RadiusY : 12571.74
    this values correpond to the chart scale.
  12. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 26 Aug 2010 Link to this post

    Hello guillaume cros,

    If we understand your question correctly, you are looking for a method that would convert "data" units to physical pixels -- you can use the Axis.ConvertDataUnitsToPhysical(...) method like this:

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
     
            RadChart1.DefaultView.ChartArea.AxisY.RangeChanged += new EventHandler(AxisY_RangeChanged);
            RadChart1.SizeChanged += new SizeChangedEventHandler(RadChart1_SizeChanged);
     
            ObservableCollection<ChartData> data = new ObservableCollection<ChartData>();
            data.Add(new ChartData() { YValue = 100000 });
            data.Add(new ChartData() { YValue = 50000 });
            data.Add(new ChartData() { YValue = 70000 });
            data.Add(new ChartData() { YValue = 12000 });
            data.Add(new ChartData() { YValue = 4000 });
     
            SeriesMapping sm = new SeriesMapping();
            sm.ItemMappings.Add(new ItemMapping("YValue", DataPointMember.YValue));
            sm.SeriesDefinition = new EllipseBubbleSeriesDefinition() { ItemStyle = this.LayoutRoot.Resources["CustomBubbleStyle"] as Style };
     
            RadChart1.SeriesMappings.Add(sm);
            RadChart1.ItemsSource = data;
        }
     
        private void RadChart1_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            this.ConvertRadiusDataUnitsToPhysical();
        }
     
        private void AxisY_RangeChanged(object sender, EventArgs e)
        {
            this.ConvertRadiusDataUnitsToPhysical();
        }
     
        private void ConvertRadiusDataUnitsToPhysical()
        {
            // Axis.ConvertDataUnitsToPhysical(...) would not work in the constructor as the physical dimensions of the axis visual are not available yet.
     
            foreach (ChartData dataItem in RadChart1.ItemsSource as ObservableCollection<ChartData>)
            {
                dataItem.RadiusX = RadChart1.DefaultView.ChartArea.AxisY.ConvertDataUnitsToPhysical(8000);
                dataItem.RadiusY = RadChart1.DefaultView.ChartArea.AxisY.ConvertDataUnitsToPhysical(2000);
            }
        }
    }
     
    public class ChartData : INotifyPropertyChanged
    {
        private double yValue;
        private double radiusx;
        private double radiusy;
     
        public double YValue
        {
            get
            {
                return this.yValue;
            }
            set
            {
                if (this.yValue != value)
                {
                    this.yValue = value;
                    this.OnPropertyChanged(new PropertyChangedEventArgs("YValue"));
                }
            }
        }
     
        public double RadiusX
        {
            get
            {
                return this.radiusx;
            }
            set
            {
                if (this.radiusx != value)
                {
                    this.radiusx = value;
                    this.OnPropertyChanged(new PropertyChangedEventArgs("RadiusX"));
                }
            }
        }
     
        public double RadiusY
        {
            get
            {
                return this.radiusy;
            }
            set
            {
                if (this.radiusy != value)
                {
                    this.radiusy = value;
                    this.OnPropertyChanged(new PropertyChangedEventArgs("RadiusY"));
                }
            }
        }
     
        public event PropertyChangedEventHandler PropertyChanged;
     
        protected void OnPropertyChanged(PropertyChangedEventArgs args)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, args);
        }
    }
     
    public class EllipseBubbleSeriesDefinition : BubbleSeriesDefinition
    {
        public override IChartItem CreateChartItem()
        {
            return new EllipseBubble();
        }
    }
     
    public class EllipseBubble : Bubble
    {
        private Path BubbleElement
        {
            get
            {
                return this.GetTemplateChild("PART_BubbleElement") as Path;
            }
        }
     
        protected override Size ArrangeOverride(Size finalSize)
        {
            Size result = base.ArrangeOverride(finalSize);
     
            this.BubbleElement.Data = new EllipseGeometry()
            {
                RadiusX = (this.DataPoint.DataItem as ChartData).RadiusX,
                RadiusY = (this.DataPoint.DataItem as ChartData).RadiusY,
                Center = this.CenterPoint
            };
     
            return result;
        }
    }



    Kind regards,
    Freddie
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  13. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 27 Aug 2010 Link to this post

    Hi freddie.

    I want test your solution, but I think i have an old version of Telerik. Radchart don't containt a method "ConvertDataUnitsToPhysical".

    I know i'm on .net framework 3.5 and my Telerik version are : v.2010.1.309.1030 Trial.

    It's a normal "problem" ?

    Best regards.

    Guillaume.
  14. Ves
    Admin
    Ves avatar
    2927 posts

    Posted 01 Sep 2010 Link to this post

    Hi guillaume,

    That's correct -- this method is not available in version 2010.1.309. Please, download the latest version of RadControls for Silverlight -- currently Q2 2010 SP1. This will allow you to take advantage of the latest features and bug fixes.

    Best regards,
    Ves
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  15. guillaume cros
    guillaume cros avatar
    15 posts
    Member since:
    Apr 2010

    Posted 04 Oct 2010 Link to this post

    Hi,

    I changed my Telerik version, now I can use ConvertDataUnitsToPhysical function.

    I applied Freddie's code in my project, the size of my ellipses change but not as I would like.

    For my test I fixed the Yvalue and XValue to 5000.

    When I applied this code :

    item.DataItem.Xvalue= this.radChart.DefaultView.ChartArea.AxisX.ConvertDataUnitsToPhysical(item.DataItem.Xvalue);
    item.DataItem.Yvalue= this.radChart.DefaultView.ChartArea.AxisY.ConvertDataUnitsToPhysical(item.DataItem.Yvalue);

    the values are for Xvalue 0.25 and for Yvalue 0.05. In my Chart I have small points for ellipses (smallellipses.jpg)

    It's a normal effect ?

    Best regards,

    Guillaume.
  16. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 07 Oct 2010 Link to this post

    Hi guillaume cros,

    We are a bit unsure what are you trying to achieve by assigning physical units to the DataItem.XValue/YValue properties that generally represent logical (data) units.

    Find attached a runnable sample application with the code from our previous reply and use it as a base for any modifications you would like to apply (note that ConvertDataUnitsToPhysical is called in the SizeChanged handler and not the constructor as the physical dimensions of the control are not available yet in the constructor).


    Greetings,
    Freddie
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Back to Top