David Brubacher
Top achievements
Rank 1
David Brubacher
asked on 12 Aug 2010, 04:11 PM
I have a bubble chart with two data series. I've bound ItemSource to a property of type ObservableCollection<ObservableCollection<MyClass>> which lives in the view model. Furthermore all this gets hooked up using MEF so my code behind only wires things up and sets the data context. One exception today is that I've done most chart setup in the codebehind constructor (axis titles, series mapping, item mapping, etc.) I'm moving it to XAML right now.
The chart lives in a non-modal radwindow so that when the user changes things in the main display, the chart updates through a messaging system (Galasoft.MvvmLight.Messaging).
When the chart is first displayed the chart data displays fine. As soon as my main app makes an update, the chart displays 'no data in series'. All I'm doing is changing values in the observablecollection, which should cause the data to simply change.
I can capture propertychanged events in the code behind and cause a chart.rebind, which works but is far from ideal.
Does anyone know what's missing? Why don't the bubbles simply change as the collection changes?
I'm using version 2010.2.806.1040
P.S. I came across an extension to the ObservableCollection that suppresses changes, allowing you to bulk modify but can't find it now. Can anyone point it out? Thanks!
The chart lives in a non-modal radwindow so that when the user changes things in the main display, the chart updates through a messaging system (Galasoft.MvvmLight.Messaging).
When the chart is first displayed the chart data displays fine. As soon as my main app makes an update, the chart displays 'no data in series'. All I'm doing is changing values in the observablecollection, which should cause the data to simply change.
I can capture propertychanged events in the code behind and cause a chart.rebind, which works but is far from ideal.
Does anyone know what's missing? Why don't the bubbles simply change as the collection changes?
I'm using version 2010.2.806.1040
P.S. I came across an extension to the ObservableCollection that suppresses changes, allowing you to bulk modify but can't find it now. Can anyone point it out? Thanks!
3 Answers, 1 is accepted
0
David Brubacher
Top achievements
Rank 1
answered on 12 Aug 2010, 04:17 PM
Just tried something different.
Instead of clearing the outer collection when all data changes (as opposed to just one bubble changing) and then making new collections and adding them back in, I'm clearing the inner collections and adding MyClass objects back in.
eg:
Instead of clearing the outer collection when all data changes (as opposed to just one bubble changing) and then making new collections and adding them back in, I'm clearing the inner collections and adding MyClass objects back in.
eg:
var selected = ScenarioPoints[0];
selected.Clear();
var unSelected = ScenarioPoints[1];
unSelected.Clear();
The chart no longer goes to 'No data in series' but the bubbles don't move.
0
David Brubacher
Top achievements
Rank 1
answered on 12 Aug 2010, 04:20 PM
And here is the chart setup in code-behind
// setup the basic chart look and feel
chart.DefaultView.ChartArea.AxisY.AutoRange = true;
chart.DefaultView.ChartArea.AxisY.Step = 5;
chart.DefaultView.ChartArea.AxisY.Title = "Change in Mean Annual Precipitation (%)";
chart.DefaultView.ChartArea.AxisX.AutoRange = true;
chart.DefaultView.ChartArea.AxisX.Step = 1;
chart.DefaultView.ChartArea.AxisX.MinorTicksVisibility = Visibility.Visible;
chart.DefaultView.ChartArea.AxisX.StripLinesVisibility = Visibility.Visible;
chart.DefaultView.ChartArea.AxisX.Title = "Change in Mean Annual Temperature (°C)";
chart.DefaultView.ChartLegend.Visibility = Visibility.Collapsed;
chart.DefaultView.ChartArea.EnableAnimations = false;
// create the series to hold selected points
var selectedMapping = new SeriesMapping
{
SeriesDefinition = new BubbleSeriesDefinition
{
Appearance =
{
Fill = new SolidColorBrush(Color.FromArgb(80, 0, 0, 255))
},
BubbleSizeRelative = false,
ShowItemToolTips = true
},
CollectionIndex = 1
};
selectedMapping.ItemMappings.Add(new ItemMapping("Precipitation", DataPointMember.YValue));
selectedMapping.ItemMappings.Add(new ItemMapping("Temperature", DataPointMember.XValue));
selectedMapping.ItemMappings.Add(new ItemMapping("Size", DataPointMember.BubbleSize));
selectedMapping.ItemMappings.Add(new ItemMapping("Name", DataPointMember.Tooltip));
chart.SeriesMappings.Add(selectedMapping);
// create the series to hold unselected points
var unselectedMapping = new SeriesMapping
{
SeriesDefinition = new BubbleSeriesDefinition
{
Appearance =
{
Fill = new SolidColorBrush(Color.FromArgb(200, 255, 255, 141)),
Stroke = new SolidColorBrush(Color.FromArgb(200, 255, 188, 50)),
StrokeThickness = 2
},
BubbleSizeRelative = false,
ShowItemToolTips = true
},
CollectionIndex = 0
};
unselectedMapping.ItemMappings.Add(new ItemMapping("Precipitation", DataPointMember.YValue));
unselectedMapping.ItemMappings.Add(new ItemMapping("Temperature", DataPointMember.XValue));
unselectedMapping.ItemMappings.Add(new ItemMapping("Size", DataPointMember.BubbleSize));
unselectedMapping.ItemMappings.Add(new ItemMapping("Name", DataPointMember.Tooltip));
chart.SeriesMappings.Add(unselectedMapping);
0
David Brubacher
Top achievements
Rank 1
answered on 13 Aug 2010, 02:52 PM
Working with 2010.2.812 has pretty much cleared everything up. The rebinding still has to happen in the code behind but performance is good. Here is the XAML and code behind in case anyone is interested. Everything I did was found in the help and in forum posts but it took some real searching. Hopefully someone can learn from this more complex example. The data source is a much lighter weight collection of collections.
ScenarioPoints = new Collection<Collection<ChartPoint>>();
<UserControl x:Class="deleted.Client.Views.ChartView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="450"
xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Charting"
xmlns:Charting="clr-namespace:Telerik.Windows.Controls.Charting;assembly=Telerik.Windows.Controls.Charting">
<Grid>
<telerik:RadChart ItemsSource="{Binding ScenarioPoints}" x:Name="chart" >
<telerik:RadChart.SeriesMappings>
<Charting:SeriesMapping x:Name="selected" CollectionIndex = "1">
<Charting:SeriesMapping.SeriesDefinition >
<Charting:BubbleSeriesDefinition BubbleSizeRelative="False"
ShowItemToolTips="True">
<Charting:BubbleSeriesDefinition.Appearance>
<Charting:SeriesAppearanceSettings Fill="#500000FF" />
</Charting:BubbleSeriesDefinition.Appearance>
</Charting:BubbleSeriesDefinition>
</Charting:SeriesMapping.SeriesDefinition>
<Charting:SeriesMapping.ItemMappings>
<Charting:ItemMapping FieldName="Precipitation" DataPointMember="YValue" />
<Charting:ItemMapping FieldName="Temperature" DataPointMember="XValue" />
<Charting:ItemMapping FieldName="Size" DataPointMember="BubbleSize" />
<Charting:ItemMapping FieldName="Name" DataPointMember="Tooltip" />
</Charting:SeriesMapping.ItemMappings>
</Charting:SeriesMapping>
<Charting:SeriesMapping x:Name="unSelected" CollectionIndex = "0">
<Charting:SeriesMapping.SeriesDefinition >
<Charting:BubbleSeriesDefinition BubbleSizeRelative="False"
ShowItemToolTips="True">
<Charting:BubbleSeriesDefinition.Appearance>
<Charting:SeriesAppearanceSettings
Fill="#C8FFFF8D" Stroke="#C8FFBC32" StrokeThickness="2"/>
</Charting:BubbleSeriesDefinition.Appearance>
</Charting:BubbleSeriesDefinition>
</Charting:SeriesMapping.SeriesDefinition>
<Charting:SeriesMapping.ItemMappings>
<Charting:ItemMapping FieldName="Precipitation" DataPointMember="YValue" />
<Charting:ItemMapping FieldName="Temperature" DataPointMember="XValue" />
<Charting:ItemMapping FieldName="Size" DataPointMember="BubbleSize" />
<Charting:ItemMapping FieldName="Name" DataPointMember="Tooltip" />
</Charting:SeriesMapping.ItemMappings>
</Charting:SeriesMapping>
</telerik:RadChart.SeriesMappings>
<telerik:RadChart.DefaultView>
<Charting:ChartDefaultView>
<Charting:ChartDefaultView.ChartArea>
<Charting:ChartArea EnableAnimations="False" NoDataString="No Scenario Selected">
<Charting:ChartArea.AxisY>
<Charting:AxisY AutoRange="True" Step="5"
Title="Change in Mean Annual Precipitation (%)" />
</Charting:ChartArea.AxisY>
<Charting:ChartArea.AxisX>
<Charting:AxisX AutoRange="True" Step="1"
Title="Change in Mean Annual Temperature (°C)"
MinorTicksVisibility="Visible" StripLinesVisibility="Visible" />
</Charting:ChartArea.AxisX>
</Charting:ChartArea>
</Charting:ChartDefaultView.ChartArea>
<Charting:ChartDefaultView.ChartLegend>
<Charting:ChartLegend Visibility="Collapsed" />
</Charting:ChartDefaultView.ChartLegend>
<Charting:ChartDefaultView.ChartTitle>
<Charting:ChartTitle HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid Margin="-2,-10,0,-15">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="250" Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2"
VerticalAlignment="Center" Margin="0,0,20,0" Foreground="#FF1E395B" />
<TextBlock Text="Baseline:" Grid.Column="1" Grid.Row="0" FontSize="12" Foreground="#FF1E395B" />
<TextBlock Text="Future:" Grid.Column="1" Grid.Row="1" FontSize="12" Foreground="#FF1E395B" HorizontalAlignment="Right" />
<TextBlock Text="{Binding Baseline}" Grid.Column="2" Grid.Row="0" FontSize="12" Foreground="#FF1E395B" Margin="4,0,0,0" />
<TextBlock Text="{Binding Future}" Grid.Column="2" Grid.Row="1" FontSize="12" Foreground="#FF1E395B" Margin="4,0,0,0" />
</Grid>
</Charting:ChartTitle>
</Charting:ChartDefaultView.ChartTitle>
</Charting:ChartDefaultView>
</telerik:RadChart.DefaultView>
</telerik:RadChart>
</Grid>
</UserControl>
/// <summary>
/// Provide a view of ranked models in a chart
/// </summary>
public partial class ChartView
{
/// <summary>
/// Create a new instance of the chart
/// </summary>
public ChartView()
{
InitializeComponent();
if (!ViewModelBase.IsInDesignModeStatic)
CompositionInitializer.SatisfyImports(this);
}
/// <summary>
/// Set the view model this view is bound to
/// </summary>
[Import(ViewModelTypes.ChartViewModel)]
public object ViewModel
{
set
{
DataContext = value;
((ChartViewModel)DataContext).PropertyChanged += ChartViewPropertyChanged;
}
}
/// <summary>
/// Handle changes to the chart points
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ChartViewPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "ScenarioPoints")
chart.Rebind();
}
}