LineChart with Markers

I came across a forum post  in silverlight forums looking for a way to get markers in a linechart. I wanted to try it myself.

This is the end result. As the points are random, you might have to hit refresh, in case you dont see the lines.

charting

 

I changed the template to include a canvas

 <ControlTemplate TargetType=”charting:Chart”>
                        <Border Background=”{TemplateBinding Background}”
                                BorderBrush=”{TemplateBinding BorderBrush}”
                                BorderThickness=”{TemplateBinding BorderThickness}”
                                Padding=”10″>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height=”Auto” />
                                    <RowDefinition Height=”*” />
                                </Grid.RowDefinitions>

                                <datavis:Title Content=”{TemplateBinding Title}”
                                               Style=”{TemplateBinding TitleStyle}” />

                                <!– Use a nested Grid to avoid possible clipping behavior resulting from ColumnSpan+Width=Auto –>
                                <Grid Grid.Row=”1″
                                      Margin=”0,15,0,15″>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width=”*” />
                                        <ColumnDefinition Width=”Auto” />
                                    </Grid.ColumnDefinitions>

                                    <datavis:Legend x:Name=”Legend”
                                                    Title=”{TemplateBinding LegendTitle}”
                                                    Style=”{TemplateBinding LegendStyle}”
                                                    Grid.Column=”1″ />

                                    <Grid x:Name=”ChartArea”
                                          Style=”{TemplateBinding ChartAreaStyle}”>
                                        <Grid x:Name=”PlotArea”
                                              Style=”{TemplateBinding PlotAreaStyle}”>
                                            <Grid x:Name=”GridLinesContainer” />
                                            <Grid x:Name=”SeriesContainer”>
                                              
                                            </Grid>
                                                <Border BorderBrush=”#FF919191″
                                                    BorderThickness=”1″ />
                                             <Canvas  Background=”Transparent”                                                      
                                                         x:Name=”c1″></Canvas>
                                        </Grid>
                                      
                                    </Grid>
                                   
                                </Grid>
                            </Grid>
                        </Border>
                    </ControlTemplate>

and in the code behind once we have the chart rendered . In the Layout updated method of the chart. I call the following function. which adds the markers

  void Highlight(List<Order> orderList)
        {
             LineSeries ls = this.chart1.Series[0] as LineSeries;
             Grid plotArea = chart1.GetChildrenByType<Grid>().Where(g => g.Name == “PlotArea”).SingleOrDefault<Grid>();
             Canvas c1 = chart1.GetChildrenByType<Canvas>().Where(c => c.Name == “c1”).SingleOrDefault<Canvas>();
            foreach (Order o in orderList)
            {
                Point p = ls.Points[orders.IndexOf(o)];
                Line ln = new Line();
                ln.Stroke = new SolidColorBrush(Colors.Black);
                ln.StrokeThickness = 1.0;
                DoubleCollection dashCollection = new DoubleCollection();
                dashCollection.Add(2);
                dashCollection.Add(4);
                ln.StrokeDashArray = dashCollection;
                ln.X1 = p.X;
                ln.X2 = p.X;
                ln.Y1 = -10.0;
                ln.Y2 = plotArea.ActualHeight;
                TextBlock txt = new TextBlock();
                txt.Text = o.OrderDate.ToShortDateString();
                txt.Foreground = new SolidColorBrush(Colors.Blue);
                Grid chartArea = plotArea.Parent as Grid;
                txt.SetValue(Canvas.LeftProperty, ln.X1 + 5.0);
                txt.SetValue(Canvas.TopProperty, ln.Y1 – 10);               
                c1.Children.Add(txt);
                c1.Children.Add(ln);
            }
        }

you can download the sample here

Creating Silverlight MEWA

I started playing with live framework bits and learning a little bit. I created a silverlight MEWA.
The creation of silverlight MEWA is no different for the most part. So I wanted to work with Feeds, entries and resources
I have some samples that I have done previously. What I wanted to do is to store the XAP file, Title of the sample and some description in the entries and load the XAP file of the selected sample directly by reading the resource

