Scatter don’t show point marker if there is a only one value on the chart.
How can i solve that problem?
P.S: If i create my own renderiableseries class which only draw point markers, all works fine.
P.P.S I suppose that this behavior depenends on ReasmplingMode value.
- Ivan Zakharov asked 9 years ago
- last edited 9 years ago
- You must login to post comments
We actually have a test-case for that, since it was reported as a bug in about 2012 (but since fixed)!
In SciChart v3.4 (and probably many other versions), this works just fine. What version are you using, and what code have you used to declare your scatter series?
Here is the code for the test-case:
XAML
<UserControl x:Class="Abt.Controls.SciChart.Wpf.TestSuite.TestCases.OCLim.SingleDataPointChart"
xmlns omitted for brevity ... >
<Grid>
<s:SciChartSurface x:Name="sciChart" s:ThemeManager.Theme="Chrome" ChartTitle="ChartTitle">
<s:SciChartSurface.RenderableSeries>
<s:XyScatterRenderableSeries x:Name="renderableSeries" YAxisId="Right" SeriesColor="OrangeRed">
<s:XyScatterRenderableSeries.PointMarker>
<s:EllipsePointMarker Width="11" Height="11" Fill="Red" Stroke="Lavender" StrokeThickness="2"/>
</s:XyScatterRenderableSeries.PointMarker>
</s:XyScatterRenderableSeries>
</s:SciChartSurface.RenderableSeries>
<s:SciChartSurface.XAxis>
<s:NumericAxis AxisTitle="X Axis Title" VisibleRange="0, 10"/>
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxes>
<s:NumericAxis AxisTitle="Y Axis Title (Right)" AxisAlignment="Right" Id="Right" VisibleRange="0, 1"/>
<s:NumericAxis AxisTitle="Y Axis Title (Left)" AxisAlignment="Left" Id="Left" VisibleRange="0, 1"/>
</s:SciChartSurface.YAxes>
<s:SciChartSurface.ChartModifier>
<s:TooltipModifier/>
</s:SciChartSurface.ChartModifier>
</s:SciChartSurface>
</Grid>
</UserControl>
Code Behind
using System.Windows;
using System.Windows.Controls;
using Abt.Controls.SciChart.Model.DataSeries;
namespace Abt.Controls.SciChart.Wpf.TestSuite.TestCases.OCLim
{
public partial class SingleDataPointChart : UserControl
{
public SingleDataPointChart()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
var dataseries = new XyDataSeries<double, double>();
dataseries.Append(5, 0.5);
sciChart.RenderableSeries[0].DataSeries = dataseries;
}
}
}
Result
See attached image
- Andrew Burnett-Thompson answered 9 years ago
- last edited 9 years ago
- You must login to post comments
I am using a version 3.21.0.5511.
I suppose problem is that i have a miltiple dataseries in one chart, so i need a synchronization for their xValues. For that, i am filling yValues by Double.NaN.
I understand now =) that really scatterchart doesn’t have a only one value. It has only one not Double.NaN yValue at time. It is possible that reasmpling approach hides that value?
Code
private IChartSeriesViewModel AddPointMarkerSeriesNotSafe(LineTimeSeries timeSeries, BasePointMarker pointMarker)
{
IChartSeriesViewModel result = null;
mapDataSeries.TryGetValue(timeSeries, out result);
if (result != null) return result;
//It function creates a DataSeries
var sp = DataSeriesHelper.MergeXy(timeSeries, v => v.Min, this.synchronizer.XValues);
timeSeries.Modified += XyTimeSeriesModified;
result = new ChartSeriesViewModel(sp, new XyScatterRenderableSeries
{
PointMarker = pointMarker,
DoClusterResampling = true
});
ChartSeries.Add(result);
this.synchronizer.Add(result);
mapDataSeries.AddOrUpdate(timeSeries, result, (k, v) => result);
return result;
}
//It function creates merge xValues between timeSeries and list of keys, it fill new xValues Double.NaN.
public static XyDataSeries<DateTime, double> MergeXy(ITimeSeries timeSeries, Func<ITimePoint, double> selector, IList<DateTime> keys)
{
var result = new XyDataSeries<DateTime, double>();
int keyIndex = 0;
int tsIndex = 0;
int count = timeSeries.Count + keys.Count;
List<DateTime> dsKeys = new List<DateTime>(count);
List<double> dsValues = new List<double>(count);
while (tsIndex < timeSeries.Count
|| keyIndex < keys.Count)
{
if (keyIndex >= keys.Count
|| (tsIndex < timeSeries.Count && timeSeries[tsIndex].Time <= keys[keyIndex]))
{
if (keyIndex < keys.Count && timeSeries[tsIndex].Time == keys[keyIndex])
{
keyIndex++;
}
var tp = timeSeries[tsIndex++];
dsKeys.Add(tp.Time);
dsValues.Add(selector(tp));
}
else
{
dsKeys.Add(keys[keyIndex++]);
dsValues.Add(Double.NaN);
}
}
result.Append(dsKeys, dsValues);
return result;
}
XAML
<s:SciChartSurface SeriesSource="{Binding FastController.DataSeries.ChartSeries}"
RenderPriority="Normal"
s:ThemeManager.Theme="BlackSteel"
Loaded="Surface_Loaded"
Name="Surface"
Padding="5 2 10 2">
<s:SciChartSurface.RenderSurface>
<s:HighSpeedRenderSurface/>
</s:SciChartSurface.RenderSurface>
<s:SciChartSurface.ChartModifier>
<s:ModifierGroup s:MouseManager.MouseEventGroup="{Binding Parent.Parent.SharedMouseGroupId, Mode=TwoWay}">
<c:CustomAnnotationRenderingModifier AnnotationSource="{Binding FastController.Annotations.AnnotationViewModels}"
ShowLastPoint="{Binding ShowLastPoint}" />
<c:AtonMouseWheelModifier />
<c:AtonYDragModifier />
<c:AtonSeriesSelectionModifier/>
<c:AtonZoomPanModifier x:Name="ZoomPanModifier" ExecuteOn="MouseLeftButton" />
<s:ZoomExtentsModifier ExecuteOn="MouseDoubleClick"/>
<c:VisibleRangeChangedEventModifier ReceiveHandledEvents="True"/>
<c:CursorModifierEx SnapsToDevicePixels="True"
IsEnabled="True"
ShowTooltip="True"
ShowTooltipOn="MouseRightButtonDown"
ReceiveHandledEvents="True"/>
</s:ModifierGroup>
</s:SciChartSurface.ChartModifier>
<s:SciChartSurface.XAxis>
<s:CategoryDateTimeAxis GrowBy="0, 0.05">
<s:CategoryDateTimeAxis.Scrollbar>
<s:SciChartScrollbar Height="16"/>
</s:CategoryDateTimeAxis.Scrollbar>
</s:CategoryDateTimeAxis>
</s:SciChartSurface.XAxis>
</s:SciChartSurface>
- Ivan Zakharov answered 9 years ago
- last edited 9 years ago
-
Hi Arthur, the default ResamplingMode for XyScatterRenderableSeries is None. Unless you have changed it (we recommend leaving the default), then no resampling is applied. DoClusterResampling is an experimental resampling mode which can allow very high point counts, but in our tests, it provides no performance improvement until you are using over 200k scatter points. I would suggest leaving this value as default to prove whether the problem is resampling or not.
-
Hi Andrew, i'm sorry but it didn't help to me. See attached images below.
-
Hi Artur, In my original answer, there is a code sample. If you modify that to display three points, with the third a NaN point, e.g.
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) { var dataseries = new XyDataSeries<double, double>(); dataseries.Append(5, 0.5); dataseries.Append(6, double.NaN); dataseries.Append(7, 0.5); sciChart.RenderableSeries[0].DataSeries = dataseries; }
Then the chart correctly renders. This is using v3.4.2 which is our latest build. Best regards, Andrew -
Hold on ... we can reproduce a bug where the NaN are only before the point, e.g. when the following code is used
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) { var dataseries = new XyDataSeries<double, double>(); dataseries.Append(5, double.NaN); dataseries.Append(6, double.NaN); dataseries.Append(7, 0.5); sciChart.RenderableSeries[0].DataSeries = dataseries; }
then the point does not show. One second, we are investigating. -
Hi Artur, We have a fix in build v3.4.2.6661 which is will be available on our nightly build page in approximately 10 minutes. This should now correctly render a single scatter point (or pointmarker on any other series) when isolated in a stream of NaNs, and similarly fixes the bug where one point after several successive NaNs is blank. Thanks for reporting! Best regards, Andrew
- You must login to post comments
Code
private IChartSeriesViewModel AddPointMarkerSeriesNotSafe(LineTimeSeries timeSeries, BasePointMarker pointMarker)
{
IChartSeriesViewModel result = null;
mapDataSeries.TryGetValue(timeSeries, out result);
if (result != null) return result;
//It function just create a DataSeries
var sp = DataSeriesHelper.MergeXy(timeSeries, v => v.Min, this.synchronizer.XValues);
timeSeries.Modified += XyTimeSeriesModified;
result = new ChartSeriesViewModel(sp, new XyScatterRenderableSeries
{
PointMarker = pointMarker,
});
ChartSeries.Add(result);
this.synchronizer.Add(result);
mapDataSeries.AddOrUpdate(timeSeries, result, (k, v) => result);
return result;
}
- Ivan Zakharov answered 9 years ago
- You must login to post comments
Please login first to submit.