This is a migrated thread and some comments may be shown as answers.

Image as Row or Column

14 Answers 127 Views
PivotGrid
This is a migrated thread and some comments may be shown as answers.
Charles Benoualid
Top achievements
Rank 1
Charles Benoualid asked on 09 Jan 2013, 03:41 PM
is it possible to add Image as Row or Column in pivotGrid? Because it is something that we would require in the near future in our projects. We also need export to excel as soon as possible.

14 Answers, 1 is accepted

Sort by
0
Rosen Vladimirov
Telerik team
answered on 10 Jan 2013, 06:18 AM
Hello Charles,

Could you share some example where do you intend to use images - in the Cells or in Row/Column Headers?

The export functionality is in our to-do list and we'll try to add this feature for the official release of RadPivotGrid (end of February).

Thanks for choosing RadPivotGrid. Do not hesitate to contact us with all your suggestions and concerns.

Regards,
Rosen Vladimirov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Charles Benoualid
Top achievements
Rank 1
answered on 11 Jan 2013, 05:03 PM
lets say product name is the row header. Then allow us to put product name with an image associated to the product name. Because alot of customer require to see more then just the product names.
Also is it possible to do string concatenation in Aggregate functions in the pivot.
0
Rosen Vladimirov
Telerik team
answered on 14 Jan 2013, 07:45 AM
Hello Charles,

We'll provide DataTemplateSelectors in the near future (official release is our target) where you'll be able to modify the headers in the way you want based on their PropertyName and GroupName. With the current release of RadPivotGrid this is not possible.
For your second question if I understand you correctly, you can use StringFormat property for your aggregate descriptions. This way you can represent all of the values in a Currency format for example. But if you want to use aggregate function that concatenates strings and populates RadPivotGrid's cells with the concatenated value, then you should implement custom aggregate description. Please let me know what is your case and how could I help you to resolve it.

Looking forward to hearing from you.

Greetings,
Rosen Vladimirov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Charles Benoualid
Top achievements
Rank 1
answered on 30 Jan 2013, 09:38 PM
Can u send me a modified solution (like the last time) for concatening string by creating a custom aggregate function.
For the rest, the pivot work pretty well.
0
Rosen Vladimirov
Telerik team
answered on 31 Jan 2013, 10:46 AM
Hi Charles,

I'm sending you a simple project where by using custom aggregate function, we are aggregating string values (concatenate them). As I'm not sure if this is exactly what you need, please check the attachment and share some more details on your scenario.

I'm looking forward to hearing from you.

Greetings,
Rosen Vladimirov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Charles Benoualid
Top achievements
Rank 1
answered on 31 Jan 2013, 03:14 PM
Hi, can u modify RadPivotGrid_SL_645577 (last one) in Binding Problem using Pivot thread to make it works with index properties. For Static stuff i see its working from your example. I sent you two screenshot. When using Index Property I cannot see anything its just saying error.


0
Rosen Vladimirov
Telerik team
answered on 31 Jan 2013, 03:28 PM
Hi Charles,

Is it possible to share more details on your scenario? What kind of data you have and how do you intend to show it in RadPivotGrid? As we have already discussed RadPivotGrid is designed to aggregate numeric values and all projects I've sent you are customized for a specific case. This is leading to different issues when we do not have the exact scenario that has to be covered. This information will give us the chance to provide you the best solution we have.

Looking forward to hearing from you.

All the best,
Rosen Vladimirov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Sergio
Top achievements
Rank 1
answered on 10 Sep 2013, 12:07 PM
Hi.

We had a similar problem recently with one client that needed to filter/group text information and not numeric items.

The PivotGrid was not originally ment for this but is way faster to use and develop than the RadGridView since it already has the built in column/row collapse, item hiearchy, column groups, etc. all that would have to be coded for the RadGridView. Another feature is the drag&drop on the field list that allows our clients to quickly change the columns with the rows and do all kinds of analysis.

Data Example:
The client has a retail company and usually only wants to analyse values so he would use the pivot normally:
[Rows hierarchy]
Beverages with alchool
     Ready to drink
           Carbonated
           Plain
    Mix
           Carbonated
           Plain
Beverages without alchool
     Ready to drink
           Carbonated
           Plain
    Mix
           Carbonated
           Plain

[Columns Hierarchy]
Cold
    330ml
    550ml
Non Cold
    330ml
    550ml


This information comes from a database using the PrepareDescriptionForField event of the LocalDataSourceProvider.

