We have a heat map that has two Information Layers, one that is bound to the world map and another that is bound to the United States map. We currently default to displaying the United States map and pull down an initial data set that contains sales figures and set up a custom color mapping with that bound data. We're currently experiencing a bug that after we pull down that initial data set if we pull down another set of data with slightly different figures Texas and Indiana disappear from the map.
I'm hoping that there is just something minor that I may be doing wrong that is causing this. It's weird because depending on the data set that is returned (via the query that populates the data set) it will not always disappear. Also, Indiana doesn't always disappear, but Texas is that one that we can get to disappear on us a lot. The following code is contained inside it's own user control with the data source being set on the containing page.
Here is the XAML:
Then we have the C#:
I omitted the logic around Country populating sales data and setting the legend values because it is nearly identical to that of the state and it's also not the issue here.
I'm hoping that there is just something minor that I may be doing wrong that is causing this. It's weird because depending on the data set that is returned (via the query that populates the data set) it will not always disappear. Also, Indiana doesn't always disappear, but Texas is that one that we can get to disappear on us a lot. The following code is contained inside it's own user control with the data source being set on the containing page.
Here is the XAML:
<
UserControl
x:Class
=
"SilverlightApplication2.Blargh"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
mc:Ignorable
=
"d"
d:DesignHeight
=
"300"
d:DesignWidth
=
"400"
>
<
UserControl.Resources
>
<
ShapefileViewModel
x:Key
=
"DataContext"
Region
=
"world"
/>
<
ShapefileViewModel
x:Key
=
"DataContextUSA"
Region
=
"USA/usa_states"
/>
</
UserControl.Resources
>
<
Grid
x:Name
=
"LayoutRoot"
Background
=
"White"
HorizontalAlignment
=
"Stretch"
VerticalAlignment
=
"Stretch"
>
<
Grid.Resources
>
<
telerik:ExtendedDataConverter
x:Key
=
"ExtendedDataConverter"
/>
<
DataTemplate
x:Key
=
"CustomToolTipDataTemplate"
>
<
StackPanel
Margin
=
"10,5"
>
<
TextBlock
FontWeight
=
"Bold"
Text
=
"{Binding Converter={StaticResource ExtendedDataConverter}, ConverterParameter='CNTRY_NAME'}"
/>
<
TextBlock
Text
=
"{Binding Converter={StaticResource ExtendedDataConverter}, ConverterParameter='sales', StringFormat='Sales: ${0:#,#0.00}'}"
/>
</
StackPanel
>
</
DataTemplate
>
<
DataTemplate
x:Key
=
"CustomStateToolTipDataTemplate"
>
<
StackPanel
Margin
=
"10,5"
>
<
TextBlock
FontWeight
=
"Bold"
Text
=
"{Binding Converter={StaticResource ExtendedDataConverter}, ConverterParameter='STATE_NAME'}"
/>
<
TextBlock
Text
=
"{Binding Converter={StaticResource ExtendedDataConverter}, ConverterParameter='sales', StringFormat='Sales: ${0:#,#0.00}'}"
/>
</
StackPanel
>
</
DataTemplate
>
</
Grid.Resources
>
<
telerik:RadMap
x:Name
=
"RadMap1"
Background
=
"#374F5D"
BorderBrush
=
"Transparent"
BorderThickness
=
"0"
UseDefaultLayout
=
"False"
MouseClickMode
=
"None"
MouseDoubleClickMode
=
"None"
ZoomLevel
=
"1"
MinZoomLevel
=
"1"
MaxZoomLevel
=
"4"
HorizontalAlignment
=
"Stretch"
VerticalAlignment
=
"Stretch"
>
<
telerik:RadMap.Provider
>
<
telerik:EmptyProvider
/>
</
telerik:RadMap.Provider
>
<
telerik:InformationLayer
x:Name
=
"InformationLayer"
>
<
telerik:InformationLayer.Reader
>
<
telerik:MapShapeReader
Source
=
"{Binding Source={StaticResource DataContext}, Path=ShapefileSourceUri}"
DataSource
=
"{Binding Source={StaticResource DataContext}, Path=ShapefileDataSourceUri}"
ToolTipTemplate
=
"{StaticResource CustomToolTipDataTemplate}"
/>
</
telerik:InformationLayer.Reader
>
<
telerik:InformationLayer.Colorizer
>
<
telerik:ColorMeasureScale
x:Name
=
"CountryColorScale"
ExtendedPropertyName
=
"total_sales"
Mode
=
"Count"
TickMarkCount
=
"6"
>
<
telerik:ColorMeasureScale.ShapeFillCollection
>
<
telerik:MapShapeFill
Fill
=
"#FFFFFF"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#CDCFFD"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#888DF2"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#5159E2"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#2E35C6"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#0B1074"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
</
telerik:ColorMeasureScale.ShapeFillCollection
>
<
telerik:ColorMeasureScale.HighlightFillCollection
>
<
telerik:MapShapeFill
Fill
=
"#FFEEA6"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
</
telerik:ColorMeasureScale.HighlightFillCollection
>
</
telerik:ColorMeasureScale
>
</
telerik:InformationLayer.Colorizer
>
<
telerik:InformationLayer.ShapeFill
>
<
telerik:MapShapeFill
Fill
=
"#FFF7DE"
Stroke
=
"#5A636B"
StrokeThickness
=
"1"
/>
</
telerik:InformationLayer.ShapeFill
>
<
telerik:InformationLayer.HighlightFill
>
<
telerik:MapShapeFill
Fill
=
"#F7E7BD"
Stroke
=
"#5A636B"
StrokeThickness
=
"1"
/>
</
telerik:InformationLayer.HighlightFill
>
</
telerik:InformationLayer
>
<
telerik:InformationLayer
x:Name
=
"StateLayer"
Visibility
=
"Collapsed"
>
<
telerik:InformationLayer.Reader
>
<
telerik:MapShapeReader
Source
=
"{Binding Source={StaticResource DataContextUSA}, Path=ShapefileSourceUri}"
DataSource
=
"{Binding Source={StaticResource DataContextUSA}, Path=ShapefileDataSourceUri}"
ToolTipTemplate
=
"{StaticResource CustomStateToolTipDataTemplate}"
/>
</
telerik:InformationLayer.Reader
>
<
telerik:InformationLayer.Colorizer
>
<
telerik:ColorMeasureScale
x:Name
=
"StateColorScale"
ExtendedPropertyName
=
"total_sales"
Mode
=
"Count"
TickMarkCount
=
"6"
>
<
telerik:ColorMeasureScale.ShapeFillCollection
>
<
telerik:MapShapeFill
Fill
=
"#FFFFFF"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#CDCFFD"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#888DF2"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#5159E2"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#2E35C6"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
<
telerik:MapShapeFill
Fill
=
"#0B1074"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
</
telerik:ColorMeasureScale.ShapeFillCollection
>
<
telerik:ColorMeasureScale.HighlightFillCollection
>
<
telerik:MapShapeFill
Fill
=
"#FFEEA6"
Stroke
=
"#1F287A"
StrokeThickness
=
"1"
/>
</
telerik:ColorMeasureScale.HighlightFillCollection
>
</
telerik:ColorMeasureScale
>
</
telerik:InformationLayer.Colorizer
>
<
telerik:InformationLayer.ShapeFill
>
<
telerik:MapShapeFill
Fill
=
"#FFF7DE"
Stroke
=
"#5A636B"
StrokeThickness
=
"1"
/>
</
telerik:InformationLayer.ShapeFill
>
<
telerik:InformationLayer.HighlightFill
>
<
telerik:MapShapeFill
Fill
=
"#F7E7BD"
Stroke
=
"#5A636B"
StrokeThickness
=
"1"
/>
</
telerik:InformationLayer.HighlightFill
>
</
telerik:InformationLayer
>
</
telerik:RadMap
>
<
telerik:MapLegend
x:Name
=
"InformationLayerLegend"
MarkerSize
=
"40,20"
VerticalAlignment
=
"Bottom"
HorizontalAlignment
=
"Right"
Margin
=
"0,0,10,10"
Format
=
"{}{0:0,,.00}"
LabelLayout
=
"Center"
Layer
=
"{Binding ElementName=InformationLayer}"
>
<
telerik:MapLegend.Header
>
<
TextBlock
Margin
=
"10,0,0,0"
>
<
Run
FontSize
=
"16"
FontWeight
=
"ExtraBlack"
>Sales</
Run
>
<
Run
FontSize
=
"14"
>(in millions)</
Run
>
</
TextBlock
>
</
telerik:MapLegend.Header
>
</
telerik:MapLegend
>
<
telerik:MapLegend
x:Name
=
"StateLayerLegend"
MarkerSize
=
"40,20"
Visibility
=
"Collapsed"
VerticalAlignment
=
"Bottom"
HorizontalAlignment
=
"Right"
Margin
=
"0,0,10,10"
Format
=
"{}{0:0,,.00}"
LabelLayout
=
"Center"
Layer
=
"{Binding ElementName=StateLayer}"
>
<
telerik:MapLegend.Header
>
<
TextBlock
Margin
=
"10,0,0,0"
>
<
Run
FontSize
=
"16"
FontWeight
=
"ExtraBlack"
>Sales</
Run
>
<
Run
FontSize
=
"14"
>(in millions)</
Run
>
</
TextBlock
>
</
telerik:MapLegend.Header
>
</
telerik:MapLegend
>
</
Grid
>
</
UserControl
>
Then we have the C#:
using
Telerik.Windows.Controls.Map;
namespace
SilverlightApplication2
{
public
partial
class
Blargh : UserControl
{
private
bool
initialized;
private
const
string
SalesDataField =
"sales"
;
public
Blargh()
{
InitializeComponent();
RadMap1.InitializeCompleted +=
new
EventHandler(RadMap1_InitializeCompleted);
}
public
DependencyProperty RegionProperty = DependencyProperty.Register(
"Region"
,
typeof
(
string
),
typeof
(Blargh),
new
PropertyMetadata(
"All"
,
new
PropertyChangedCallback(OnRegionPropertyChanged)));
private
static
void
OnRegionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var current = d
as
Blargh;
if
(current.Region ==
"All"
)
{
current.InformationLayer.Visibility = Visibility.Visible;
current.InformationLayerLegend.Visibility = Visibility.Visible;
current.StateLayer.Visibility = Visibility.Collapsed;
current.StateLayerLegend.Visibility = Visibility.Collapsed;
current.SetZoom();
current.RadMap1.Center =
new
Location(38.138254674708641, 24.156992308937237);
}
else
if
(current.Region ==
"USA"
)
{
current.InformationLayer.Visibility = Visibility.Collapsed;
current.InformationLayerLegend.Visibility = Visibility.Collapsed;
current.StateLayer.Visibility = Visibility.Visible;
current.StateLayerLegend.Visibility = Visibility.Visible;
current.SetZoom();
current.RadMap1.Center =
new
Location(38.138254674708683, -95.374257691063036);
}
}
public
string
Region
{
get
{
return
(
string
)GetValue(RegionProperty); }
set
{ SetValue(RegionProperty, value); }
}
private
ObservableCollection<Sales> _DataSource =
new
ObservableCollection<Sales>();
public
ObservableCollection<Sales> DataSource
{
get
{
return
_DataSource; }
set
{
_DataSource = value;
InformationLayer.Reader.Read();
StateLayer.Reader.Read();
}
}
void
RadMap1_InitializeCompleted(
object
sender, EventArgs e)
{
if
(!
this
.initialized)
{
this
.initialized =
true
;
if
(InformationLayer.Reader.ExtendedPropertySet ==
null
)
InformationLayer.Reader.ExtendedPropertySet =
new
ExtendedPropertySet();
if
(InformationLayer.Reader.ExtendedPropertySet !=
null
)
{
ExtendedPropertySet propertySet = InformationLayer.Reader.ExtendedPropertySet;
propertySet.RegisterProperty(
"CNTRY_NAME"
,
string
.Empty,
typeof
(
string
),
string
.Empty);
propertySet.RegisterProperty(SalesDataField,
string
.Empty,
typeof
(
decimal
), (
decimal
)0);
}
this
.InformationLayer.Reader.PreviewReadCompleted +=
new
PreviewReadShapesCompletedEventHandler(CountryReader_PreviewReadCompleted);
this
.InformationLayer.Reader.ReadCompleted +=
new
ReadShapesCompletedEventHandler(CountryReader_ReadCompleted);
if
(StateLayer.Reader.ExtendedPropertySet ==
null
)
StateLayer.Reader.ExtendedPropertySet =
new
ExtendedPropertySet();
if
(StateLayer.Reader.ExtendedPropertySet !=
null
)
{
ExtendedPropertySet propertySet = StateLayer.Reader.ExtendedPropertySet;
propertySet.RegisterProperty(
"STATE_NAME"
,
string
.Empty,
typeof
(
string
),
string
.Empty);
propertySet.RegisterProperty(SalesDataField,
string
.Empty,
typeof
(
decimal
), (
decimal
)0);
}
StateLayer.Reader.PreviewReadCompleted +=
new
PreviewReadShapesCompletedEventHandler(StateReader_PreviewReadCompleted);
StateLayer.Reader.ReadCompleted +=
new
ReadShapesCompletedEventHandler(StateReader_ReadCompleted);
}
}
void
StateReader_PreviewReadCompleted(
object
sender, PreviewReadShapesCompletedEventArgs eventArgs)
{
if
(eventArgs.Error ==
null
)
{
foreach
(MapShape shape
in
eventArgs.Items)
{
this
.SetAdditionalStateData(shape);
}
var colorizer =
this
.StateLayer.Colorizer
as
ColorMeasureScale;
colorizer.SetColorByExtendedData(eventArgs.Items, SalesDataField,
true
);
}
}
void
StateReader_ReadCompleted(
object
sender, ReadShapesCompletedEventArgs eventArgs)
{
List<
double
> values =
new
List<
double
>();
foreach
(var state
in
DataSource.Select(State).Distinct())
{
var sales = DataSource.Where(State).Sum(sales);
values.Add(Convert.ToDouble(sales));
}
if
(values.Count > 0 && values.Count >= 4)
{
//Uses Mean and Standard Deiviation to Set Map Legend Ranges -- Omitted for Space
}
else
{
StateColorScale.MaxValue = (values.Count > 0 ? values.Max() : 0);
StateColorScale.MinValue = 0;
}
}
private
void
SetAdditionalStateData(MapShape shape)
{
ExtendedData extendedData = shape.ExtendedData;
if
(extendedData !=
null
)
{
string
stateName = (
string
)shape.ExtendedData.GetValue(
"STATE_NAME"
);
decimal
dValue = GetSalesByState(stateName);
if
(dValue > 0)
shape.ExtendedData.SetValue(SalesDataField, dValue);
}
}
private
decimal
GetSalesByState(
string
State)
{
if
(DataSource.Count > 0)
{
return
DataSource.Where(State).Sum(sales);
}
return
(
decimal
)0;
}
}
}
I omitted the logic around Country populating sales data and setting the legend values because it is nearly identical to that of the state and it's also not the issue here.