5

Does anyone knows any good tool for drawing correlation heat maps for WPF?

Example based on comments:

enter image description here

Original image source

Brian Lyttle
  • 14,558
  • 15
  • 68
  • 104
Xenofonte
  • 59
  • 1
  • 2
  • Please see http://en.wikipedia.org/wiki/Heat_map for the definition of a heat map.. What you're asking for isn't one, sorry. At best I'd say you're asking for how to change the background of a cell in a table... – Peter Drier Jan 31 '13 at 14:49

5 Answers5

8

The free WPF Toolkit has a TreeMap. You can define it in XAML as follows:

<vis:TreeMap ItemsSource="{Binding Path=HeatMap.Sectors}"
              Interpolators="{StaticResource colourInterpolator}">
  <vis:TreeMap.ItemDefinition>
    <vis:TreeMapItemDefinition ValueBinding="{Binding MarketCap}">
      <DataTemplate>
        <Grid>
          <Border x:Name="Border"
                  BorderBrush="Black"
                  BorderThickness="1"
                  Margin="1"
                  Opacity="0.5">                      
          </Border>
          <TextBlock Text="{Binding Name}"
                     TextWrapping="Wrap"
                     FontSize="20"
                     Margin="5"
                     VerticalAlignment="Center"
                     HorizontalAlignment="Center"/>
        </Grid>
      </DataTemplate>
    </vis:TreeMapItemDefinition>
  </vis:TreeMap.ItemDefinition>
</vis:TreeMap>

The above XAML is a snippet from an application I have written that shows financial HeatMaps. You can see a Silverlight version running here:

http://www.scottlogic.co.uk/blog/colin/xaml-finance/

(Just hit the 'heatmap' button)

ColinE
  • 68,894
  • 15
  • 164
  • 232
  • It seems a bit different from what I want. I'm looking for a correlation heatmap like this - http://lcchong.files.wordpress.com/2011/05/image_thumb.png?w=644&h=206 Thanks anyway – Xenofonte May 31 '11 at 15:16
  • OK - you need a DataGrid! There is a perfectly good DataGrid that is part of the WPF framework. – ColinE May 31 '11 at 15:17
  • I think I'll go down that route :) – Xenofonte May 31 '11 at 15:38
  • Datagrid on its own provides no simple method to do a heatmap – rollsch Oct 30 '16 at 20:25
  • @rolls, possible duplicate of http://stackoverflow.com/questions/5549617/change-datagrid-cell-colour-based-on-values – ASh Oct 31 '16 at 07:22
2

If you are looking for a commercial product, I would suggest you look at the Telerik controls. Telerik has excellent controls for WPF. Included in the long list is a Heat Map control. Here is a link to the site where they list the heat map feature:

http://www.telerik.com/products/wpf/map.aspx

If you are looking to build something, here are a couple blog articles that lay out how to do it (with source provided):

http://www.garrettgirod.com/?p=111

http://www.nickdarnell.com/?p=833

IAmTimCorey
  • 16,412
  • 5
  • 39
  • 75
  • Thank you for your answer but I'm looking for a correlation heatmap like this - http://lcchong.files.wordpress.com/2011/05/image_thumb.png?w=644&h=206 – Xenofonte May 31 '11 at 15:15
2

The Syncfusion charting component appears to provide heatmaps.

Brian Lyttle
  • 14,558
  • 15
  • 68
  • 104
  • 1
    Thank you for your answer but I'm looking for a correlation heatmap like this - http://lcchong.files.wordpress.com/2011/05/image_thumb.png?w=644&h=206 – Xenofonte May 31 '11 at 15:15
  • 1
    @Xenofonte: I've edited your question to include this. As other have stated this is similar to a datagrid, but there is probably some code to write and maintain for the visualization you want. It is worth checking if the syncfusion or telerik controls require less customization. – Brian Lyttle May 31 '11 at 16:02
1

Not a free component, but if you can get your hands on the Telerik library you could use the following:

http://www.telerik.com/products/wpf/heatmap.aspx

I have had to use it in the past for a few projects and it worked pretty well.

Kevin B Burns
  • 1,032
  • 9
  • 24
1

I used DevExpress with a custom ColorFormatter behaviour. I couldn't find anything on the market that did this out of the box. This took me a few days to develop. My code attaached below, hopefully this helps someone out there.

Edit: I used POCO view models and MVVM however you could change this to not use POCO if you desire.

Example

Table2DViewModel.cs

namespace ViewModel
{
    [POCOViewModel]
    public class Table2DViewModel
    {
        public ITable2DView Table2DView { get; set; }

        public DataTable ItemsTable { get; set; }


        public Table2DViewModel()
        {
        }

        public Table2DViewModel(MainViewModel mainViewModel, ITable2DView table2DView) : base(mainViewModel)
        {
            Table2DView = table2DView;   
            CreateTable();
        }