SO I created a Silverlight MEWA in VisualStudio. with some basic UI with listBox to hold the list of samples and Contentcontrol to display the selected sample

For storing the data I created a feed like this after getting loading the MeshObjects

LiveOperatingEnvironment loe;
loe = new LiveOperatingEnvironment();
NetworkCredential creds = new NetworkCredential(“hotmail id”,”password”);
loe.Connect(creds);
DataFeed samples = new DataFeed(“Samples”);
loe.Mesh.MeshObjects.Entries.Where(q => q.Resource.Title == “Sample SL MEWA”).Single().DataFeeds.Add(ref samples);

Once I created a feed, I had to add some entries(1 for each sample)

//feed is the variable whch holds a reference to the feed I added

DataEntry entry = feed.DataEntries.Add(File.OpenRead(XAP filename), “ExtendedAutoCompleteBox”);
entry.Resource.SetUserData<XapData>(new XapData { Description = “This sample shows an extended Auto completebox to select multiple items”, MainDll =”Name of the dll”, StartPage = “Page”, Title = “ExtAutoCompleteBox” });
entry.Update();
feed.DataEntries.Add(ref entry);
feed.Update();

XAPData is another class I added which holds the different properties I want to access for the sample

public class XapData
    {   
        public string StartPage { get; set; }   
        public string MainDll { get; set; }   
        public string Title { get; set; }   
        public string Description { get; set; }
    }

That’s all for setting up the data to be used in the application

Now back in the Silverlight MEWA, After the MeshApp is loaded we will have access to the feeds and entries. So in the MeshAppLoaded eventhandler. I added a SelectionChanged event handler for the ListBox  and set the ItemsSource of the listbox to be the list of entries

listSamples.SelectionChanged += new SelectionChangedEventHandler(listSamples_SelectionChanged);           
DataFeed feed = meshApp.DataFeeds.Entries.First();
listSamples.ItemsSource = feed.DataEntries.Entries.ToList();

In the SelectionChanged eventhandler, we get the selected DataEntry, get the corresponding data we stored for the sample and Load the XAP file from the MediaResource

 void listSamples_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems != null && e.AddedItems.Count > 0)
            {
                entry = e.AddedItems[0] as DataEntry;
                entry.Load();
                selectedItemData = entry.Resource.GetUserData<XapData>();
                entry.ReadMediaResourceCompleted += new EventHandler<MediaResourceAsyncEventArgs>(entry_ReadMediaResourceCompleted);
                entry.ReadMediaResourceAsync(stream);
            }

Once the Resource(XAP file in this sample) is loaded, we load all the dlls in the XAP file and create an instance of the startpage for the sample

 void entry_ReadMediaResourceCompleted(object sender, MediaResourceAsyncEventArgs e)
        {
            stream.Seek(0, SeekOrigin.Begin);
            string appManifest = new StreamReader(Application.GetResourceStream(new StreamResourceInfo(stream, null), new Uri(“AppManifest.xaml”, UriKind.Relative)).Stream).ReadToEnd();
            Assembly asm = null;
            XElement deploymentRoot = XDocument.Parse(appManifest).Root;
            List<XElement> deploymentParts = (from assemblyParts in deploymentRoot.Elements().Elements()
                                              select assemblyParts).ToList();
            Assembly MyAssembly = null;
            foreach (XElement xElement in deploymentParts)
            {
                string source = xElement.Attribute(“Source”).Value;
                AssemblyPart asmPart = new AssemblyPart();

                StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(e.Result, “application/binary”), new Uri(source, UriKind.Relative));
                if (source.EndsWith(“dll”)))
                {
                    asm = asmPart.Load(streamInfo.Stream);

                    if (source == selectedItemData.MainDll)
                        MyAssembly = asm;
                }
            }

            UIElement ele = MyAssembly.CreateInstance(selectedItemData.StartPage) as UIElement;
            SampleContent.Content = ele;
        }
        }

mewa1

As the Data is stored in the sample itself, I need to share the instance of this sample. if any one is interested in sharing their sample or want to see this sample, I can send an invite if you leave a comment.