How to make the point's color in a PointSeries changed dynamically

10 posts, 1 answers
  1. Star
    Star avatar
    6 posts
    Member since:
    Jul 2019

    Posted 06 Jul Link to this post

    When I create a PointSeries chart, the point's color is determined at moment the chart is showing. But I want the point's color changed with the datasource's some content after the chart was  shown.

    So I make a new PlotInfo class shown as below, and  I set DefaultVisualMaterialSelector bind to PlotInfo's ColorFlag, with a Converter.
    Finally, the project doesn't work, the point's color didn't change when I modify the ColorFlag.
    So does ChartView3D support this kind of abbility? And how can I get what I want?

    public class PlotInfo : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public double XValue { get; set; }
        public double YValue { get; set; }
        public string ZValue { get; set; }
        private string m_sColorFlag;
        public string ColorFlag
        {
            get { return m_sColorFlag;}
            set
            {
                m_sColorFlag = value;
                if(this.PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("ColorFlag"));
                }
            }
        }
    }

    MainWindow.xaml

    <Window x:Class="VariableMaterial.MainWindow"
            xmlns:local="clr-namespace:VariableMaterial"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:ColorConvert x:Key="myColorConvert" />
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition />
            </Grid.RowDefinitions>
            <ToolBar Grid.Row="0" Height="auto">
                <Button Content="SetColorFlag=A" Click="ButtonA_Click" Margin="10,0,0,0"/>
                <Button Content="SetColorFlag=B" Click="ButtonB_Click" Margin="10,0,0,0"/>
            </ToolBar>       
            <telerik:RadCartesianChart3D Grid.Row="1">
                <telerik:RadCartesianChart3D.XAxis>
                    <telerik:LinearAxis3D />
                </telerik:RadCartesianChart3D.XAxis>
                <telerik:RadCartesianChart3D.YAxis>
                    <telerik:LinearAxis3D />
                </telerik:RadCartesianChart3D.YAxis>
                <telerik:RadCartesianChart3D.ZAxis>
                    <telerik:CategoricalAxis3D />
                </telerik:RadCartesianChart3D.ZAxis>
                <telerik:RadCartesianChart3D.Series>
                    <telerik:PointSeries3D PointSize="100"
                                           DefaultVisualMaterialSelector="{Binding ColorFlag, Converter={StaticResource myColorConvert}}"
                                           XValueBinding="XValue"
                                           YValueBinding="YValue"
                                           ZValueBinding="ZValue"
                                           ItemsSource="{Binding}"/>
                </telerik:RadCartesianChart3D.Series>
                <telerik:RadCartesianChart3D.Grid>
                    <telerik:CartesianChart3DGrid />
                </telerik:RadCartesianChart3D.Grid>
                <telerik:RadCartesianChart3D.Behaviors>
                    <telerik:Chart3DCameraBehavior />
                </telerik:RadCartesianChart3D.Behaviors>
            </telerik:RadCartesianChart3D>
        </Grid>
    </Window>

     

    MainWindow.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Media;
    using System.Windows.Media.Media3D;
     
     
    namespace VariableMaterial
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public ObservableCollection<PlotInfo> source = new ObservableCollection<PlotInfo>();
            public MainWindow()
            {
                InitializeComponent();
     
                PlotInfo info1 = new PlotInfo()
                {
                    XValue = 1,
                    YValue = 1,
                    ZValue = "A",
                    ColorFlag = "A",
                };
     
                PlotInfo info2 = new PlotInfo()
                {
                    XValue = 2,
                    YValue = 2,
                    ZValue = "B",
                    ColorFlag = "B",
                };
     
                source.Add(info1);
                source.Add(info2);
     
                this.DataContext = source;
            }
     
            private void ButtonA_Click(object sender, RoutedEventArgs e)
            {
                source[0].ColorFlag = "B";
            }
     
            private void ButtonB_Click(object sender, RoutedEventArgs e)
            {
                source[1].ColorFlag = "A";
            }
        }
     
        public class ColorConvert : IValueConverter
        {
            private Dictionary<Color, Material> colorToMaterialDict = new Dictionary<Color, Material>();
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                string colorFlag = (string)value;
                Color color;
     
                if (colorFlag == "A")
                {
                    color = (Color)ColorConverter.ConvertFromString("#007ACC");
                }
                else
                {
                    color = (Color)ColorConverter.ConvertFromString("#68217A");
                }
     
                Material material;
                if (!this.colorToMaterialDict.TryGetValue(color, out material))
                {
                    material = new DiffuseMaterial(new SolidColorBrush(color));
                    colorToMaterialDict[color] = material;
                }
                     
                return material;
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }

     

  2. Dinko
    Admin
    Dinko avatar
    956 posts

    Posted 10 Jul Link to this post

    Hello Star X,

    Thank you for the provided code snippet.

    The reason why the DefaultVisualMaterialSelector is not working is that it expect object of type MaterialSelector. In the convert method the Material object is returned which will not work as expected. In order the approach to work you can again bind the DefaultVisualMaterialSelector property to a ColorFlag, but this time you can declare this property in a ViewModel class. Then you can create custom class which derives from MaterialSelector and perform your custom logic inside the SelectMaterial() method. The final step is to return new instance of this MaterialSelector in the Convert() method of the IValueConverter in order to reset the colors.

    I have create a sample project based on the provided code snippet to demonstrate this approach. Hope this information is helpful.

    Regards,
    Dinko
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.

  3. Star
    Star avatar
    6 posts
    Member since:
    Jul 2019

    Posted 13 Jul Link to this post

    Thanks Dinko !

    Your solution is work well.

    In your solution, a special property  is defined and bind to DefaultVisualMaterialSelector with a converter,  so eachtime this property's value was set,  the Convert() method was called and a custom MaterialSelector was return. In the custom MaterialSelector class, a  override function SelectMaterial()  do some bussiness loggic and return  material with the  specific color.

    So I call this special property a RedrawFlag, because eachtime it's value was set, a redraw event on 3Dpoints will trigered. And I also noticed,  when I set one 3Dpoint's color, all 3Dpoints in the chart will be redraw. Is that right?

    By using your solution, I create a project with a large points chart  about 6000, and the point's color is changed as what I want. But when make the program running for about 2 hours (after press RandomColor button), the using memory keep on increasing from 40MB to 200MB, so is there some code wrong?

    The code is as following.
    Regards,
    Star X.

    MainWindow.xaml

    <Window x:Class="Large3DPoint_ColorBind.MainWindow"
            xmlns:local="clr-namespace:Large3DPoint_ColorBind"
            mc:Ignorable="d"
            Title="MainWindow" Height="600" Width="1000">
            <Window.Resources>
                <local:MyColorConvert x:Key="myColorConvert" />           
            </Window.Resources>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30"/>
                    <RowDefinition />
                </Grid.RowDefinitions>
                <ToolBar Grid.Row="0" Height="auto">
                    <Button Content="SetToGreen" Click="ButtonGreen_Click" Margin="10,0,10,0" Background="LightGray"/>
                <Button Content="SetToRed" Click="ButtonRed_Click" Margin="10,0,10,0" Background="LightGray"/>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="40,0,0,0" Background="GreenYellow">
                    <TextBlock x:Name="textBlock"  TextWrapping="NoWrap" Text="PointIndex(zeroBase):" Margin="10,0,10,0" VerticalAlignment="Center"/>
                    <TextBox x:Name="pointIndex"  Margin="10,0,10,0" TextWrapping="Wrap" Text=""  Width="50" Background="AliceBlue"/>
                </StackPanel>
                <Button x:Name="buttonRandom" Content="RandomColor" VerticalAlignment="Center" Width="100" Background="LightGray" Click="buttonRandom_Click"/>
            </ToolBar>
                <telerik:RadCartesianChart3D Grid.Row="1" Background="DimGray">
                    <telerik:RadCartesianChart3D.XAxis>
                        <telerik:LinearAxis3D />
                    </telerik:RadCartesianChart3D.XAxis>
                    <telerik:RadCartesianChart3D.YAxis>
                        <telerik:LinearAxis3D />
                    </telerik:RadCartesianChart3D.YAxis>
                    <telerik:RadCartesianChart3D.ZAxis>
                        <telerik:CategoricalAxis3D />
                    </telerik:RadCartesianChart3D.ZAxis>
     
                    <telerik:RadCartesianChart3D.Series>
                        <telerik:PointSeries3D PointSize="10"                                      
                                           XValueBinding="XValue"
                                           YValueBinding="YValue"
                                           ZValueBinding="ZValue"
                                           ItemsSource="{Binding SourceData}"
                                           DefaultVisualMaterialSelector="{Binding RedrawFlag, Converter={StaticResource myColorConvert}}"/>
                    </telerik:RadCartesianChart3D.Series>
                    <telerik:RadCartesianChart3D.Grid>
                        <telerik:CartesianChart3DGrid />
                    </telerik:RadCartesianChart3D.Grid>
                    <telerik:RadCartesianChart3D.Behaviors>
                        <telerik:Chart3DCameraBehavior />
                        <telerik:Chart3DTooltipBehavior/>
                </telerik:RadCartesianChart3D.Behaviors>
     
            </telerik:RadCartesianChart3D>
            </Grid>
    </Window>

     

    MainWindow.xaml.cs

    using System;
    using System.Windows;
    namespace Large3DPoint_ColorBind
    {
        public partial class MainWindow : Window
        {
            ViewModel vm;
            System.Timers.Timer timer;
            Random ra = new Random();
            public MainWindow()
            {
                InitializeComponent();
     
                vm = new ViewModel();
                this.DataContext = vm;
            }
     
            private void ButtonGreen_Click(object sender, RoutedEventArgs e)
            {
                int iIndex = -1;
                if(int.TryParse(pointIndex.Text.ToString(), out iIndex) == true)
                {
                    SetPointWithColor(iIndex, "green");
                }
            }
     
            private void ButtonRed_Click(object sender, RoutedEventArgs e)
            {
                int iIndex = -1;
                if (int.TryParse(pointIndex.Text.ToString(), out iIndex) == true)
                {
                    SetPointWithColor(iIndex, "red");
                }
            }
     
            public void SetPointWithColor(int iIndex, string sColor)
            {
                if ((iIndex >= 0) && (iIndex < vm.SourceData.Count))
                {
                    vm.SourceData[iIndex].ColorFlag = sColor;
     
                    //triger the redraw event
                    vm.RedrawFlag = "";
                }
                else
                {
                    MessageBox.Show("Out of range!");
                }
            }
     
            private void buttonRandom_Click(object sender, RoutedEventArgs e)
            {
                timer = new System.Timers.Timer() { };
                timer.Interval = 100;
                timer.Elapsed += Timer_Elapsed;
                timer.Enabled = true;
            }
     
            private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                //throw new NotImplementedException
                int iColor = ra.Next(0, 100);
                string sColor = "yellow";
                if (iColor%3 == 0)
                {
                    sColor = "green";
                }
                else if (iColor % 3 == 1)
                {
                    sColor = "red";
                }
                else
                {
                    sColor = "yellow";
                }
     
                int iIndex = ra.Next(0, vm.SourceData.Count);
     
                SetPointWithColor(iIndex, sColor);
            }
        }
    }

     

    PlotInfo.cs

    using Telerik.Windows.Controls;
     
    namespace Large3DPoint_ColorBind
    {
        public class PlotInfo : ViewModelBase
        {
            public double XValue { get; set; }
            public double YValue { get; set; }
            public double ZValue { get; set; }
     
            private string m_sColorFlag;
            public string ColorFlag
            {
                get { return m_sColorFlag; }
                set
                {
                    m_sColorFlag = value;
                    this.OnPropertyChanged("ColorFlag");
                }
            }
        }
    }

     

    ViewModel.cs

    using System.Collections.ObjectModel;
    using Telerik.Windows.Controls;
     
    namespace Large3DPoint_ColorBind
    {
      public  class ViewModel : ViewModelBase
        {
            private ObservableCollection<PlotInfo> _sourceData;
     
            public ObservableCollection<PlotInfo> SourceData
            {
                get { return _sourceData; }
                set { _sourceData = value; this.OnPropertyChanged("SourceData"); }
            }
     
            private string m_sRedrawFlag;
            public string RedrawFlag
            {
                get { return m_sRedrawFlag; }
                set
                {
                    m_sRedrawFlag = value;
                    this.OnPropertyChanged("RedrawFlag");
                }
            }
     
            public ViewModel()
            {
                SourceData = new ObservableCollection<PlotInfo>();
                this.GetData();
            }
     
            private void GetData()
            {
                for (int k = 0; k < 60; k++)
                {
                    for (int m = 0; m < 50; m++)
                    {
                        //1st layer
                        SourceData.Add(new PlotInfo { XValue = k, YValue = m, ZValue = 5, ColorFlag = "white" });
                    }
                }
     
                for (int k = 0; k < 60; k++)
                {
                    for (int m = 0; m < 50; m++)
                    {
                        //2nd layer
                        SourceData.Add(new PlotInfo { XValue = k, YValue = m, ZValue =50, ColorFlag = "white" });
                    }
                }
     
            }
     
        }
    }

     

    MyDefaultVisualMaterialSelector.cs

    using System;
    using System.Collections.Generic;
    using System.Windows.Media;
    using System.Windows.Media.Media3D;
    using Telerik.Charting;
    using Telerik.Windows.Controls.ChartView;
     
    namespace Large3DPoint_ColorBind
    {
        public class MyDefaultVisualMaterialSelector : MaterialSelector
        {
            private Dictionary<Color, Material> colorToMaterialDict = new Dictionary<Color, Material>();
     
            public override Material SelectMaterial(object context)
            {
                var value = context as XyzDataPoint3D;
                var businessItem = value.DataItem as PlotInfo;
     
                string sColorRGB = "#000000";
                switch (businessItem.ColorFlag)
                {
                    case "yellow":
                        sColorRGB = "#ffff00";
                        break;
                    case "green":
                        sColorRGB = "#008000";
                        break;
                    case "red":
                        sColorRGB = "#ff0000";
                        break;
                    case "white":
                        sColorRGB = "#FFFFFF";
                        break;
                    default:
                        break;
                }
     
                Color color = (Color)ColorConverter.ConvertFromString(sColorRGB);
     
                Material material;
                if (!this.colorToMaterialDict.TryGetValue(color, out material))
                {
                    material = new DiffuseMaterial(new SolidColorBrush(color));
                    colorToMaterialDict[color] = material;
                }
                return material;
     
            }
        }
    }

     

    ColorConvert.cs

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows.Data;
     
     
    namespace Large3DPoint_ColorBind
    {
        public class MyColorConvert : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {           
                return new MyDefaultVisualMaterialSelector();
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }

     

  4. Star
    Star avatar
    6 posts
    Member since:
    Jul 2019

    Posted 13 Jul Link to this post

    Thanks Dinko !

    Your solution is work well.

    In your solution, a special property  is defined and bind to DefaultVisualMaterialSelector with a converter,  so eachtime this property's value was set,  the Convert() method was called and a custom MaterialSelector was return. In the custom MaterialSelector class, a  override function SelectMaterial()  do some bussiness loggic and return  material with the  specific color.

    So I call this special property a RedrawFlag, because eachtime it's value was set, a redraw event on 3Dpoints will trigered. And I also noticed,  when I set one 3Dpoint's color, all 3Dpoints in the chart will be redraw. Is that right?

    By using your solution, I create a project with a large points chart  about 6000, and the point's color is changed as what I want. But when make the program running for about 2 hours (after press RandomColor button), the using memory keep on increasing from 40MB to 200MB, so is there some code wrong?

    The code is as following.
    Regards,
    Star X.

    MainWindow.xaml

    <Window x:Class="Large3DPoint_ColorBind.MainWindow"
            xmlns:local="clr-namespace:Large3DPoint_ColorBind"
            mc:Ignorable="d"
            Title="MainWindow" Height="600" Width="1000">
            <Window.Resources>
                <local:MyColorConvert x:Key="myColorConvert" />           
            </Window.Resources>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30"/>
                    <RowDefinition />
                </Grid.RowDefinitions>
                <ToolBar Grid.Row="0" Height="auto">
                    <Button Content="SetToGreen" Click="ButtonGreen_Click" Margin="10,0,10,0" Background="LightGray"/>
                <Button Content="SetToRed" Click="ButtonRed_Click" Margin="10,0,10,0" Background="LightGray"/>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="40,0,0,0" Background="GreenYellow">
                    <TextBlock x:Name="textBlock"  TextWrapping="NoWrap" Text="PointIndex(zeroBase):" Margin="10,0,10,0" VerticalAlignment="Center"/>
                    <TextBox x:Name="pointIndex"  Margin="10,0,10,0" TextWrapping="Wrap" Text=""  Width="50" Background="AliceBlue"/>
                </StackPanel>
                <Button x:Name="buttonRandom" Content="RandomColor" VerticalAlignment="Center" Width="100" Background="LightGray" Click="buttonRandom_Click"/>
            </ToolBar>
                <telerik:RadCartesianChart3D Grid.Row="1" Background="DimGray">
                    <telerik:RadCartesianChart3D.XAxis>
                        <telerik:LinearAxis3D />
                    </telerik:RadCartesianChart3D.XAxis>
                    <telerik:RadCartesianChart3D.YAxis>
                        <telerik:LinearAxis3D />
                    </telerik:RadCartesianChart3D.YAxis>
                    <telerik:RadCartesianChart3D.ZAxis>
                        <telerik:CategoricalAxis3D />
                    </telerik:RadCartesianChart3D.ZAxis>
     
                    <telerik:RadCartesianChart3D.Series>
                        <telerik:PointSeries3D PointSize="10"                                      
                                           XValueBinding="XValue"
                                           YValueBinding="YValue"
                                           ZValueBinding="ZValue"
                                           ItemsSource="{Binding SourceData}"
                                           DefaultVisualMaterialSelector="{Binding RedrawFlag, Converter={StaticResource myColorConvert}}"/>
                    </telerik:RadCartesianChart3D.Series>
                    <telerik:RadCartesianChart3D.Grid>
                        <telerik:CartesianChart3DGrid />
                    </telerik:RadCartesianChart3D.Grid>
                    <telerik:RadCartesianChart3D.Behaviors>
                        <telerik:Chart3DCameraBehavior />
                        <telerik:Chart3DTooltipBehavior/>
                </telerik:RadCartesianChart3D.Behaviors>
     
            </telerik:RadCartesianChart3D>
            </Grid>
    </Window>

     

    MainWindow.xaml.cs

    using System;
    using System.Windows;
    namespace Large3DPoint_ColorBind
    {
        public partial class MainWindow : Window
        {
            ViewModel vm;
            System.Timers.Timer timer;
            Random ra = new Random();
            public MainWindow()
            {
                InitializeComponent();
     
                vm = new ViewModel();
                this.DataContext = vm;
            }
     
            private void ButtonGreen_Click(object sender, RoutedEventArgs e)
            {
                int iIndex = -1;
                if(int.TryParse(pointIndex.Text.ToString(), out iIndex) == true)
                {
                    SetPointWithColor(iIndex, "green");
                }
            }
     
            private void ButtonRed_Click(object sender, RoutedEventArgs e)
            {
                int iIndex = -1;
                if (int.TryParse(pointIndex.Text.ToString(), out iIndex) == true)
                {
                    SetPointWithColor(iIndex, "red");
                }
            }
     
            public void SetPointWithColor(int iIndex, string sColor)
            {
                if ((iIndex >= 0) && (iIndex < vm.SourceData.Count))
                {
                    vm.SourceData[iIndex].ColorFlag = sColor;
     
                    //triger the redraw event
                    vm.RedrawFlag = "";
                }
                else
                {
                    MessageBox.Show("Out of range!");
                }
            }
     
            private void buttonRandom_Click(object sender, RoutedEventArgs e)
            {
                timer = new System.Timers.Timer() { };
                timer.Interval = 100;
                timer.Elapsed += Timer_Elapsed;
                timer.Enabled = true;
            }
     
            private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                //throw new NotImplementedException
                int iColor = ra.Next(0, 100);
                string sColor = "yellow";
                if (iColor%3 == 0)
                {
                    sColor = "green";
                }
                else if (iColor % 3 == 1)
                {
                    sColor = "red";
                }
                else
                {
                    sColor = "yellow";
                }
     
                int iIndex = ra.Next(0, vm.SourceData.Count);
     
                SetPointWithColor(iIndex, sColor);
            }
        }
    }

     

    PlotInfo.cs

    using Telerik.Windows.Controls;
     
    namespace Large3DPoint_ColorBind
    {
        public class PlotInfo : ViewModelBase
        {
            public double XValue { get; set; }
            public double YValue { get; set; }
            public double ZValue { get; set; }
     
            private string m_sColorFlag;
            public string ColorFlag
            {
                get { return m_sColorFlag; }
                set
                {
                    m_sColorFlag = value;
                    this.OnPropertyChanged("ColorFlag");
                }
            }
        }
    }

     

    ViewModel.cs

    using System.Collections.ObjectModel;
    using Telerik.Windows.Controls;
     
    namespace Large3DPoint_ColorBind
    {
      public  class ViewModel : ViewModelBase
        {
            private ObservableCollection<PlotInfo> _sourceData;
     
            public ObservableCollection<PlotInfo> SourceData
            {
                get { return _sourceData; }
                set { _sourceData = value; this.OnPropertyChanged("SourceData"); }
            }
     
            private string m_sRedrawFlag;
            public string RedrawFlag
            {
                get { return m_sRedrawFlag; }
                set
                {
                    m_sRedrawFlag = value;
                    this.OnPropertyChanged("RedrawFlag");
                }
            }
     
            public ViewModel()
            {
                SourceData = new ObservableCollection<PlotInfo>();
                this.GetData();
            }
     
            private void GetData()
            {
                for (int k = 0; k < 60; k++)
                {
                    for (int m = 0; m < 50; m++)
                    {
                        //1st layer
                        SourceData.Add(new PlotInfo { XValue = k, YValue = m, ZValue = 5, ColorFlag = "white" });
                    }
                }
     
                for (int k = 0; k < 60; k++)
                {
                    for (int m = 0; m < 50; m++)
                    {
                        //2nd layer
                        SourceData.Add(new PlotInfo { XValue = k, YValue = m, ZValue =50, ColorFlag = "white" });
                    }
                }
     
            }
     
        }
    }

     

    MyDefaultVisualMaterialSelector.cs

    using System;
    using System.Collections.Generic;
    using System.Windows.Media;
    using System.Windows.Media.Media3D;
    using Telerik.Charting;
    using Telerik.Windows.Controls.ChartView;
     
    namespace Large3DPoint_ColorBind
    {
        public class MyDefaultVisualMaterialSelector : MaterialSelector
        {
            private Dictionary<Color, Material> colorToMaterialDict = new Dictionary<Color, Material>();
     
            public override Material SelectMaterial(object context)
            {
                var value = context as XyzDataPoint3D;
                var businessItem = value.DataItem as PlotInfo;
     
                string sColorRGB = "#000000";
                switch (businessItem.ColorFlag)
                {
                    case "yellow":
                        sColorRGB = "#ffff00";
                        break;
                    case "green":
                        sColorRGB = "#008000";
                        break;
                    case "red":
                        sColorRGB = "#ff0000";
                        break;
                    case "white":
                        sColorRGB = "#FFFFFF";
                        break;
                    default:
                        break;
                }
     
                Color color = (Color)ColorConverter.ConvertFromString(sColorRGB);
     
                Material material;
                if (!this.colorToMaterialDict.TryGetValue(color, out material))
                {
                    material = new DiffuseMaterial(new SolidColorBrush(color));
                    colorToMaterialDict[color] = material;
                }
                return material;
     
            }
        }
    }

     

    ColorConvert.cs

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows.Data;
     
     
    namespace Large3DPoint_ColorBind
    {
        public class MyColorConvert : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {           
                return new MyDefaultVisualMaterialSelector();
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }

     

  5. Star
    Star avatar
    6 posts
    Member since:
    Jul 2019

    Posted 13 Jul Link to this post

    oh my god, sorry  i don't know why it was paste twice, maybe my network is going wrong.

    Can the administrator of the web delete one of them?

     

  6. Dinko
    Admin
    Dinko avatar
    956 posts

    Posted 17 Jul Link to this post

    Hi,

    Thank you for the provided code snippets.

    I am currently investigating your scenario and I need more time. Will contact you tomorrow with further information about your case. 

    Regards,
    Dinko
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  7. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2245 posts

    Posted 18 Jul Link to this post

    Hello Star X,

    It seems that the material caching mechanism doesn't get cleaned in some case, but we will do some additional time to check why this happens and what alternative solution to suggest.

    Regards,
    Martin Ivanov
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  8. Star
    Star avatar
    6 posts
    Member since:
    Jul 2019

    Posted 19 Jul Link to this post

    Thanks Dinko,

    Thanks Martin Ivanov!

  9. Answer
    Martin Ivanov
    Admin
    Martin Ivanov avatar
    2245 posts

    Posted 23 Jul Link to this post

    Hello Star X,

    The memory increases because the material/shape cache of the chart populates with new materials each time a new instance of the custom material selector is created. This way each selector instance creates new instances of the materials. Even though the custom selector caches the materials, this happens only for the objects created in the current instance of the selector. The next time a color changes, a new instance of the selector is created along with the new materials. 

    To resolve this, use a static field for the "colorToMaterialDict" dictionary in the MyDefaultVisualMaterialSelector class. Here is an example in code:

    public class MyDefaultVisualMaterialSelector : MaterialSelector
    {
    	private static Dictionary<Color, Material> colorToMaterialDict = new Dictionary<Color, Material>();
    	
    	// other code here
    }
    Can you please try this and let me know if it helps?

    Regards, Martin Ivanov
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  10. Star
    Star avatar
    6 posts
    Member since:
    Jul 2019

    Posted 23 Jul Link to this post

    Hello Martin Ivanov,

    Your solution is very good!

    After I apply your solution to my project, the program run with a beginning  memory size of 38MB,and grow to a max memory size of 48MB in half hour, and  it stabilized to this value during the next 2 hours.

    So thanks you all, it help me a lot!

    Thanks!

    Regards,

    Star X

Back to Top