The problem is that the client suddently didn't want to know the sales, but actually the product names (distinct) sold along with an image (arrow up,down,equal) that would visually indicate if the growth of sales compared to last year.

Ok, you will say that this is a very specific (even might be a bit idiotic) need but is very real. So what could we do if the Pivot only allowed values on the cells and not images or specific aggregates?
The solution, has previous stated on this post and I'm writing it here because it might shed some light for others, was to use the template selector, then a content control. Since the DataContext was still only CellData and we needed the more information like the datasource, we added a converter.
This is FAR from being the best solution (even because it uses reflection and the filters on the RadPivotFieldList don't do their job..) but helped us get on our way and solve a specific problem. Hopefully the component will evolve.

<UserControl x:Class="SilverlightApplication1.MainPage"
    mc:Ignorable="d"
   xmlns:tree="clr-namespace:Telerik.Windows.Controls.Pivot;assembly=Telerik.Windows.Controls.Pivot"
    xmlns:local="clr-namespace:SilverlightApplication1"
             xmlns:fieldList="http://schemas.telerik.com/2008/xaml/presentation/pivot"
              xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             xmlns:pivot="http://schemas.telerik.com/2008/xaml/presentation/pivot"
    d:DesignHeight="300" d:DesignWidth="400">
 
    <UserControl.Resources>
         
 
        <pivot:LocalDataSourceProvider  x:Key="dataProvider"  >
            <pivot:LocalDataSourceProvider.ItemsSource>
                <local:CDTS/>
            </pivot:LocalDataSourceProvider.ItemsSource>
            <pivot:LocalDataSourceProvider.RowGroupDescriptions>
                <pivot:PropertyGroupDescription PropertyName="Categoria" />
            </pivot:LocalDataSourceProvider.RowGroupDescriptions>
            <pivot:LocalDataSourceProvider.ColumnGroupDescriptions>
                <pivot:PropertyGroupDescription PropertyName="Refrescantes" />
                <pivot:PropertyGroupDescription PropertyName="Funcionais" />
            </pivot:LocalDataSourceProvider.ColumnGroupDescriptions>
            <pivot:LocalDataSourceProvider.AggregateDescriptions>
                <pivot:PropertyAggregateDescription PropertyName="Items" AggregateFunction="Count" />
            </pivot:LocalDataSourceProvider.AggregateDescriptions>
        </pivot:LocalDataSourceProvider>
 
        <local:Formatter x:Key="FormatConverter"  DataSource="{StaticResource dataProvider}" />
 
 
        <local:PCellTemplateSelector x:Key="PCellTemplateSelector">
            <local:PCellTemplateSelector.Teste>
                <DataTemplate>
                    <ContentControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
                                    Content="{Binding Data, Converter={StaticResource FormatConverter}}" />
                </DataTemplate>
            </local:PCellTemplateSelector.Teste>
        </local:PCellTemplateSelector>
 
        
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
 
        <pivot:RadPivotGrid DataProvider="{StaticResource dataProvider}" FontSize="10" CellTemplateSelector="{StaticResource PCellTemplateSelector}"/>
 
        <pivot:RadPivotFieldList x:Name="FieldList" Grid.Column="1" Margin="1 0 0 0" DataProvider="{StaticResource dataProvider}"
                                                      HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  />
 
    </Grid>
</UserControl>

// Summary:
   //     Default CellTemplateSelector for Telerik.Windows.Controls.RadPivotGrid.
   public class PCellTemplateSelector : Telerik.Windows.Controls.DataTemplateSelector
   {
 
       public DataTemplate Teste { get; set; }
 
       public override System.Windows.DataTemplate SelectTemplate(object item, DependencyObject container)
       {
           return this.Teste;
       }
   }
 
 
   public class Formatter : DependencyObject, IValueConverter
   {
       #region DataSource Dependency Property
 
       public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register(
           "DataSource",                          
           typeof(LocalDataSourceProvider),                       
           typeof(Formatter),           
           null);
 
       public LocalDataSourceProvider DataSource
       {
           set
           {
               this.SetValue(DataSourceProperty, value);
           }
           get
           {
               return (LocalDataSourceProvider)this.GetValue(DataSourceProperty);
           }
       }
 
       
       #endregion
 
 
 
       #region IValueConverter Members
 
       public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
       {
 
 
           CellAggregateValue cellAggregateValue = value as CellAggregateValue;
           if (cellAggregateValue != null)
           {
               int? totalItems = null;
               List<CDT> candidateItems = GetFilteredItems(cellAggregateValue.ColumnGroup, cellAggregateValue.RowGroup, out totalItems);
 
               if (totalItems != null) //total row/column
               {
                   TextBlock txt = new TextBlock();
                   txt.TextAlignment = TextAlignment.Center;
                   txt.HorizontalAlignment = HorizontalAlignment.Center;
                   txt.VerticalAlignment = VerticalAlignment.Center;
                   txt.Margin = new Thickness(2);
                   txt.FontWeight = FontWeights.Bold;
                   txt.FontSize = 12;
                   txt.Foreground = new SolidColorBrush(Colors.Gray);
                   txt.Text = totalItems.ToString();
 
                   return txt;
               }
               else if (candidateItems.Count() == 1 && candidateItems[0].Conteudo != null) //item
               {
 
                   Grid grid = new Grid();
                   grid.Margin = new Thickness(1);
                   grid.HorizontalAlignment = HorizontalAlignment.Stretch;
                   grid.VerticalAlignment = VerticalAlignment.Stretch;
                   grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(50, GridUnitType.Star) });
                   grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(20, GridUnitType.Auto) });
                   TextBlock txt = new TextBlock();
                   txt.TextWrapping = TextWrapping.Wrap;
                   txt.HorizontalAlignment = HorizontalAlignment.Center;
                   txt.VerticalAlignment = VerticalAlignment.Center;
                   txt.Foreground = new SolidColorBrush(Colors.LightGray);
                   txt.Margin = new Thickness(3);
                   txt.FontSize = 10;
                   txt.Text = candidateItems[0].Conteudo;
                   Grid.SetColumn(txt, 0);
                   grid.Children.Add(txt);
                   Image img = new Image();
                   img.Width = 20;
                   img.Margin = new Thickness(0, 3, 3, 3);
                   img.Height = 20;
                   img.VerticalAlignment = VerticalAlignment.Center;
                   img.HorizontalAlignment = HorizontalAlignment.Center;
                   img.Source = new BitmapImage(new Uri("/SilverlightApplication1;component/Alert-Icon-.png", UriKind.Relative));
                   img.Stretch = Stretch.Uniform;
                   Grid.SetColumn(img, 1);
                   grid.Children.Add(img);
                   return grid;
               }
               else
               {
                   return null;
               }
           }
           else
           {
 
               return null;
           }
       }
 
       private List<CDT> GetFilteredItems(IGroup column, IGroup row, out int? totalItems)
       {
           totalItems = null;
 
           List<CDT> candidateItems = ((Collection<CDT>)DataSource.ItemsSource).ToList();
 
           bool isCount = false;
           if ((row.Name is Telerik.Pivot.Core.NullValue) || ((string)row.Name).ToLower().Contains("total"))
           {
               row = row.Parent;
               isCount = true;
           }
           if ((column.Name is Telerik.Pivot.Core.NullValue) || ((string)column.Name).ToLower().Contains("total"))
           {
               column = column.Parent;
               isCount = true;
           }
 
           #region filter items for this column tree
 
           if (column != null) //GRAND TOTAL
           {
               string columnName = DataSource.ColumnGroupDescriptions[column.Level].PropertyName;
               candidateItems = candidateItems.Where(x => ((string)x.GetType().GetProperty(columnName).GetValue(x, null)) == (string)column.Name).ToList();
               while (column.Parent != null)
               {
                   column = column.Parent;
                   columnName = DataSource.ColumnGroupDescriptions[column.Level].PropertyName;
                   candidateItems = candidateItems.Where(x => ((string)x.GetType().GetProperty(columnName).GetValue(x, null)) == (string)column.Name).ToList();
               }
           }
           else
           {
               totalItems = 0;
           }
           #endregion
 
           #region filter items for this row tree
 
           if (row != null) //GRAND TOTAL
           {
               string rowName = DataSource.RowGroupDescriptions[row.Level].PropertyName;
               candidateItems = candidateItems.Where(x => ((string)x.GetType().GetProperty(rowName).GetValue(x, null)) == (string)row.Name).ToList();
               while (row.Parent != null)
               {
                   row = row.Parent;
                   rowName = DataSource.RowGroupDescriptions[row.Level].PropertyName;
                   candidateItems = candidateItems.Where(x => ((string)x.GetType().GetProperty(rowName).GetValue(x, null)) == (string)row.Name).ToList();
               }
           }
           else
           {
               totalItems = 0;
           }
           #endregion
 
           if (isCount)
           {
               totalItems = candidateItems.Where(x => x.Conteudo != null).Select(x => x.Conteudo.Split('\n').Length).Sum();
           }
 
           return candidateItems;
       }
 
       public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
       {
           return value;
       }
 
       #endregion
   }



