Select to view content in your preferred language

Graphs and Charts

7031
36
03-31-2011 04:10 PM
NathalieNeagle
Regular Contributor
I have a simple police application that allows officers to spatial select and query some points (police calls).  I using esri FeatureDataGrid.  I wanted to create a few simple charts and graphs and send the queried data (that is in the featuredatagrid) into these grids and charts. 

Currently I'm trying to send the selected GraphicLayer
<esri:GraphicsLayer ID="MySelectionGraphicsLayer" />

here's a small snip of my code behind to select the graphiclayer
 GraphicsLayer selectionGraphicslayer = Map.Layers["MySelectionGraphicsLayer"] as GraphicsLayer;
            selectionGraphicslayer.ClearGraphics();


I'm wondering if I'm binding it right

Here's my Pie Chart




 <Grid Style="{StaticResource WrapperStyle}">
            <chartingToolkit:Chart Title="AnimationSequence = FirstToLast" Palette="{StaticResource GrowPieDataPointPalette}" Style="{StaticResource ChartStyle}" MouseLeftButtonDown="OnMouseLeftButtonDown" Margin="1,4,-1,-4">
                <chartingToolkit:Chart.Series>
                    <chartingToolkit:PieSeries ItemsSource="{Binding ElementName=Map, Path=Layers[MySelectionGraphicsLayer].Graphics}" DependentValueBinding="{Binding Attributes[DISPDESC]}" AnimationSequence="FirstToLast"/>
                 </chartingToolkit:Chart.Series>
            </chartingToolkit:Chart>
        </Grid>




My table works and here's how I'm binding that:

 <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="15" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <TextBlock x:Name="DataDisplayTitle" Text="Search Results" FontSize="9" Grid.Row="0" FontWeight="Bold" FontFamily="Arial" Foreground="#FFFFFFFF" />



                            <esriWidgets:FeatureDataGrid Grid.Row="1" x:Name="QueryDetailsDataGrid" Height="170" 
                                      Map="{Binding ElementName=Map}" 
                                      GraphicsLayer="{Binding Layers[MySelectionGraphicsLayer], ElementName=Map}" />

                        </Grid>




Does it seem like I'm binding the Pie Graph correctly because now app is not completely firing and its not really working; it is only selecting or creating one graphic.  If I try to select 20 points only one gets selected and the featuredatagrid is not firing and showing up (ResultsDisplay.Visibility = Visibility.Visibility).  Everything was working before so I'm wondering/thinking it is something with my pie chart.



Thanks
Nat
0 Kudos
36 Replies
MuhammadWaqar_ul_islam
Occasional Contributor
thanks its working
0 Kudos
MuhammadWaqar_ul_islam
Occasional Contributor
I little Query in Pie Chart Value
i Want to calculate values of field (Shape_lenght) data type (double)  of a line feature

  DataContext = graphicsLayer.Graphics.GroupBy(graphic => (string)graphic.Attributes["GISUTPL_DIA"],
                            (GISUTPL_DIA, graphics) => new AttributeGroup
                            {
                               Key = GISUTPL_DIA,
                                Count = graphics.Count(),
                   Sum = graphics.Select(g => (double)g.Attributes["SHAPE_Length"]).Sum(),                                Graphics = graphics
                            }).ToArray();


public class AttributeGroup
        {
          public string Key { get; set; }
            public double    Sum { get; set; }
            public int Count { get; set; }
          
            public IEnumerable<Graphic> Graphics { get; set; } // only useful for graphics selection from sliver selection
        }


GOT AN ERROR ON
Sum = graphics.Select(g => (double)g.Attributes["SHAPE_Length"]).Sum(),
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Check :

  • that the attribute SHAPE_Length is exposed by your service,

  • that your are using the right case

  • and that you included this attribute in the list of returned attributes (i.e. OutFields="*" or OutFields="........, SHAPE_Length")

0 Kudos
MuhammadWaqar_ul_islam
Occasional Contributor
Check :

  • that the attribute SHAPE_Length is exposed by your service,

  • that your are using the right case

  • and that you included this attribute in the list of returned attributes (i.e. OutFields="*" or OutFields="........, SHAPE_Length")




