Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Loading multiple charts dynamically

0.00/5 (No votes)
30 Mar 2012 1  
How to dynamically load multiple charts in Silverlight.

Introduction

This article will cover how to dynamically load multiple charts in Silverlight. This is similar to the dashboard concept where you would want to load multiple charts on the same page. The following sections will cover the issues I faced while development and some of the solutions I figured out during the process.

Issues While Loading Multiple Charts Dynamically

  1. Do not know number of charts.
  2. Layout has to be designed at runtime.
  3. Screen renders white background until all charts are loaded.

Solution

  1. The main page will just have a StackPanel where all charts would be loaded.
  2. Create a grid dynamically with number of rows and columns set dynamically.
  3. Instantiate the Chart user control and add it to the cell. This user control can have public properties/constructor through which you can pass the data series from the main page.

338217/3.png

338217/4.png

Main Page XAML

<scrollviewer grid.row="1" grid.column="0" 
       horizontalscrollbarvisibility="Auto" borderbrush="Transparent"
       borderthickness="0" height="Auto">
    <stackpanel horizontalalignment="Stretch" orientation="Vertical" name="MainPanel" />
        </stackpanel />
</scrollviewer />

Main Page Code-Behind

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    LoadCharts();
}

private void LoadCharts()
{
    int rowCount = 2;
    int coulmnCount = 2;

    //dynamic grid
    Grid dynamicGrid = new Grid();

    //Rows
    for (int i = 0; i < rowCount; i++)
    {
        RowDefinition objRowDefinition = new RowDefinition();
        objRowDefinition.Height = GridLength.Auto;
        dynamicGrid.RowDefinitions.Add(objRowDefinition);
    }

    //Coulmn count
    for (int i = 0; i < coulmnCount; i++)
    {
        ColumnDefinition objColumnDefinition = new ColumnDefinition();
        objColumnDefinition.Width = GridLength.Auto;
        dynamicGrid.ColumnDefinitions.Add(objColumnDefinition);
    }

    //Add charts dynamically
    for (int i = 0; i < rowCount; i++)
    {
        for (int j = 0; j < coulmnCount; j++)
        {
            StackPanel cellStackPanel = new StackPanel();
            cellStackPanel.Orientation = Orientation.Horizontal;
            cellStackPanel.SetValue(Grid.RowProperty, i);
            cellStackPanel.SetValue(Grid.ColumnProperty, j);

            //You can enhance Chart constuctor to take data series. 
            UCChart chart1 = new UCChart(1, 1000);
            cellStackPanel.Children.Add(chart1);
            dynamicGrid.Children.Add(cellStackPanel);
        }
    }
    MainPanel.Children.Add(dynamicGrid);
}

Chart User Control XAML

<chartingtoolkit:chart name="scatterChart" height="400" width="500">
    <chart.series>
        <scatterseries title="Series 1" name="series1" 
            independentvaluebinding="{Binding SerialNumber}" 
            dependentvaluebinding="{Binding Value}" />
    </chart.series />

Chart User Control Code-behind

public partial class UCChart : UserControl
{
    private Random random = new Random(20110810);
    private int _fromCount;
    private int _toCount;
    private delegate void AssignDataSeriesDelegate(
            ScatterSeries series, StackPanel spPanelProgress);

    public UCChart()
    {
        InitializeComponent();
    }

    public UCChart(int fromCount, int toCount)
    {
        _fromCount = fromCount;
        _toCount = toCount;
        InitializeComponent();
    }

    private List <datapoint> GenerateDataPoints(int from, int to)
    {
        List<datapoint /> dataPoints = new List<datapoint />();

        for (int i = _fromCount; i <= _toCount; i++)
        {
            dataPoints.Add(new DataPoint { SerialNumber = i, Value = (random.NextDouble() / 2) });
        }
        return dataPoints;
    }

    private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
    {
        CallAsync();
    }

    private void CallAsync()
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerAsync();
    }

    void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        Dispatcher.BeginInvoke(new AssignDataSeriesDelegate(AssignDataSeries), 
                  (ScatterSeries)scatterChart.Series[0], spPanelProgress);
    }

    private void AssignDataSeries(ScatterSeries series, StackPanel spPanelProgress)
    {
        spPanelProgress.Visibility = System.Windows.Visibility.Visible;
        ScatterSeries series1 = (ScatterSeries)scatterChart.Series[0];
        // Generate the random data points for the series
        series1.ItemsSource = GenerateDataPoints(1, 6000);
        spPanelProgress.Visibility = System.Windows.Visibility.Collapsed;
    }
}

Conclusion

This article does not cover data retrieval from the database and chart creation at runtime even though it was implemented in my project. I wanted to keep things simpler for this article. There could be other ways for improving this, please put in your comments.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here