AeroClassics
AeroClassics

Reputation: 1124

Heatmap does not show data

I am using the OxyPlot.Wpf library version 2.1.2, Windows 10, Visual Studio 2022 Professional,Prism.Wpf 8.1.97, and Prim.Unity 8.1.97. I am trying to create a Heat Map. In the ViewModel I create a PlotModel, I build up a 2D array of doubles, add a LinearColorAxis, a DateTimeAxis, a LinearAxis, and a HeatMapSeries. In the HeatMapSeries I assign my 2D array to the Data field. And assign the Series to the Model. Last Step is to assign the Model to the bound PlotModel. In my View I have a oxy:PlotView and the Model property is bound to the PlotModel in the ViewModel. Prism sets the data context. When I open the Window, I see the X & Y axes labels and values but there is nothing but a white area where I would expect the data to be? Ihave put a breakpoint where the SetProperty is called and looking at the model the data is in the series that is in the model. I cannot figure out why the data does not appear in the heatmap. Below is the View and ViewModel and hopefully can spot if I did something stupid.

<UserControl x:Class="PatternOfLife.Views.HeatMapView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
         xmlns:oxy="http://oxyplot.org/wpf"
HorizontalContentAlignment="Stretch"
d:DesignHeight="500"
d:DesignWidth="500"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">

<UserControl.Background>
    <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
        <GradientStop Offset="0" Color="{StaticResource StartWindowBackgroundColor}" />
        <GradientStop Offset="1" Color="{StaticResource EndWindowBackgroundColor}" />
    </LinearGradientBrush>
</UserControl.Background>

<Grid>
    <oxy:PlotView
        x:Name="plotView"
        Model="{Binding Path=PolPlotModel}"/>

</Grid>

    internal class HeatMapViewModel : BindableBase, IRegionMemberLifetime, IActiveAware
{
    private bool _isActive;
    public event EventHandler IsActiveChanged;
    private readonly IEventAggregator _eventAggregator;
    private readonly double _nanoseconds = 1.720532e18;
    private readonly double _startingFreq = 50.0e6;
    private readonly double _endingFreq = 60e6;
    private readonly double _freqStep = 1e+06;
    private readonly double _timeStep = 60 * 1e9;
    private double _startTime = 1.720449e+18;
    private double _endTime = 1.720450e+18;
    private List<SignalData> _signals;
    private HeatMapParameters _heatmapParameters;
    private BuildHeatMapData _buildHeatMapData;
    private double[,] _heatMapData;
    private PlotModel _polPlotModel;


    public bool IsActive
    {
        get { return _isActive; }
        set
        {
            SetProperty(ref _isActive, value);
            OnIsActiveChanged();
        }
    }
    bool IRegionMemberLifetime.KeepAlive => false;

    public PlotModel PolPlotModel
    {
        get => _polPlotModel;
        set
        {
            SetProperty(ref _polPlotModel, value);
        }
    }
    public HeatMapViewModel(IEventAggregator eventAggregator)
    {
        _isActive = false;
        _eventAggregator = eventAggregator;
    }

    protected virtual void OnIsActiveChanged()
    {
        if (IsActive)
        {
            _heatmapParameters = new HeatMapParameters(_startingFreq,
                                                       _endingFreq,
                                                       _freqStep,
                                                       _startTime,
                                                       _endTime,
                                                       _timeStep);

            Task.Run(async () =>
            {
                _signals = await DataRetrievalClass.GetData(_heatmapParameters);
            }).Wait();

            if (_signals != null)
            {
                _buildHeatMapData = new BuildHeatMapData(_heatmapParameters, _signals);
            }

            if (_buildHeatMapData != null)
            {
                _heatMapData = _buildHeatMapData.BuildData();
            }

            // Create an OxyPlot model
            var plotModel = new PlotModel { Title = "Pattern of Life" };

            // Color axis (the X and Y axes are generated automatically)
            plotModel.Axes.Add(new LinearColorAxis
            {
                Palette = OxyPalettes.Rainbow(100)
            });

            // Fix up Our X-axins Min and Max 

            plotModel.Axes.Add(new DateTimeAxis
            {
                Key = "xAxis",
                Position = AxisPosition.Bottom,
                Minimum = DateTimeAxis.ToDouble(_heatmapParameters.StartTimeDateTime), // set the start time
                Maximum = DateTimeAxis.ToDouble(_heatmapParameters.EndTimeDateTime),
                Title = "Time",
                StringFormat = "HH:mm:ss",
                MajorTickSize = 2, // adjust the tick size to match your 2-minute intervals
                MinorTickSize = 1,
                TickStyle = TickStyle.Crossing,
                AxisTitleDistance = 6,
                TitleFontSize = 14,
                Unit = "minutes", // set the incrementing interval to 2 minutes
            });

            plotModel.Axes.Add(new LinearAxis
            {
                Key = "yAxis",
                Position = AxisPosition.Left,
                Title = "Frequency",
                StringFormat = "F0", // display the frequency values with no decimal places
                Minimum = 50, // set the minimum frequency value
                Maximum = 60, // set the maximum frequency value
                Unit = "MHz", // set the incrementing interval to 1 MHz
            });

            // Create a heatmap series
            var heatmapSeries = new HeatMapSeries
            {
                XAxisKey = "xAxis",
                YAxisKey = "yAxis",
                Data = _heatMapData,
                RenderMethod = HeatMapRenderMethod.Bitmap,
                X0 = 0,
                X1 = _heatmapParameters.NumOfFreqSteps,
                Y0 = 0,
                Y1 = _heatmapParameters.NumOfFreqSteps,
                LabelFontSize = 0.2, // neccessary to display the label
                Interpolate = true
            };

            // Add the heatmap series to the plot model
            plotModel.Series.Add(heatmapSeries);

            PolPlotModel = plotModel;

            // Set the plot model to the OxyPlot control
            //PlotView.Model = plotModel;
        }
    }

}

Upvotes: 0

Views: 37

Answers (0)

Related Questions