1) i Have check  SHAPE_Length is exposed in my services (services pics is attached)
2) i m using right case SHAPE_Length
3)  list of returned attributes
  // Specify fields to return from query
            query.OutFields.AddRange(new string[] { "GISUTPLDS2", "GISUTPL_IMT", "GISUTPL_IYR", "GISUTPL_DIA", "GISUTPLFC", "SHAPE_Length" });
            query.Geometry = args.Geometry;
<slData:DataGrid.Columns>
                        <slData:DataGridTextColumn CanUserSort="True" SortMemberPath="GISUTPLDS2" Binding="{Binding Attributes[GISUTPLDS2]}" Header="Name"/>
                        <slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[GISUTPL_IMT]}" Header="MONTH"/>
                        <slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[GISUTPL_IYR]}" Header="YEAR"/>
                        <slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[GISUTPL_DIA]}" Header="DIA"/>
                        <slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[GISUTPLFC]}" Header="MATERIAL"/>
                        <slData:DataGridTextColumn CanUserSort="True"  SortMemberPath="SHAPE_Length" Binding="{Binding Attributes[SHAPE_Length]}" Header="Length"/>
                    </slData:DataGrid.Columns>
                </slData:DataGrid>

-----------------------------------------------------------------------

WHAT NEXT TO DO TO SOLVE THIS ISSUE
--------------------------------------------------------------------------
0 Kudos
DominiqueBroux
Esri Frequent Contributor
WHAT NEXT TO DO TO SOLVE THIS ISSUE

As I saw your are displaying the SHAPE_Length in the grid, can you check that there is no special values (such as null or infinity) that could explain why the sum is crashing?

If it's the case, you may need a converter to replace these special values by something else (likely 0).
If it's not the case, I guess you need more debugging to figure out  what are the lengths when the sum is crashing.

Hope this help.
0 Kudos
MuhammadWaqar_ul_islam
Occasional Contributor
As I saw your are displaying the SHAPE_Length in the grid, can you check that there is no special values (such as null or infinity) that could explain why the sum is crashing?

If it's the case, you may need a converter to replace these special values by something else (likely 0).
If it's not the case, I guess you need more debugging to figure out  what are the lengths when the sum is crashing.

Hope this help.


i have calculate the sum of values of feild Integer (works fine showing values in the pie as well in the attributes table  and Shape_lenght values too ) i m attaching snap shoot of that
0 Kudos
NathalieNeagle
Regular Contributor
Dominique,

I was hoping to ask another question.  I created another chart (Bar Chart) and want to re-use all the code but have the bar chart group by a different field.  So I thought I could just add a few lines to accomplish but I'm having no luck.


Here' I just add a new Group field called Key2
  public class AttributeGroup
        {
            public string Key { get; set; }
            public int Sum { get; set; }
            public int Count { get; set; }
            public int Key2 { get; set; }
            public IEnumerable<Graphic> Graphics { get; set; } // only useful for graphics selection from sliver selection
        }




Now here's where I'm not sure what/if I can do this.

  DataContext = graphicsLayer.Graphics.GroupBy(graphic => (string)graphic.Attributes["TYPECODE"],
                            (typecode, graphics) => new AttributeGroup
                            {
                                Key = typecode,
                                Key2 = graphics.GroupBy(g => (int)g.Attributes["CALL"]), 
                                Count = graphics.Count(),
                                Sum = graphics.Select(g => (int)g.Attributes["DOW"]).Sum(),
                                Graphics = graphics
                               
                            }).ToArray();



This new line is giving me the trouble, is this approach possible?
Key2 = graphics.GroupBy(g => (string)g.Attributes["CALL"]),

I also thought maybe just create a new class named AttributeGroup2 and then create a new enumeration of AttributeGroup2 but I didn't have success.

Nathalie
0 Kudos
DominiqueBroux
Esri Frequent Contributor
You can't use the same datacontext for your 2 charts both are not using the same grouping.

