Select to view content in your preferred language

Help with a simple Line Chart

3329
20
03-09-2011 12:48 PM
JoshV
by
Regular Contributor
Hello All-

I have a simple Silverlight Application that uses a Timeline and I just want to put in a simple Line Chart above the timeline that will dynamically change if possible.  I've been looking at this link (http://www.silverlight.net/content/samples/sl4/toolkitcontrolsamples/run/default.html) but in the Line Series Section for the XAML I do not understand how they are passing the values to the chart.  Does anyone have any good examples of code that show the chart linked to a layer in the Map?

Many Thanks,
0 Kudos
20 Replies
JenniferNery
Esri Regular Contributor
I have not used LineSeries myself but if you look at the code and chart sample, you will notice that they set ItemsSource, IndependentValueBinding (X-axis) and DependentValueBinding (Y-axis).


  <chartingToolkit:Chart Title="Typical Use">
                    <chartingToolkit:ChartSeries>
                        <chartingToolkit:LineSeries Title="Particulate Levels" ItemsSource="{Binding LevelsInRainfall, Source={StaticResource ParticulateLevel}}" IndependentValueBinding="{Binding Rainfall}" DependentValueBinding="{Binding Particulate}"/>
                    </chartingToolkit:Chart.Series>
                </chartingToolkit:Chart>


This might also be helpful: http://leeontech.wordpress.com/2009/03/13/showing-and-hiding-series-in-chart/
0 Kudos
JoshV
by
Regular Contributor
I have not used LineSeries myself but if you look at the code and chart sample, you will notice that they set ItemsSource, IndependentValueBinding (X-axis) and DependentValueBinding (Y-axis).




Hi Jennifer-  Where is "Rainfall" and "Particulate" coming from?  I can tell its affecting the X and Y axis but am not sure where exactly its coming from.  Also what would I do differently to have it read from a layer in my Map?  Thanks Jennifer
0 Kudos
DominiqueBroux
Esri Frequent Contributor
If you need to get one line or one column by graphic, the ItemSources of your chart can be the Graphics property of your layer.

Something like (based on this sample : http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#TemporalRendererTracks) :
<Charting:Chart>
<Charting:Chart.Series>
<Charting:ColumnSeries Title="Wind Speed" ItemsSource="{Binding ElementName=MyMap, Path=Layers[MyHurricaneFeatureLayer].Graphics}" IndependentValueBinding="{Binding Attributes[EVENTID]}" DependentValueBinding="{Binding Attributes[WINDSPEED]}"/>
</Charting:ColumnSeries>
</Charting:Chart.Series>
</Charting:Chart>


Then, when using TimeAware layers, the difficulty is to filter the graphics in order your chart to display only the graphics in the current time extent and/or only the last observations.

Let do that with the hurricane sample.

1) Let's write a method returning the graphics corresponding to the last observations of the time extent (thanks LINQ):
private IEnumerable<Graphic> GetLastObservations(IEnumerable<Graphic> graphics)
{
return from g in graphics
where g.TimeExtent.Intersects(MyMap.TimeExtent)
group g by g.Attributes["EVENTID"] into grp
select grp.OrderByDescending(g => g.Attributes["Date_Time"]).First();
}
2) Define a property to return the LastObservations:
private readonly ObservableCollection<Graphic> _lastObservations = new ObservableCollection<Graphic>();
public ObservableCollection<Graphic> LastObservations { get { return _lastObservations; } }

3) Define a method setting this LastObservations property:
private void SetLastObservations()
{
    var layer = MyMap.Layers["MyHurricaneFeatureLayer"] as GraphicsLayer;
    LastObservations.Clear();
    foreach (var g in GetLastObservations(layer.Graphics))
        LastObservations.Add(g);
}
4) Call SetLastObservations when the collection can change i.e. when the feature layer updates and when the time extent changes:
private void FeatureLayer_UpdateCompleted(object sender, EventArgs e)
{
    SetLastObservations();
}
 
private void MyMap_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if (e.PropertyName == "TimeExtent")
        SetLastObservations();
}
4) In XAML, hook up these events
5) Modify the chart to take care of this LastObservations property
<Charting:Chart><Charting:Chart.Series>
<Charting:ColumnSeries Title="Wind Speed" ItemsSource="{Binding LastObservations}" IndependentValueBinding="{Binding Attributes[EVENTID]}" DependentValueBinding="{Binding Attributes[WINDSPEED]}">
</Charting:ColumnSeries>
</Charting:Chart.Series>
<Charting:Chart.Axes>
<Charting:LinearAxis Orientation="Y" Minimum="0" Maximum="120" Interval="20" ShowGridLines="True" FontStyle="Italic"/>
</Charting:Chart.Axes>
</Charting:Chart>

6) Set the datacontext of your control to itself:
public TemporalRendererTracks()
{
    InitializeComponent();
    DataContext = this;
}

