Select to view content in your preferred language

Custom Clusterer

1244
4
Jump to solution
05-08-2012 08:25 AM
DanielSanders
Occasional Contributor
I would like to create a custom clusterer that clusters only selected graphics on a feature layer. Other than ignoring unselected graphics, I would ilke for it to work exactly like the FlareClusterer. Is there any way to get a copy of the existing code for FlareClusterer to start with?

Thanks...
0 Kudos
1 Solution

Accepted Solutions
JenniferNery
Esri Regular Contributor
You can create your own FlareClusterer and override OnCreateGraphic().

You can try the following code:
public class MyFlareClusterer : FlareClusterer  {    protected override Graphic OnCreateGraphic(GraphicCollection cluster, ESRI.ArcGIS.Client.Geometry.MapPoint point, int maxClusterCount)   {    if (cluster != null)    {     if (cluster.Any(g => g.Selected))     {      var graphics = new GraphicCollection(cluster.Where(g => g.Selected));      return base.OnCreateGraphic(graphics, point, maxClusterCount);     }     else     {      foreach (var g in cluster)       return g;     }    }    return null;   }    }


I'm not sure if you wanted to refresh the cluster when selection is changed, but if you are using Editor. You can trigger clustering by subscribing to EditCompleted event.
    private void Editor_EditCompleted(object sender, Editor.EditEventArgs e)     {      if(e.Action == Editor.EditAction.Select)      {       var l = MyMap.Layers["CensusDemographics"] as FeatureLayer;       l.Clusterer.ClusterGraphicsAsync(l.Graphics, MyMap.Resolution);      }     }


You can look at tweak this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#FeatureLayerSelection. Remove the ArcGISDynamicLayer, change FeatureLayer.Mode to OnDemand, remove the "Renderer="{StaticResource YellowMarkerRenderer}"" and add the following:
    <esri:FeatureLayer.Clusterer>      <local:MyFlareClusterer FlareBackground="Yellow"                                 FlareForeground="#99000000"                                 MaximumFlareCount="20" Radius="10" Gradient="{StaticResource BlueGradient}" />     </esri:FeatureLayer.Clusterer>


Under Resources, you can set your gradient.
<LinearGradientBrush x:Key="BlueGradient" MappingMode="RelativeToBoundingBox" >     <GradientStop Color="#990011FF" Offset="0"/>     <GradientStop Color="#990055FF" Offset="0.25"/>     <GradientStop Color="#990099FF" Offset="0.5"/>     <GradientStop Color="#9900CCFF" Offset="0.75"/>     <GradientStop Color="#9900FFFF" Offset="1"/>    </LinearGradientBrush>

View solution in original post

0 Kudos
4 Replies
JenniferNery
Esri Regular Contributor
You can create your own FlareClusterer and override OnCreateGraphic().

You can try the following code:
public class MyFlareClusterer : FlareClusterer  {    protected override Graphic OnCreateGraphic(GraphicCollection cluster, ESRI.ArcGIS.Client.Geometry.MapPoint point, int maxClusterCount)   {    if (cluster != null)    {     if (cluster.Any(g => g.Selected))     {      var graphics = new GraphicCollection(cluster.Where(g => g.Selected));      return base.OnCreateGraphic(graphics, point, maxClusterCount);     }     else     {      foreach (var g in cluster)       return g;     }    }    return null;   }    }


I'm not sure if you wanted to refresh the cluster when selection is changed, but if you are using Editor. You can trigger clustering by subscribing to EditCompleted event.
    private void Editor_EditCompleted(object sender, Editor.EditEventArgs e)     {      if(e.Action == Editor.EditAction.Select)      {       var l = MyMap.Layers["CensusDemographics"] as FeatureLayer;       l.Clusterer.ClusterGraphicsAsync(l.Graphics, MyMap.Resolution);      }     }