        private void CreateTable()
        {
            var dt = new DataTable();
            var xAxisStrings = new string[]{"X1","X2","X3"};
            var yAxisStrings = new string[]{"Y1","Y2","Y3"};

            //TODO determine your min, max number for your colours
            var minValue = 0;
            var maxValue = 100;
            Table2DView.SetColorFormatter(minValue,maxValue, null);

            //Add the columns
            dt.Columns.Add(" ", typeof(string));
            foreach (var x in xAxisStrings) dt.Columns.Add(x, typeof(double));

            //Add all the values
            double z = 0;
            for (var y = 0; y < yAxisStrings.Length; y++)
            {
                var dr = dt.NewRow();
                dr[" "] = yAxisStrings[y];
                for (var x = 0; x < xAxisStrings.Length; x++)
                {
                    //TODO put your actual values here!
                    dr[xAxisStrings[x]] = z++; //Add a random values
                }
                dt.Rows.Add(dr);
            }
            ItemsTable = dt;
        }


        public static Table2DViewModel Create(MainViewModel mainViewModel, ITable2DView table2DView)
        {
            var factory = ViewModelSource.Factory((MainViewModel mainVm, ITable2DView view) => new Table2DViewModel(mainVm, view));
            return factory(mainViewModel, table2DView);
        }
    }

}

ITable2DView.cs

namespace Interfaces
    {
        public interface ITable2DView
        {
            void SetColorFormatter(float minValue, float maxValue, ColorScaleFormat colorScaleFormat);
        }
    }

Table2DView.xaml.cs

namespace View
{
    public partial class Table2DView : ITable2DView
    {
        public Table2DView()
        {
            InitializeComponent();
        }

        static ColorScaleFormat defaultColorScaleFormat = new ColorScaleFormat
        {
            ColorMin = (Color)ColorConverter.ConvertFromString("#FFF8696B"),
            ColorMiddle = (Color)ColorConverter.ConvertFromString("#FFFFEB84"),
            ColorMax = (Color)ColorConverter.ConvertFromString("#FF63BE7B")
        };

        public void SetColorFormatter(float minValue, float maxValue, ColorScaleFormat colorScaleFormat = null)
        {
            if (colorScaleFormat == null) colorScaleFormat = defaultColorScaleFormat;
            ConditionBehavior.MinValue = minValue;
            ConditionBehavior.MaxValue = maxValue;
            ConditionBehavior.ColorScaleFormat = colorScaleFormat;
        }
    }
}

DynamicConditionBehavior.cs

namespace Behaviors
{
    public class DynamicConditionBehavior : Behavior<GridControl>
    {
        GridControl Grid => AssociatedObject;

        protected override void OnAttached()
        {
            base.OnAttached();
            Grid.ItemsSourceChanged += OnItemsSourceChanged;
        }

        protected override void OnDetaching()
        {
            Grid.ItemsSourceChanged -= OnItemsSourceChanged;
            base.OnDetaching();
        }

        public ColorScaleFormat ColorScaleFormat { get; set;}
        public float MinValue { get; set; }
        public float MaxValue { get; set; }

        private void OnItemsSourceChanged(object sender, EventArgs e)
        {
            var view = Grid.View as TableView;

            if (view == null) return;

            view.FormatConditions.Clear();

            foreach (var col in Grid.Columns)
            {
                view.FormatConditions.Add(new ColorScaleFormatCondition
                {
                    MinValue = MinValue,
                    MaxValue = MaxValue,
                    FieldName = col.FieldName,
                    Format = ColorScaleFormat,
                });
            }

        }
    }
}

Table2DView.xaml

<UserControl x:Class="View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" 
             xmlns:ViewModels="clr-namespace:ViewModel"
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
             xmlns:behaviors="clr-namespace:Behaviors"
             xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
             DataContext="{dxmvvm:ViewModelSource Type={x:Type ViewModels:ViewModel}}"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="800">

    <UserControl.Resources>
        <Style TargetType="{x:Type dxg:GridColumn}">
            <Setter Property="Width" Value="50"/>
            <Setter Property="HorizontalHeaderContentAlignment" Value="Center"/>
        </Style>

        <Style TargetType="{x:Type dxg:HeaderItemsControl}">
            <Setter Property="FontWeight" Value="DemiBold"/>
        </Style>
    </UserControl.Resources>

        <!--<dxmvvm:Interaction.Behaviors>
            <dxmvvm:EventToCommand EventName="" Command="{Binding OnLoadedCommand}"/>
        </dxmvvm:Interaction.Behaviors>-->
        <dxg:GridControl ItemsSource="{Binding ItemsTable}"
                     AutoGenerateColumns="AddNew"
                     EnableSmartColumnsGeneration="True">

        <dxmvvm:Interaction.Behaviors >
            <behaviors:DynamicConditionBehavior x:Name="ConditionBehavior" />
            </dxmvvm:Interaction.Behaviors>
            <dxg:GridControl.View>
                <dxg:TableView ShowGroupPanel="False"
                           AllowPerPixelScrolling="True"/>
            </dxg:GridControl.View>
        </dxg:GridControl>
  </UserControl>
rollsch
  • 2,518
  • 4
  • 39
  • 65