public class CDTS : Collection<CDT>
    {
        public CDTS()
        {
 
             
 
            //REFRESCANTES 330
            this.Add(new CDT { Categoria0 = "Bebidas s/ Alcool", Categoria1 = "Pronto a beber", Categoria2 = "C/ Gás", Tipo = "Refrescantes", SubTipo = "330ml", Conteudo = "SKU1\nSKU16" });
            this.Add(new CDT { Categoria0 = "Bebidas s/ Alcool", Categoria1 = "Pronto a beber", Categoria2 = "S/ Gás", Tipo = "Refrescantes", SubTipo = "330ml", Conteudo = "SKU12" });
            this.Add(new CDT { Categoria0 = "Bebidas s/ Alcool", Categoria1 = "Pronto a beber", Categoria2 = "Águas", Tipo = "Refrescantes", SubTipo = "330ml" });
            this.Add(new CDT { Categoria0 = "Bebidas s/ Alcool", Categoria1 = "Solúveis", Categoria2 = "Café", Tipo = "Refrescantes", SubTipo = "330ml", Conteudo = "SKU45\nSKU59" });
            this.Add(new CDT { Categoria0 = "Bebidas s/ Alcool", Categoria1 = "Solúveis", Categoria2 = "Sumo", Tipo = "Refrescantes", SubTipo = "330ml" });
 
(...)




The result is on the image attached.
0
Rosen Vladimirov
Telerik team
answered on 12 Sep 2013, 01:21 PM
Hi Tiago,

Thank you for choosing RadPivotGrid. Your solution of the problem is very interesting for us and we would like to help you to improve it further. Can you send us a sample demonstrating your approach, so we could check it and if possible - to suggest how to improve it. Anyway the solution is very interesting and good looking. Great work.

I'm looking forward to hearing from you.

Regards,
Rosen Vladimirov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Sergio
Top achievements
Rank 1
answered on 12 Sep 2013, 06:45 PM
I can't post here the exact code we have because it uses a lot of our internal framework.

Anyway I will post here the sample I've used for testing while I was trying to get the result I needed.
Hopefully you can find areas where it can be improved either by reducing the code, improving performance or even by reducing the impact on future releases due to this large component customization.
Currently it supports cell selection because we need to list special information on a grid based on the subset of data on the cell. (ex: selected cell has a couple of product codes and on the grid we list those products market information, price analysis, etc.)

I would leave here a few suggestions for your development teams to consider for the future of this control:
- ContentControl for the cells
- Custom Filter on the row labels (instead of TOP 10 of the values, I may want to create a diferent one using a formula on the expression editor)
- Cell selection event

0
Rosen Vladimirov
Telerik team
answered on 17 Sep 2013, 02:44 PM
Hi Tiago,

We'll be glad to help you with your implementation. We'll consider all of your feature requests. The cells in our RadPivotGrid for Silverlight are TextBlocks to improve the performance, but as you know you can use CellTemplate and set whatever you need.

Thank you for your suggestions. Feel free to send more suggestions and feedback.

Regards,
Rosen Vladimirov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Sergio
Top achievements
Rank 1
answered on 17 Sep 2013, 11:25 PM
I've already compiled a small app and I'm using the nightly build libraries.
I was going to upload it here but my guess is that is could be a security risk since this is public and then anyone could use those dlls even without being licensed.
Should I send the solution zip through a support ticket (or any other way) and then, once you've filtered everything necessary, you'll post it here?

Thanks
0
Rosen Vladimirov
Telerik team
answered on 18 Sep 2013, 08:12 AM
Hello Tiago,

Feel free to open a support ticket and send the project there. We'll take a look at it and once we are ready, we'll post it here.

Thank you for your commitment and cooperation. I'm looking forward to hearing from you.

Regards,
Rosen Vladimirov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Sergio
Top achievements
Rank 1
answered on 18 Sep 2013, 09:37 AM
Done.
Hope to hear from you later maybe with suggestions on how to improve performance or solve a few issues.

Thanks
Tags
PivotGrid
Asked by
Charles Benoualid
Top achievements
Rank 1
Answers by
Rosen Vladimirov
Telerik team
Charles Benoualid
Top achievements
Rank 1
Sergio
Top achievements
Rank 1
Share this question
or