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
- Do not know number of charts.
- Layout has to be designed at runtime.
- Screen renders white background until all charts are loaded.
Solution
- The main page will just have a
StackPanel
where all charts would be loaded.
- Create a grid dynamically with number of rows and columns set dynamically.
- 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.
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;
Grid dynamicGrid = new Grid();
for (int i = 0; i < rowCount; i++)
{
RowDefinition objRowDefinition = new RowDefinition();
objRowDefinition.Height = GridLength.Auto;
dynamicGrid.RowDefinitions.Add(objRowDefinition);
}
for (int i = 0; i < coulmnCount; i++)
{
ColumnDefinition objColumnDefinition = new ColumnDefinition();
objColumnDefinition.Width = GridLength.Auto;
dynamicGrid.ColumnDefinitions.Add(objColumnDefinition);
}
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);
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];
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.