Create a datacontext by chart instead, eachone with its own group attribute.
0 Kudos
NathalieNeagle
Regular Contributor
Dominique,

That is what I was thinking so I don't need to create a new class AttributeGroup, right?
XAML FOR MY LINE GRID

        <userControls:CollapsiblePanel x:Name="LineGrid" IsExpanded="False" VerticalAlignment="Top" 
            HorizontalAlignment="Right" Margin="0,75,10,0" Width="420" Height="320" Effect="{StaticResource dropShadow}" >




            <Grid Width="400" Height="300" HorizontalAlignment="Right" VerticalAlignment="Center">

                <Border Background="{StaticResource CommonPanelBorderBackgroundBrush}" BorderBrush="{StaticResource CommonBorderBrush}" BorderThickness="1" CornerRadius="6" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                    <Border Effect="{StaticResource miniDropShadow}" Style="{StaticResource RibbonElementBorder}" Padding="15" Margin="10" >


                        <chartingToolkit:Chart Title="Police DATA">
                            <chartingToolkit:Chart.Series>
                                <chartingToolkit:LineSeries IsSelectionEnabled="True" SelectionChanged="LineSeries_SelectionChanged" 
                                    Title="CAD CALL TYPE" 
                                    ItemsSource="{Binding}" 
                                   IndependentValuePath="KEY2"
                                   DependentValuePath="Count"
                                   
                                />       
                                </chartingToolkit:Chart.Series>
                        </chartingToolkit:Chart>

                    </Border>
                </Border>

                <Image Source="images/CloseX.png" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="3" Stretch="None" Cursor="Hand" ToolTipService.ToolTip="Close" >
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseLeftButtonDown" >
                            <actions:ToggleCollapseAction TargetName="LineGrid" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Image>

            </Grid>

        </userControls:CollapsiblePanel>





CODE BEHIND WITH TWO DATACONTENT

            // PIE CHART -  create an enumeration of AttributeGroup from the graphics in your layer

            DataContext = graphicsLayer.Graphics.GroupBy(graphic => (string)graphic.Attributes["TYPECODE"],
                            (typecode, graphics) => new AttributeGroup
                            {
                                Key = typecode,
                                
                                Count = graphics.Count(),
                                Sum = graphics.Select(g => (int)g.Attributes["DOW"]).Sum(),
                                Graphics = graphics

                            }).ToArray();

            //END PIE CHART

            //LINE CHART
             DataContext = graphicsLayer.Graphics.GroupBy(graphic => (int)graphic.Attributes["CALL"],
                            (call, graphics) => new AttributeGroup
                            {
                              
                              Key2 = call,
                             //  GISDATE = DateTime.ParseExact(gisdate.ToString(), "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture),
                               
                               Count = graphics.Count(),
                               Sum = graphics.Select(g => (int)g.Attributes["DOW"]).Sum(),
                            
                                Graphics = graphics
                            }).ToArray();

          //END LINE CHART



But this seems to kind of break my pie chart...now my pie chart groups but the legend group names (CAD CALL TYPES) Don't display correctly instead of being names like Homicide, Robbery, or Assualt it is just 1, 2 , and/or 3.

I think I need to assign the DataContext property a new value??? like if it was a type??
private DataContext lineChartDataContent; ?????
then use
   lineChartDataContent = graphicsLayer.Graphics.GroupBy(graphic => (int)graphic.Attributes["GISDATE"],
                            (gisdate, graphics) => new AttributeGroup



Not to sure can you enlighten me
0 Kudos
DominiqueBroux
Esri Frequent Contributor
If you want to display both charts at the same time you can't use the DataContext for both charts.

In your control (or your view model), you have to create two dependency properties (or 2 properties) of type IEnumerable<AttributeGroup>.

You initialize the first one with the group by TYPECODE, the second one with the group by CALL (instead of initializing the datacontext).

Then in XAML you bind the ItemsSource of yours charts to these properties (instead of ItemsSource="{Binding}").

Note : you don't need the new Key2 property, you can use the same Key property for both groups of graphics.
0 Kudos