Hope I didn't forget some steps!
0 Kudos
JoshV
by
Regular Contributor
If you need to get one line or one column by graphic, the ItemSources of your chart can be the Graphics property of your layer.

Something like (based on this sample : http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#TemporalRendererTracks) :


Hi Dominique-  Thank you for posting this reply.  Where you are saying
<Chart.Chart>
what do I need to do to reference Chart so I can that part working?
0 Kudos
DominiqueBroux
Esri Frequent Contributor
In your project, add a reference to System.Windows.Controls.DataVisualization.Toolkit.

and in your xaml, add this line:
 xmlns:Charting="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
0 Kudos
JoshV
by
Regular Contributor
In your project, add a reference to System.Windows.Controls.DataVisualization.Toolkit.

and in your xaml, add this line:
 xmlns:Charting="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"



Hi Dominique-  The reference you gave me worked so now I'm trying to test all the code you provided.  The Graph comes in my Silverlight just fine but when I run the website in my browser nothing ever gets drawn in the graph.  No line or or anything.  I'm testing to see if the Layer name I used instead of MyHurricaneFeatureLayer is an issue.  I used your code nearly exactly accept changed MyHurricaneFeatureLayer to WellsFeatureLayer and the Attributes in my layer I need to use are in a column called EOM (X-axis) and column called Adj_Close (Y-Axis).  If you have any suggestions I'd be glad to hear them.  Thanks again Dominique

Also, the WellsFeatureLayer is just from my Dynamic Layer but I added a line after the dynamic service in my XAML like this:

<esri:FeatureLayer ID="WellsFeatureLayer" Url="http://serverprd02/ArcGIS/rest/services/SilverLightDir/Wells_Timeline/MapServer/0" />
0 Kudos
DominiqueBroux
Esri Frequent Contributor
No clue.

Do you get something if you use the first version I gave that doesn't need any code:

 
<Charting:Chart>
<Charting:Chart.Series>
<Charting:ColumnSeries Title="Wind Speed" ItemsSource="{Binding ElementName=MyMap, Path=Layers[MyHurricaneFeatureLayer].Graphics}" IndependentValueBinding="{Binding Attributes[EVENTID]}" DependentValueBinding="{Binding Attributes[WINDSPEED]}"/>
</Charting:ColumnSeries>
</Charting:Chart.Series>
</Charting:Chart>
0 Kudos
JoshV
by
Regular Contributor
No clue.

Do you get something if you use the first version I gave that doesn't need any code:

 
<Charting:Chart>
<Charting:Chart.Series>
<Charting:ColumnSeries Title="Wind Speed" ItemsSource="{Binding ElementName=MyMap, Path=Layers[MyHurricaneFeatureLayer].Graphics}" IndependentValueBinding="{Binding Attributes[EVENTID]}" DependentValueBinding="{Binding Attributes[WINDSPEED]}"/>
</Charting:ColumnSeries>
</Charting:Chart.Series>
</Charting:Chart>


Hi Dominique-  Thank you again for the fast response.  I used just your code above and made some minor changes and I will post it below in case you see any problems.  First, I'm not sure if this is the issue but I published my MSD to a MapService and that MapService is what I was calling in your code below.  Do I need to publish it as more than a Mapservice because I'm not sure how the Chart will know which layer to use in my MapService.  I tried just declaring a FeatureLayer but not sure if that was the way to do it.

<esri:ArcGISDynamicMapServiceLayer ID="WellsLayer" Opacity="0.8" 
                    Url="http://serverprd02/ArcGIS/rest/services/SilverLightDir/Wells_Timeline/MapServer"
                     Initialized="ArcGISDynamicMapServiceLayer_Initialized" />


            <esri:FeatureLayer ID="WellsFeatureLayer" Url="http://serverprd02/ArcGIS/rest/services/SilverLightDir/Wells_Timeline/MapServer/0" />


Second, below is my code of small changes I made in the chart.  Any issue?  I also attached a picture of the Attribute Table showing the two columns in my Wells Layer in my MapService that I need to use for this Chart.

<charting:Chart HorizontalAlignment="Left" VerticalAlignment="Bottom">
            <charting:Chart.Series>
                <charting:ColumnSeries Title="Wind Speed" ItemsSource="{Binding ElementName=map1, Path=Layers[WellsLayer].Graphics}" IndependentValueBinding="{Binding Attributes[EOM]}" DependentValueBinding="{Binding Attributes[Adj_Close]}">
                </charting:ColumnSeries>
            </charting:Chart.Series>
        </charting:Chart>


Thoughts?  I'm sure I'm forgetting something and that's why my Chart is not drawing.  I feel this is very close to working.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
You feature layer ID is WellsFeatureLayer (not WellsLayer).

 
Path=Layers[WellsFeatureLayer].Graphics
0 Kudos