Reputation: 1124
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