Congratulations to all the winners of April 2013, they have won INR 3400 cash and INR 20147 worth prizes !
DotNetFunda.Com Logo
Twitter TwitterLinkedIn
YouTubeGoogle
 Online : 4445 |  Welcome, Guest!   Register  Login
 Home > Blogs > WPF > Create a Heat Map Control in WPF ...
Niladri.Biswas

Create a Heat Map Control in WPF

 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

  1. PresentationCore
  2. PresentationFramework
  3. System.Xaml
  4. 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
Found interesting? Add this to:


Experience:6 year(s)
Home page:http://www.dotnetfunda.com
Member since:Monday, October 25, 2010
Level:Diamond
Status: [Member]
Biography:Lead Engineer at HCL Technologies Ltd., having 6 years of experience in IT field.
I love to explore new technologies and love challenges and try to help others as much as possible not only by coding but also by all possible means.
>> Write Response - Respond to this post and get points

More Blogs

About Us | Contact Us | The Team | Advertise | Software Development | Write for us | Testimonials | Privacy Policy | Terms of Use | Link Exchange | Members | Go Top
General Notice: If you find plagiarised (copied) contents on this page, please let us know the original source along with your correct email id (to communicate) for further action.
Copyright © DotNetFunda.Com. All Rights Reserved. Copying or mimicking the site design and layout is prohibited. Logos, company names used here if any are only for reference purposes and they may be respective owner's right or trademarks. | 5/19/2013 8:32:54 PM