Does anyone knows a开发者_JAVA百科ny good tool for drawing correlation heat maps for WPF?
Example based on comments:
Original image source
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)
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
The Syncfusion charting component appears to provide heatmaps.
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.
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.
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>
精彩评论