SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, iOS Chart, Android Chart and JavaScript Chart Components
SciChart WPF ships with hundreds of WPF Chart Examples which you can browse, play with, view the source-code and even export each WPF Chart Example to a stand-alone Visual Studio solution. All of this is possible with the new and improved SciChart WPF Examples Suite, which ships as part of the SciChart WPF SDK.
Demonstrates how to create a UniformHeatmap and use Automatic Peak Detection to highlight peaks on dense heatmaps. This is useful when heatmap is bigger than a screen resolution. In this case peaks may be lost because of heatmap compression. Setting the AutoPeakDetection property on a FastUniformHeatmapRenderableSeries turns on a peak detection algorithm to avoid this.
Documentation links:
– Heatmap API Documentation
– UniformHeatmapDataSeries class
– RenderableSeries API.
The C#/WPF source code for the WPF Heatmap Peak Detector example is included below (Scroll down!).
Did you know you can also view the source code from one of the following sources as well?
<UserControl x:Class="SciChart.Examples.Examples.HeatmapChartTypes.UniformHeatmapPeakDetection.UniformHeatmapPeakDetection"
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:ext="http://schemas.abtsoftware.co.uk/scichart/exampleExternals"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<UserControl.Resources>
<s:GradientStopsToLinearGradientBrushConverter x:Key="ColorsToLinearGradientBrushConverter"/>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.RowSpan="2"
Background="#232426"
BorderBrush="#323539"
BorderThickness="0,0,2,0">
<StackPanel>
<ToggleButton x:Name="RubberBandToggle"
HorizontalAlignment="Left"
Content="Zoom"
IsChecked="True"
Style="{StaticResource ZoomButtonStyle}"
ToolTipService.ToolTip="Toggle Rubber-Band Zoom"
s:ToggleButtonExtensions.GroupName="ZoomPanSelectionGroup"/>
<ToggleButton x:Name="ZoomPanToggle"
HorizontalAlignment="Left"
Content="Pan"
IsChecked="False"
Style="{StaticResource PanButtonStyle}"
ToolTipService.ToolTip="Toggle Zoom-Pan"
s:ToggleButtonExtensions.GroupName="ZoomPanSelectionGroup"/>
<Button HorizontalAlignment="Left"
Command="{Binding AnimateZoomExtentsCommand, Source={x:Reference SciChartSurface}}"
Content="Zoom Extents"
Style="{StaticResource ZoomExtentsButtonStyle}"
ToolTipService.ToolTip="Zoom to Extents"/>
<ext:FlyoutSeparator/>
<ToggleButton x:Name="PeakDetectorToggle"
HorizontalAlignment="Left"
Content="PD"
IsChecked="True"
Style="{StaticResource DefaultToggleButtonStyle}"
ToolTipService.ToolTip="Toggle Auto Peak Detection"/>
<ext:FlyoutMenuButton Content="TF" Padding="0" Style="{StaticResource FlyoutMenuButtonStyle}">
<ext:FlyoutMenuButton.PopupContent>
<StackPanel MinWidth="150" Orientation="Vertical">
<TextBlock Text="Texture Filtering"/>
<CheckBox x:Name="textureSwitch"
Margin="4"
Content="UseLinearTextureFiltering"/>
</StackPanel>
</ext:FlyoutMenuButton.PopupContent>
</ext:FlyoutMenuButton>
</StackPanel>
</Border>
<s:SciChartSurface x:Name="SciChartSurface" Grid.Row="1" Grid.Column="1">
<s:SciChartSurface.RenderableSeries>
<s:FastUniformHeatmapRenderableSeries x:Name="HeatmapRenderableSeries">
<s:FastUniformHeatmapRenderableSeries.Style>
<Style TargetType="{x:Type s:FastUniformHeatmapRenderableSeries}">
<Setter Property="AutoPeakDetection" Value="{Binding IsChecked, Mode=OneWay, Source={x:Reference PeakDetectorToggle}}"/>
<Setter Property="UseLinearTextureFiltering" Value="{Binding IsChecked, Mode=OneWay, Source={x:Reference Name=textureSwitch}}"/>
<Setter Property="ColorMap">
<Setter.Value>
<s:HeatmapColorPalette Minimum="-70" Maximum="0">
<s:HeatmapColorPalette.GradientStops>
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="0.0001" Color="DarkBlue" />
<GradientStop Offset="0.2" Color="CornflowerBlue" />
<GradientStop Offset="0.4" Color="DarkGreen" />
<GradientStop Offset="0.6" Color="Chartreuse" />
<GradientStop Offset="0.8" Color="Yellow" />
<GradientStop Offset="1" Color="Red" />
</s:HeatmapColorPalette.GradientStops>
</s:HeatmapColorPalette>
</Setter.Value>
</Setter>
</Style>
</s:FastUniformHeatmapRenderableSeries.Style>
</s:FastUniformHeatmapRenderableSeries>
</s:SciChartSurface.RenderableSeries>
<s:SciChartSurface.XAxis>
<s:NumericAxis AutoRange="Once" />
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis AutoRange="Once"/>
</s:SciChartSurface.YAxis>
<s:SciChartSurface.ChartModifier>
<s:ModifierGroup>
<s:ZoomExtentsModifier IsEnabled="True"/>
<s:ZoomPanModifier IsEnabled="{Binding IsChecked, Source={x:Reference ZoomPanToggle}}"/>
<s:RubberBandXyZoomModifier IsEnabled="{Binding IsChecked, Source={x:Reference RubberBandToggle}}"/>
</s:ModifierGroup>
</s:SciChartSurface.ChartModifier>
</s:SciChartSurface>
<s:HeatmapColorMap Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
BorderThickness="0"
Background="Transparent"
ColorMap="{Binding ColorMap.GradientStops, Source={x:Reference HeatmapRenderableSeries}, Converter={StaticResource ColorsToLinearGradientBrushConverter}}"
Maximum="{Binding ColorMap.Maximum, Source={x:Reference HeatmapRenderableSeries}}"
Minimum="{Binding ColorMap.Minimum, Source={x:Reference HeatmapRenderableSeries}}"
Orientation="Horizontal"
EnableAxisDrag="True"
TextFormatting="0">
<s:HeatmapColorMap.AxisStyle>
<Style TargetType="s:AxisBase">
<Setter Property="Margin" Value="0,-15,0,0"/>
<Setter Property="DrawMajorBands" Value="False"/>
<Setter Property="DrawMinorTicks" Value="False"/>
<Setter Property="DrawMajorGridLines" Value="False"/>
<Setter Property="DrawMinorGridLines" Value="False"/>
</Style>
</s:HeatmapColorMap.AxisStyle>
</s:HeatmapColorMap>
</Grid>
</UserControl>
// *************************************************************************************
// SCICHART® Copyright SciChart Ltd. 2011-2022. All rights reserved.
//
// Web: http://www.scichart.com
// Support: support@scichart.com
// Sales: sales@scichart.com
//
// UniformHeatmapPeakDetection.xaml.cs is part of the SCICHART® Examples. Permission
// is hereby granted to modify, create derivative works, distribute and publish any part
// of this source code whether for commercial, private or personal use.
//
// The SCICHART® examples are distributed in the hope that they will be useful, but
// without any warranty. It is provided "AS IS" without warranty of any kind, either
// expressed or implied.
// *************************************************************************************
using System;
using System.Windows.Controls;
using SciChart.Charting.Model.DataSeries.Heatmap2DArrayDataSeries;
using SciChart.Examples.ExternalDependencies.Data;
namespace SciChart.Examples.Examples.HeatmapChartTypes.UniformHeatmapPeakDetection
{
public partial class UniformHeatmapPeakDetection : UserControl
{
public UniformHeatmapPeakDetection()
{
InitializeComponent();
var buffer = GetSpectrogramBuffer();
HeatmapRenderableSeries.DataSeries = new UniformHeatmapDataSeries<int, int, double>(buffer, 0, 1, 0, 1);
}
private double[,] GetSpectrogramBuffer()
{
const int yCount = 100;
const int xCount = 4_096;
var spectrogramBuffer = new double[yCount, xCount];
var random = new Random();
var transform = new FFT2();
transform.init(12);
var re = new double[xCount];
var im = new double[xCount];
for (int y = 0; y < yCount; y++)
{
for (int i = 0; i < xCount; i++)
{
re[i] = 2d * Math.Sin(2 * Math.PI * i / 20) +
5 * Math.Sin(2 * Math.PI * i / 10) -
2d * random.NextDouble();
im[i] = -10;
}
transform.run(re, im);
for (int i = 0; i < xCount; i++)
{
var mag = Math.Sqrt(re[i] * re[i] + im[i] * im[i]);
im[i] = i;
spectrogramBuffer[y, i] = 20 * Math.Log10(mag / xCount);
}
}
return spectrogramBuffer;
}
}
}