Blog author:
Niladri.Biswas | Posted on: 7/10/2012 | Category:
WPF Blogs | Views: 1541 | Status:
[Member] |
Points: 75
|
Alert Moderator
Download source file
What is Heat Map?
A heat map is a graphical representation of data where the values taken by a variable in a two-dimensional table are represented as colors(Adopted from Wikipedia)
How to make a Heat Map Control in WPF?
Step 1: Create a class library project say, HeapMap
Step 2: Add the below references
- PresentationCore
- PresentationFramework
- System.Xaml
- WindowsBase

Step 3: Create a class say HeatMapControl.cs and the class should inherit the Grid Class(which is in System.Windows.Controls namespace)
public class HeatMapControl:Grid
Step 4: Expose a property where we can assign the source data
public DataTable HeatMapSource
{
get;
set;
}
Step 5: Now we need to create the chart
The chart will be created by using the following sequence
private void CreatHeatMap()
{
//Assign the legend units
AssignLegendUnits();
//Create Column Header
CreateColumnHeaders();
//Create Row Header
CreateRowHeaders();
//Create the chart
CreateChart();
//Display the units
DisplayUnits();
}
In the AssignLegendUnits function, we basically say as what the colors indicates
private void AssignLegendUnits()
{
Double _maxValue = 0.0;
Double _unitRange;
_maxValue = GetMaxValue(HeatMapSource);
_unitRange = _maxValue / 4;
_firstUnit = _unitRange;
_firstLegendText = "Less than " + _firstUnit;
_secondUnit = _firstUnit + _unitRange;
_secondLegendText = "Between " + _firstUnit + " And " + _secondUnit;
_thirdUnit = _secondUnit + _unitRange;
_thirdLegendText = "Between " + _secondUnit + " And " + _thirdUnit;
_fourthUnit = _thirdUnit + _unitRange;
_fourthLegendText = "Between " + _thirdUnit + " And " + _fourthUnit;
}
This uses GetMaxValue function for determining the maximum value from all the columns of the data table
private Double GetMaxValue(DataTable dtChartData)
{
Double maxValue = 0.0;
foreach (DataColumn dc in dtChartData.Columns)
{
if (dc.Ordinal > 0)
{
string columnName = dc.ColumnName;
string max = dtChartData.Compute("Max([" + columnName + "])", "").ToString();
if (!string.IsNullOrEmpty(max))
{
if (maxValue < Convert.ToDouble(dtChartData.Compute("Max([" + columnName + "])", "")))
maxValue = Convert.ToDouble(dtChartData.Compute("Max([" + columnName + "])", ""));
}
}
}
return maxValue;
}
In the CreateColumnHeaders function, we create the column headers
private void CreateColumnHeaders()
{
int columnIndex = 0;
foreach (DataColumn dc in HeatMapSource.Columns)
{
ColumnDefinition cd = new ColumnDefinition();
cd.Width = GridLength.Auto;
this.ColumnDefinitions.Add(cd);
Label lbl = new Label();
lbl.FontSize = 10;
if (dc.Ordinal != 0)
{
lbl.Content = dc.ColumnName;
RotateTransform rt = new RotateTransform();
rt.Angle = -90;
lbl.LayoutTransform = rt;
}
lbl.Background = Brushes.Transparent;
lbl.BorderBrush = Brushes.Black;
Grid.SetRow(lbl, 0);
Grid.SetColumn(lbl, columnIndex);
this.Children.Add(lbl);
columnIndex++;
}
}
We create the row headers in CreateRowHeaders function
private void CreateRowHeaders()
{
RowDefinition defaultRow = new RowDefinition();
defaultRow.Height = GridLength.Auto;
this.RowDefinitions.Add(defaultRow);
int rowIndex = 0;
foreach (DataRow dr in HeatMapSource.Rows)
{
RowDefinition rd = new RowDefinition();
rd.Height = new GridLength(19, GridUnitType.Pixel);
rd.Height = GridLength.Auto;
this.RowDefinitions.Add(rd);
Label rowHeader = new Label();
rowHeader.FontSize = 9;
rowHeader.VerticalContentAlignment = VerticalAlignment.Stretch;
rowHeader.Content = dr[0].ToString();
rowHeader.Background = Brushes.Transparent;
Grid.SetRow(rowHeader, rowIndex + 1);
Grid.SetColumn(rowHeader, 0);
this.Children.Add(rowHeader);
rowIndex++;
}
}
Once all these basic operations are set up properly, next we can create the chart which is being done in CreateChart function. And in this function, based on the weight we assign the colors also.
private void CreateChart()
{
//Set the Thickness for each of the label
System.Windows.Thickness th = new Thickness(0.3, 0.3, 0.3, 0.3);
int rowIndex = 1;
int columnIndex = 1;
foreach (DataRow dr in HeatMapSource.Rows)
{
columnIndex = 1;
foreach (DataColumn dc in HeatMapSource.Columns)
{
if (dc.Ordinal != 0)
{
string cellValue = dr[dc.ColumnName].ToString();
Label lbl = new Label();
//set the label properties
lbl.Width = 27;
lbl.BorderThickness = th;
lbl.BorderBrush = Brushes.Black;
if (string.IsNullOrEmpty(cellValue))
{
lbl.Background = Brushes.Transparent;
}
else
{
//Depends on the value assign the color
//First legend color
if (Convert.ToDouble(cellValue) > 0.0 && Convert.ToDouble(cellValue) < _firstUnit)
{
lbl.Background = Brushes.Moccasin;
}
//Second legend color
else if (Convert.ToDouble(cellValue) > _firstUnit && Convert.ToDouble(cellValue) <= _secondUnit)
{
lbl.Background = Brushes.BurlyWood;
}
//Third legend color
else if (Convert.ToDouble(cellValue) > _secondUnit && Convert.ToDouble(cellValue) <= _thirdUnit)
{
lbl.Background = Brushes.Chocolate;
}
//Fourth Legend color
else if (Convert.ToDouble(cellValue) > _thirdUnit && Convert.ToDouble(cellValue) <= _fourthUnit)
{
lbl.Background = Brushes.SaddleBrown;
}
}
Grid.SetRow(lbl, rowIndex);
Grid.SetColumn(lbl, columnIndex);
this.Children.Add(lbl);
columnIndex++;
}
}
rowIndex++;
}
}
Finally we display the meaing of every unit in the DisplayUnits function
private void DisplayUnits()
{
RowDefinition spaceRow = new RowDefinition();
spaceRow.Height = new GridLength(20, GridUnitType.Pixel);
this.RowDefinitions.Add(spaceRow);
RowDefinition legendRow = new RowDefinition();
legendRow.Height = GridLength.Auto;
this.RowDefinitions.Add(legendRow);
if (HeatMapSource.Rows.Count > 0 && HeatMapSource.Columns.Count > 0)
{
#region First Legend
Grid grCh = new Grid();
Grid.SetRow(grCh, HeatMapSource.Rows.Count + 2);
Grid.SetColumn(grCh, 0);
Grid.SetColumnSpan(grCh, HeatMapSource.Columns.Count - 1);
this.Children.Add(grCh);
ColumnDefinition grColm1 = new ColumnDefinition();
grColm1.Width = new GridLength(20);
grCh.ColumnDefinitions.Add(grColm1);
ColumnDefinition grColm2 = new ColumnDefinition();
grColm2.Width = GridLength.Auto;
grCh.ColumnDefinitions.Add(grColm2);
ColumnDefinition grColm3 = new ColumnDefinition();
grCh.ColumnDefinitions.Add(grColm3);
RowDefinition grRow1 = new RowDefinition();
grCh.RowDefinitions.Add(grRow1);
Label lblLegendFirst = new Label();
lblLegendFirst.Background = Brushes.Moccasin;
lblLegendFirst.Width = 30;
Grid.SetRow(lblLegendFirst, 0);
Grid.SetColumn(lblLegendFirst, 1);
grCh.Children.Add(lblLegendFirst);
Label lblLegendText = new Label();
lblLegendText.Content = this._firstLegendText;
lblLegendText.FontSize = 10;
lblLegendText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendText, 0);
Grid.SetColumn(lblLegendText, 2);
grCh.Children.Add(lblLegendText);
#endregion
#region Sec Legend
RowDefinition legendSecondRow = new RowDefinition();
legendSecondRow.Height = new GridLength(20);
this.RowDefinitions.Add(legendSecondRow);
Grid grLegendSec = new Grid();
Grid.SetRow(grLegendSec, HeatMapSource.Rows.Count + 3);
Grid.SetColumn(grLegendSec, 0);
Grid.SetColumnSpan(grLegendSec, HeatMapSource.Columns.Count - 1);
ColumnDefinition grLegendSecCol1 = new ColumnDefinition();
grLegendSecCol1.Width = new GridLength(20);
grLegendSec.ColumnDefinitions.Add(grLegendSecCol1);
ColumnDefinition grLegendSecCol2 = new ColumnDefinition();
grLegendSecCol2.Width = GridLength.Auto;
grLegendSec.ColumnDefinitions.Add(grLegendSecCol2);
ColumnDefinition grLegendSecCol3 = new ColumnDefinition();
grLegendSec.ColumnDefinitions.Add(grLegendSecCol3);
RowDefinition grLegendSecRow1 = new RowDefinition();
grLegendSec.RowDefinitions.Add(grLegendSecRow1);
Label lblLegendSec = new Label();
lblLegendSec.Background = Brushes.BurlyWood;
lblLegendSec.Width = 30;
Grid.SetRow(lblLegendSec, 0);
Grid.SetColumn(lblLegendSec, 1);
grLegendSec.Children.Add(lblLegendSec);
Label lblLegendSecText = new Label();
lblLegendSecText.Content = this._secondLegendText;
lblLegendSecText.FontSize = 10;
lblLegendSecText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendSecText, 0);
Grid.SetColumn(lblLegendSecText, 2);
grLegendSec.Children.Add(lblLegendSecText);
this.Children.Add(grLegendSec);
#endregion
#region Third Legend
RowDefinition legendThirdRow = new RowDefinition();
legendThirdRow.Height = GridLength.Auto;
this.RowDefinitions.Add(legendThirdRow);
Grid grLegendThrid = new Grid();
Grid.SetRow(grLegendThrid, HeatMapSource.Rows.Count + 4);
Grid.SetColumn(grLegendThrid, 0);
Grid.SetColumnSpan(grLegendThrid, HeatMapSource.Columns.Count - 1);
this.Children.Add(grLegendThrid);
ColumnDefinition grLegendThirdCol1 = new ColumnDefinition();
grLegendThirdCol1.Width = new GridLength(20);
grLegendThrid.ColumnDefinitions.Add(grLegendThirdCol1);
ColumnDefinition grLegendThirdCol2 = new ColumnDefinition();
grLegendThirdCol2.Width = GridLength.Auto;
grLegendThrid.ColumnDefinitions.Add(grLegendThirdCol2);
ColumnDefinition grLegendThirdCol3 = new ColumnDefinition();
grLegendThrid.ColumnDefinitions.Add(grLegendThirdCol3);
RowDefinition grLegendThridRow1 = new RowDefinition();
grLegendThrid.RowDefinitions.Add(grLegendThridRow1);
Label lblLegendThird = new Label();
lblLegendThird.Width = 30;
lblLegendThird.Background = Brushes.Chocolate;
Grid.SetRow(lblLegendThird, 3);
Grid.SetColumn(lblLegendThird, 1);
grLegendThrid.Children.Add(lblLegendThird);
Label lblLegendThirdText = new Label();
lblLegendThirdText.Content = this._thirdLegendText;
lblLegendThirdText.FontSize = 10;
lblLegendThirdText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendThirdText, 3);
Grid.SetColumn(lblLegendThirdText, 2);
grLegendThrid.Children.Add(lblLegendThirdText);
#endregion
#region Fourth Legend
RowDefinition legendFourthRow = new RowDefinition();
legendFourthRow.Height = GridLength.Auto;
this.RowDefinitions.Add(legendFourthRow);
Grid grLegendFourth = new Grid();
Grid.SetRow(grLegendFourth, HeatMapSource.Rows.Count + 5);
Grid.SetColumn(grLegendFourth, 0);
Grid.SetColumnSpan(grLegendFourth, HeatMapSource.Columns.Count - 1);
this.Children.Add(grLegendFourth);
ColumnDefinition grLegendFourthCol1 = new ColumnDefinition();
grLegendFourthCol1.Width = new GridLength(20);
grLegendFourth.ColumnDefinitions.Add(grLegendFourthCol1);
ColumnDefinition grLegendFourthCol2 = new ColumnDefinition();
grLegendFourthCol2.Width = GridLength.Auto;
grLegendFourth.ColumnDefinitions.Add(grLegendFourthCol2);
ColumnDefinition grLegendFourthCol3 = new ColumnDefinition();
grLegendFourth.ColumnDefinitions.Add(grLegendFourthCol3);
RowDefinition grLegendFourthRow1 = new RowDefinition();
grLegendFourth.RowDefinitions.Add(grLegendFourthRow1);
Label lblLegendFourth = new Label();
lblLegendFourth.Background = Brushes.SaddleBrown;
lblLegendFourth.Width = 30;
Grid.SetRow(lblLegendFourth, 1);
Grid.SetColumn(lblLegendFourth, 1);
grLegendFourth.Children.Add(lblLegendFourth);
Label lblLegendFourthText = new Label();
lblLegendFourthText.Content = this._fourthLegendText;
lblLegendFourthText.FontSize = 10;
lblLegendFourthText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendFourthText, 1);
Grid.SetColumn(lblLegendFourthText, 2);
grLegendFourth.Children.Add(lblLegendFourthText);
#endregion
}
}
The complete code is as under
using System;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace HeatMap
{
public class HeatMapControl:Grid
{
#region Variables
DataTable HeatMapSource = new DataTable();
string _firstLegendText;
string _secondLegendText;
string _thirdLegendText;
string _fourthLegendText;
Double _firstUnit;
Double _secondUnit;
Double _thirdUnit;
Double _fourthUnit;
#endregion
#region Properties
public DataTable HeatMapSource
{
get
{
return HeatMapSource;
}
set
{
HeatMapSource = value;
CreatHeatMap();
}
}
#endregion
#region Constructor
public HeatMapControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(HeatMapControl), new FrameworkPropertyMetadata(typeof(HeatMapControl)));
this.Width = 900;
this.Height = 800;
}
#endregion
#region Private Method
/// <summary>
/// Create the heat map
/// </summary>
private void CreatHeatMap()
{
//Assign the legend units
AssignLegendUnits();
//Create Column Header
CreateColumnHeaders();
//Create Row Header
CreateRowHeaders();
//Create the chart
CreateChart();
//Display the units
DisplayUnits();
}
/// <summary>
/// AssignLegendUnits
/// </summary>
private void AssignLegendUnits()
{
Double _maxValue = 0.0;
Double _unitRange;
_maxValue = GetMaxValue(HeatMapSource);
_unitRange = _maxValue / 4;
_firstUnit = _unitRange;
_firstLegendText = "Less than " + _firstUnit;
_secondUnit = _firstUnit + _unitRange;
_secondLegendText = "Between " + _firstUnit + " And " + _secondUnit;
_thirdUnit = _secondUnit + _unitRange;
_thirdLegendText = "Between " + _secondUnit + " And " + _thirdUnit;
_fourthUnit = _thirdUnit + _unitRange;
_fourthLegendText = "Between " + _thirdUnit + " And " + _fourthUnit;
}
/// <summary>
/// Create column header
/// </summary>
private void CreateColumnHeaders()
{
int columnIndex = 0;
foreach (DataColumn dc in HeatMapSource.Columns)
{
ColumnDefinition cd = new ColumnDefinition();
cd.Width = GridLength.Auto;
this.ColumnDefinitions.Add(cd);
Label lbl = new Label();
lbl.FontSize = 10;
if (dc.Ordinal != 0)
{
lbl.Content = dc.ColumnName;
RotateTransform rt = new RotateTransform();
rt.Angle = -90;
lbl.LayoutTransform = rt;
}
lbl.Background = Brushes.Transparent;
lbl.BorderBrush = Brushes.Black;
Grid.SetRow(lbl, 0);
Grid.SetColumn(lbl, columnIndex);
this.Children.Add(lbl);
columnIndex++;
}
}
/// <summary>
/// Create row header
/// </summary>
private void CreateRowHeaders()
{
RowDefinition defaultRow = new RowDefinition();
defaultRow.Height = GridLength.Auto;
this.RowDefinitions.Add(defaultRow);
int rowIndex = 0;
foreach (DataRow dr in HeatMapSource.Rows)
{
RowDefinition rd = new RowDefinition();
rd.Height = new GridLength(19, GridUnitType.Pixel);
rd.Height = GridLength.Auto;
this.RowDefinitions.Add(rd);
Label rowHeader = new Label();
rowHeader.FontSize = 9;
rowHeader.VerticalContentAlignment = VerticalAlignment.Stretch;
rowHeader.Content = dr[0].ToString();
rowHeader.Background = Brushes.Transparent;
Grid.SetRow(rowHeader, rowIndex + 1);
Grid.SetColumn(rowHeader, 0);
this.Children.Add(rowHeader);
rowIndex++;
}
}
/// <summary>
/// Create the chart
/// </summary>
private void CreateChart()
{
//Set the Thickness for each of the label
System.Windows.Thickness th = new Thickness(0.3, 0.3, 0.3, 0.3);
int rowIndex = 1;
int columnIndex = 1;
foreach (DataRow dr in HeatMapSource.Rows)
{
columnIndex = 1;
foreach (DataColumn dc in HeatMapSource.Columns)
{
if (dc.Ordinal != 0)
{
string cellValue = dr[dc.ColumnName].ToString();
Label lbl = new Label();
//set the label properties
lbl.Width = 27;
lbl.BorderThickness = th;
lbl.BorderBrush = Brushes.Black;
if (string.IsNullOrEmpty(cellValue))
{
lbl.Background = Brushes.Transparent;
}
else
{
//Depends on the value assign the color
//First legend color
if (Convert.ToDouble(cellValue) > 0.0 && Convert.ToDouble(cellValue) < _firstUnit)
{
lbl.Background = Brushes.Moccasin;
}
//Second legend color
else if (Convert.ToDouble(cellValue) > _firstUnit && Convert.ToDouble(cellValue) <= _secondUnit)
{
lbl.Background = Brushes.BurlyWood;
}
//Third legend color
else if (Convert.ToDouble(cellValue) > _secondUnit && Convert.ToDouble(cellValue) <= _thirdUnit)
{
lbl.Background = Brushes.Chocolate;
}
//Fourth Legend color
else if (Convert.ToDouble(cellValue) > _thirdUnit && Convert.ToDouble(cellValue) <= _fourthUnit)
{
lbl.Background = Brushes.SaddleBrown;
}
}
Grid.SetRow(lbl, rowIndex);
Grid.SetColumn(lbl, columnIndex);
this.Children.Add(lbl);
columnIndex++;
}
}
rowIndex++;
}
}
private void DisplayUnits()
{
RowDefinition spaceRow = new RowDefinition();
spaceRow.Height = new GridLength(20, GridUnitType.Pixel);
this.RowDefinitions.Add(spaceRow);
RowDefinition legendRow = new RowDefinition();
legendRow.Height = GridLength.Auto;
this.RowDefinitions.Add(legendRow);
if (HeatMapSource.Rows.Count > 0 && HeatMapSource.Columns.Count > 0)
{
#region First Legend
Grid grCh = new Grid();
Grid.SetRow(grCh, HeatMapSource.Rows.Count + 2);
Grid.SetColumn(grCh, 0);
Grid.SetColumnSpan(grCh, HeatMapSource.Columns.Count - 1);
this.Children.Add(grCh);
ColumnDefinition grColm1 = new ColumnDefinition();
grColm1.Width = new GridLength(20);
grCh.ColumnDefinitions.Add(grColm1);
ColumnDefinition grColm2 = new ColumnDefinition();
grColm2.Width = GridLength.Auto;
grCh.ColumnDefinitions.Add(grColm2);
ColumnDefinition grColm3 = new ColumnDefinition();
grCh.ColumnDefinitions.Add(grColm3);
RowDefinition grRow1 = new RowDefinition();
grCh.RowDefinitions.Add(grRow1);
Label lblLegendFirst = new Label();
lblLegendFirst.Background = Brushes.Moccasin;
lblLegendFirst.Width = 30;
Grid.SetRow(lblLegendFirst, 0);
Grid.SetColumn(lblLegendFirst, 1);
grCh.Children.Add(lblLegendFirst);
Label lblLegendText = new Label();
lblLegendText.Content = this._firstLegendText;
lblLegendText.FontSize = 10;
lblLegendText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendText, 0);
Grid.SetColumn(lblLegendText, 2);
grCh.Children.Add(lblLegendText);
#endregion
#region Sec Legend
RowDefinition legendSecondRow = new RowDefinition();
legendSecondRow.Height = new GridLength(20);
this.RowDefinitions.Add(legendSecondRow);
Grid grLegendSec = new Grid();
Grid.SetRow(grLegendSec, HeatMapSource.Rows.Count + 3);
Grid.SetColumn(grLegendSec, 0);
Grid.SetColumnSpan(grLegendSec, HeatMapSource.Columns.Count - 1);
ColumnDefinition grLegendSecCol1 = new ColumnDefinition();
grLegendSecCol1.Width = new GridLength(20);
grLegendSec.ColumnDefinitions.Add(grLegendSecCol1);
ColumnDefinition grLegendSecCol2 = new ColumnDefinition();
grLegendSecCol2.Width = GridLength.Auto;
grLegendSec.ColumnDefinitions.Add(grLegendSecCol2);
ColumnDefinition grLegendSecCol3 = new ColumnDefinition();
grLegendSec.ColumnDefinitions.Add(grLegendSecCol3);
RowDefinition grLegendSecRow1 = new RowDefinition();
grLegendSec.RowDefinitions.Add(grLegendSecRow1);
Label lblLegendSec = new Label();
lblLegendSec.Background = Brushes.BurlyWood;
lblLegendSec.Width = 30;
Grid.SetRow(lblLegendSec, 0);
Grid.SetColumn(lblLegendSec, 1);
grLegendSec.Children.Add(lblLegendSec);
Label lblLegendSecText = new Label();
lblLegendSecText.Content = this._secondLegendText;
lblLegendSecText.FontSize = 10;
lblLegendSecText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendSecText, 0);
Grid.SetColumn(lblLegendSecText, 2);
grLegendSec.Children.Add(lblLegendSecText);
this.Children.Add(grLegendSec);
#endregion
#region Third Legend
RowDefinition legendThirdRow = new RowDefinition();
legendThirdRow.Height = GridLength.Auto;
this.RowDefinitions.Add(legendThirdRow);
Grid grLegendThrid = new Grid();
Grid.SetRow(grLegendThrid, HeatMapSource.Rows.Count + 4);
Grid.SetColumn(grLegendThrid, 0);
Grid.SetColumnSpan(grLegendThrid, HeatMapSource.Columns.Count - 1);
this.Children.Add(grLegendThrid);
ColumnDefinition grLegendThirdCol1 = new ColumnDefinition();
grLegendThirdCol1.Width = new GridLength(20);
grLegendThrid.ColumnDefinitions.Add(grLegendThirdCol1);
ColumnDefinition grLegendThirdCol2 = new ColumnDefinition();
grLegendThirdCol2.Width = GridLength.Auto;
grLegendThrid.ColumnDefinitions.Add(grLegendThirdCol2);
ColumnDefinition grLegendThirdCol3 = new ColumnDefinition();
grLegendThrid.ColumnDefinitions.Add(grLegendThirdCol3);
RowDefinition grLegendThridRow1 = new RowDefinition();
grLegendThrid.RowDefinitions.Add(grLegendThridRow1);
Label lblLegendThird = new Label();
lblLegendThird.Width = 30;
lblLegendThird.Background = Brushes.Chocolate;
Grid.SetRow(lblLegendThird, 3);
Grid.SetColumn(lblLegendThird, 1);
grLegendThrid.Children.Add(lblLegendThird);
Label lblLegendThirdText = new Label();
lblLegendThirdText.Content = this._thirdLegendText;
lblLegendThirdText.FontSize = 10;
lblLegendThirdText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendThirdText, 3);
Grid.SetColumn(lblLegendThirdText, 2);
grLegendThrid.Children.Add(lblLegendThirdText);
#endregion
#region Fourth Legend
RowDefinition legendFourthRow = new RowDefinition();
legendFourthRow.Height = GridLength.Auto;
this.RowDefinitions.Add(legendFourthRow);
Grid grLegendFourth = new Grid();
Grid.SetRow(grLegendFourth, HeatMapSource.Rows.Count + 5);
Grid.SetColumn(grLegendFourth, 0);
Grid.SetColumnSpan(grLegendFourth, HeatMapSource.Columns.Count - 1);
this.Children.Add(grLegendFourth);
ColumnDefinition grLegendFourthCol1 = new ColumnDefinition();
grLegendFourthCol1.Width = new GridLength(20);
grLegendFourth.ColumnDefinitions.Add(grLegendFourthCol1);
ColumnDefinition grLegendFourthCol2 = new ColumnDefinition();
grLegendFourthCol2.Width = GridLength.Auto;
grLegendFourth.ColumnDefinitions.Add(grLegendFourthCol2);
ColumnDefinition grLegendFourthCol3 = new ColumnDefinition();
grLegendFourth.ColumnDefinitions.Add(grLegendFourthCol3);
RowDefinition grLegendFourthRow1 = new RowDefinition();
grLegendFourth.RowDefinitions.Add(grLegendFourthRow1);
Label lblLegendFourth = new Label();
lblLegendFourth.Background = Brushes.SaddleBrown;
lblLegendFourth.Width = 30;
Grid.SetRow(lblLegendFourth, 1);
Grid.SetColumn(lblLegendFourth, 1);
grLegendFourth.Children.Add(lblLegendFourth);
Label lblLegendFourthText = new Label();
lblLegendFourthText.Content = this._fourthLegendText;
lblLegendFourthText.FontSize = 10;
lblLegendFourthText.Background = Brushes.Transparent;
Grid.SetRow(lblLegendFourthText, 1);
Grid.SetColumn(lblLegendFourthText, 2);
grLegendFourth.Children.Add(lblLegendFourthText);
#endregion
}
}
//Get the maximum value in all the columns
private Double GetMaxValue(DataTable dtChartData)
{
Double maxValue = 0.0;
foreach (DataColumn dc in dtChartData.Columns)
{
if (dc.Ordinal > 0)
{
string columnName = dc.ColumnName;
string max = dtChartData.Compute("Max([" + columnName + "])", "").ToString();
if (!string.IsNullOrEmpty(max))
{
if (maxValue < Convert.ToDouble(dtChartData.Compute("Max([" + columnName + "])", "")))
maxValue = Convert.ToDouble(dtChartData.Compute("Max([" + columnName + "])", ""));
}
}
}
return maxValue;
}
#endregion
}
}
Step 6: Add a resource dictionary and add the below
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:HeatMap">
<Style TargetType="{x:Type local:HeatMapControl}"/>
</ResourceDictionary>
Our control is now ready.So it's time to test the control. So create a WPF Project and add reference to the HeatMap class library project.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
xmlns:HeatMapControlTest ="clr-namespace:HeatMapLibrary;assembly=HeatMapLibrary">
<Grid>
<HeatMapControlTest:HeatMapControl Width="500" Height="700" x:Name="HeatMap"/>
</Grid>
</Window>
And in the windows load event , write the below
private void Window_Loaded(object sender, RoutedEventArgs e)
{
HeatMap.HeatMapSource = GetSource();
}
private DataTable GetSource()
{
DataSet sourceData = new DataSet();
sourceData.ReadXml(AppDomain.CurrentDomain.BaseDirectory + "\\" + "Sample.xml");
return sourceData.Tables["Table1"];
}
The Sample.xml looks as under
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Table1">
<xs:complexType>
<xs:sequence>
<xs:element name="Sector" type="xs:string" minOccurs="0" />
<xs:element name="BasicMaterials" type="xs:double" minOccurs="0" />
<xs:element name="Conglomerates" type="xs:double" minOccurs="0" />
<xs:element name="ConsumerGoods" type="xs:double" minOccurs="0" />
<xs:element name="Financial" type="xs:double" minOccurs="0" />
<xs:element name="HealthCare" type="xs:double" minOccurs="0" />
<xs:element name="IndustrialGoods" type="xs:double" minOccurs="0" />
<xs:element name="Services" type="xs:double" minOccurs="0" />
<xs:element name="Technology" type="xs:double" minOccurs="0" />
<xs:element name="Utilities" type="xs:double" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<Table1>
<Sector>Agricultural Chemicals</Sector>
<BasicMaterials>10</BasicMaterials>
<Conglomerates>0</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Appliances</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>45</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Application Software</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>0</Conglomerates>
<ConsumerGoods>80</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Asset Management</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>02</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Communication Equiqment</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>0</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>65</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Conglomerates</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>0</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>50</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Credit Services</Sector>
<BasicMaterials>10</BasicMaterials>
<Conglomerates>2</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>60</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Electronic Equiqment</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>0</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>70</Services>
<Technology>0</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Life Insurance</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>0</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>90</Technology>
<Utilities>0</Utilities>
</Table1>
<Table1>
<Sector>Oil and Gas Refining and Marketing</Sector>
<BasicMaterials>0</BasicMaterials>
<Conglomerates>0</Conglomerates>
<ConsumerGoods>0</ConsumerGoods>
<Financial>0</Financial>
<HealthCare>0</HealthCare>
<IndustrialGoods>0</IndustrialGoods>
<Services>0</Services>
<Technology>0</Technology>
<Utilities>80</Utilities>
</Table1>
</NewDataSet>
The final output is as under

I hope that this article will be helpful for creating a heat map control. Thanks for reading the article. The zipped file is attached
Best Regards,
Niladri Biswas