You can look at tweak this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#FeatureLayerSelection. Remove the ArcGISDynamicLayer, change FeatureLayer.Mode to OnDemand, remove the "Renderer="{StaticResource YellowMarkerRenderer}"" and add the following:
    <esri:FeatureLayer.Clusterer>      <local:MyFlareClusterer FlareBackground="Yellow"                                 FlareForeground="#99000000"                                 MaximumFlareCount="20" Radius="10" Gradient="{StaticResource BlueGradient}" />     </esri:FeatureLayer.Clusterer>


Under Resources, you can set your gradient.
<LinearGradientBrush x:Key="BlueGradient" MappingMode="RelativeToBoundingBox" >     <GradientStop Color="#990011FF" Offset="0"/>     <GradientStop Color="#990055FF" Offset="0.25"/>     <GradientStop Color="#990099FF" Offset="0.5"/>     <GradientStop Color="#9900CCFF" Offset="0.75"/>     <GradientStop Color="#9900FFFF" Offset="1"/>    </LinearGradientBrush>
0 Kudos
DanielSanders
Occasional Contributor
Thank you for the code. I doubt that I ever would have come up with that on my own.

The MyFlareCusterer class worked, but for some reason one maptip in each cluster would not appear. In the OnCreateGraphic method I changed this:
foreach (var g in cluster)
return g;

to this:
return new Graphic();

Don't know why it works, but it does. Also, some of your other posts answered questions I had about maptips.

Thanks so much for your help...
0 Kudos
GaryBushek
Deactivated User
You can create your own FlareClusterer and override OnCreateGraphic().

You can try the following code:
public class MyFlareClusterer : FlareClusterer
 { 
  protected override Graphic OnCreateGraphic(GraphicCollection cluster, ESRI.ArcGIS.Client.Geometry.MapPoint point, int maxClusterCount)
  {
   if (cluster != null)
   {
    if (cluster.Any(g => g.Selected))
    {
     var graphics = new GraphicCollection(cluster.Where(g => g.Selected));
     return base.OnCreateGraphic(graphics, point, maxClusterCount);
    }
    else
    {
     foreach (var g in cluster)
      return g;
    }
   }
   return null;
  }  
 }


I'm not sure if you wanted to refresh the cluster when selection is changed, but if you are using Editor. You can trigger clustering by subscribing to EditCompleted event.
    private void Editor_EditCompleted(object sender, Editor.EditEventArgs e)
    {
     if(e.Action == Editor.EditAction.Select)
     {
      var l = MyMap.Layers["CensusDemographics"] as FeatureLayer;
      l.Clusterer.ClusterGraphicsAsync(l.Graphics, MyMap.Resolution);
     }
    }


You can look at tweak this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#FeatureLayerSelection. Remove the ArcGISDynamicLayer, change FeatureLayer.Mode to OnDemand, remove the "Renderer="{StaticResource YellowMarkerRenderer}"" and add the following:
    <esri:FeatureLayer.Clusterer>
     <local:MyFlareClusterer FlareBackground="Yellow"
                                FlareForeground="#99000000"
                                MaximumFlareCount="20" Radius="10" Gradient="{StaticResource BlueGradient}" />
    </esri:FeatureLayer.Clusterer>


Under Resources, you can set your gradient.
<LinearGradientBrush x:Key="BlueGradient" MappingMode="RelativeToBoundingBox" >
    <GradientStop Color="#990011FF" Offset="0"/>
    <GradientStop Color="#990055FF" Offset="0.25"/>
    <GradientStop Color="#990099FF" Offset="0.5"/>
    <GradientStop Color="#9900CCFF" Offset="0.75"/>
    <GradientStop Color="#9900FFFF" Offset="1"/>
   </LinearGradientBrush>


Jennifer,
    In your overridden method "OnCreateGraphic" you call "Any" and "Where" methods on the graphicsCollection.  Im getting an error saying those methods aren't available. Do you have any suggestions or have any updated version of this code snippet with Silverlight API version 2.4?

Thanks, Gary
0 Kudos
PreetiMaske
Esri Regular Contributor
Add "using System.Linq;" to list of namespaces in the codebehind.
0 Kudos