Adding a field to "ClusterItem"

2 posts, 0 answers
  1. Derek
    Derek avatar
    2 posts
    Member since:
    Jun 2013

    Posted 19 Dec 2013 Link to this post

    I am using pushpins on the RadMap control to represent buildings, and each push-pin has a double sqFeet value representing the internal square footage of the building.

    The example shows how to bind to the "Count" field of a ClusterItem
    http://demos.telerik.com/silverlight/#Map/Cluster

    I am clustering based off of the "Clustering" demo, and would like to show a summation of the total square footage represented by a cluster in the ClusterItem text (eg: "25 museums" would become "15039 sq. feet"). With my knowledge of XAML, the only way I can think of doing this would be to add a "sumOfSquareFeet" field to the ClusterItem, and every time a new item is added to a ClusterItem the sumOfSquareFeet value would be updated to store the new sum. 

    In the clustering example, the cluster is bound to the count of items inside of the "ClusterItem"
    <TextBlock Text="{Binding Path=Count}" Style="{StaticResource clusterTextBlockStyle}"/>

    I'd like to bind to the sum of square footage represented by a ClusterItem.

    Any ideas would be appreciated.
  2. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 20 Dec 2013 Link to this post

    Hi Derek,

    I already replied in the support thread you sent but I will post the information here to make it publicly available in case someone encounters the same issue:

    In fact the visualization layer uses the ClusterData class for the cluster. This class contains the Data property. The property can be used to pass extra information to the cluster's data template or by a cluster generator when detecting that the item belongs to the particular cluster. The visualization layer also allows the usage of custom cluster generator. Such a generator can be specified using the VisualizationLayer.ClusterGenerator property.

    So, you can use your own cluster generator to specify any additional information via the ClusterData.Data property. And you can use this property for data binding in your cluster template. You  follow these steps to implement the approach:

    1. Add new class which represents additional information for the cluster.

    public class MyClusterItem : INotifyPropertyChanged
    {
        private double sumOfSquareFeet;
      
        public event PropertyChangedEventHandler PropertyChanged;
      
        public double SumOfSquareFeet
        {
            get
            {
                return this.sumOfSquareFeet;
            }
            set
            {
                this.sumOfSquareFeet = value;
                this.OnPropertyChanged("SumOfSquareFeet");
            }
        }
      
        private void OnPropertyChanged(string name)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChangedEventArgs eventArgs = new PropertyChangedEventArgs(name);
                this.PropertyChanged(this, eventArgs);
            }
        }
    }

    2. Implement a custom cluster generator which specifies additional information in the ClusterData.Data property.

    public class CustomGenerator : DefaultClusterGenerator
    {
        public override ClusterData CreateCluster(Location center, object item)
        {
            ClusterData clusterData = base.CreateCluster(center, item);
      
            MyMapItem mapItem = item as MyMapItem;
            if (mapItem != null)
            {
                clusterData.Data = new MyClusterItem()
                {
                    SumOfSquareFeet = mapItem.SquareFeet
                };
            }
      
            return clusterData;
        }
      
        public override bool IsItemInClusterRegion(ClusterData cluster, MapObjectInfo info, int zoomLevel)
        {
            bool inRegion = base.IsItemInClusterRegion(cluster, info, zoomLevel);
            if (inRegion)
            {
                MyMapItem mapItem = info.Item as MyMapItem;
                MyClusterItem data = cluster.Data as MyClusterItem;
                if (mapItem != null && data != null)
                {
                    data.SumOfSquareFeet += mapItem.SquareFeet;
                }
            }
      
            return inRegion;
        }
    }

    3. Use the custom cluster generator in the visualization layer and apply data bindings.

    <UserControl x:Class="CustomClusterGenerator.MainPage"
        xmlns:local="clr-namespace:CustomClusterGenerator"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
        <UserControl.Resources>
            <DataTemplate x:Key="myToolTipTemplate">
                <Border Background="#7F000000" 
                        HorizontalAlignment="Center"
                        VerticalAlignment="Top" Padding="5">
                    <StackPanel>
                        <TextBlock Text="{Binding Title}" Foreground="White"/>
                        <TextBlock Text="{Binding Description}" Foreground="White"/>
                    </StackPanel>
                </Border>
            </DataTemplate>
      
            <Style x:Key="CustomPushpin" TargetType="telerik:Pushpin">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="telerik:Pushpin">
                            <Border>
                                <telerik:MapLayer.HotSpot>
                                    <telerik:HotSpot X="0.5" Y="1.0" ElementName="Pin" />
                                </telerik:MapLayer.HotSpot>
                                <Canvas x:Name="Pin" Height="32" Width="20">
                                    <Path Fill="Yellow"
                                  Height="32.005"
                                  StrokeStartLineCap="Flat"
                                  Stretch="Fill"
                                  StrokeEndLineCap="Flat"
                                  Stroke="Black"
                                  StrokeThickness="1"
                                  StrokeMiterLimit="10"
                                  StrokeLineJoin="Miter"
                                  Width="20.01"
                                  Data="M1054.5088,458.105L1065.5188,458.105C1067.7278,458.105,1069.5188,459.896,1069.5188,462.105L1069.5188,473.084C1069.5188,475.293,1067.7278,477.084,1065.5188,477.084C1065.5188,477.084,1062.6868,476.831,1062.2128,479.103C1061.6608,481.751,1060.2208,489.11,1060.2208,489.11L1059.3548,489.11C1059.3548,489.11,1058.0138,482.546,1057.2888,479.106C1056.8538,477.041,1054.5088,477.084,1054.5088,477.084C1052.2998,477.084,1050.5088,475.293,1050.5088,473.084L1050.5088,462.105C1050.5088,459.896,1052.2998,458.105,1054.5088,458.105z" />
                                    <Path Canvas.Top="2.989" Canvas.Left="3.188"
                                  Data="M1066.6162,472.8125C1066.6212,473.9125,1065.7252,474.8125,1064.6252,474.8125L1055.2502,474.8125C1054.1502,474.8125,1053.2462,473.9125,1053.2412,472.8125L1053.1962,462.5935C1053.1912,461.4935,1054.0872,460.5935,1055.1872,460.5935L1064.5622,460.5935C1065.6622,460.5935,1066.5662,461.4935,1066.5712,462.5935z"
                                  Fill="Black"
                                  Height="14.219"
                                  Stretch="Fill"
                                  Width="13.42"/>
                                </Canvas>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
      
            <DataTemplate x:Key="ClusteredItemTemplate">
                <telerik:Pushpin telerik:MapLayer.Location="{Binding Path=Location}" Style="{StaticResource CustomPushpin}"
                                 telerik:RadToolTipService.ToolTipContent="{Binding}"
                                 telerik:RadToolTipService.Placement="Mouse"
                                 telerik:RadToolTipService.ToolTipContentTemplate="{StaticResource myToolTipTemplate}"
                                 MouseLeftButtonUp="ClusteredItemMouseClick"/>
            </DataTemplate>
      
            <Style x:Key="clusterTextBlockStyle" TargetType="TextBlock">
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Top"/>
                <Setter Property="TextAlignment" Value="Center"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="Width" Value="Auto"/>
                <Setter Property="TextWrapping" Value="Wrap"/>
            </Style>
      
            <DataTemplate x:Key="ClusterTemplate">
                <Grid x:Name="ParentRoot"
                      Width="Auto" Height="50"
                      telerik:MapLayer.Location="{Binding Path=Center}"
                      telerik:MapLayer.HotSpot="0.5,1"
                      MouseLeftButtonUp="ClusterMouseClick">
                    <Path Width="{Binding Width,ElementName=ParentRoot}"
                          Height="{Binding Height,ElementName=ParentRoot}"
                          Data="M978.6509,491.334L958.6109,491.334L954.4549,500.874L949.9999,491.334L930.6259,491.334C928.4169,491.334,926.6259,489.543,926.6259,487.334L926.6259,433.272C926.6259,431.063,928.4169,429.272,930.6259,429.272L978.6509,429.272C980.8599,429.272,982.6509,431.063,982.6509,433.272L982.6509,487.334C982.6509,489.543,980.8599,491.334,978.6509,491.334z"
                          StrokeStartLineCap="Flat"
                          Stretch="Fill"
                          StrokeEndLineCap="Flat"
                          Stroke="White"
                          StrokeThickness="1"
                          StrokeMiterLimit="10"
                          StrokeLineJoin="Miter"
                          Fill="#7F000000"/>
                    <StackPanel Margin="5">
                        <TextBlock Text="{Binding Path=Data.SumOfSquareFeet}" Style="{StaticResource clusterTextBlockStyle}"/>
                        <TextBlock Text="square feet" Style="{StaticResource clusterTextBlockStyle}"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
      
            <local:CustomGenerator x:Key="ClusterGenerator" />
        </UserControl.Resources>
        <Grid x:Name="LayoutRoot">
            <telerik:RadMap x:Name="RadMap1"
                            Center="47, 13">
                <telerik:RadMap.Providers>
                    <telerik:BingMapProvider/>
                </telerik:RadMap.Providers>
                <telerik:VisualizationLayer x:Name="visualizationLayer"
                                            ClusterGenerator="{StaticResource ClusterGenerator}"
                                            ClusteringEnabled="True"
                                            ClusterItemTemplate="{StaticResource ClusterTemplate}"
                                            ItemTemplate="{StaticResource ClusteredItemTemplate}"
                                            GenerateClustersOnZoom="True"
                                            ItemsSource="{Binding}">
                </telerik:VisualizationLayer>
            </telerik:RadMap>
        </Grid>
    </UserControl>


    Regards,
    Andrey Murzov
    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 >>
  3. DevCraft banner
Back to Top