Skip to content

Commit 4c95322

Browse files
Rounding when sampling charts
1 parent 738231b commit 4c95322

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

Common/SeriesSampler.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public virtual BaseSeries Sample(BaseSeries series, DateTime start, DateTime sto
6161
if (dataDiff >= Step)
6262
{
6363
// we don't want to subsample this case, directly return what we are given as long as is within the range
64-
return GetIdentitySeries(series.Clone(empty: true), series, start, stop, truncateValues: false);
64+
return GetIdentitySeries(series.Clone(empty: true), series, start, stop, truncateValues: false, roundTime: series.SeriesType == SeriesType.StackedArea);
6565
}
6666
}
6767

@@ -125,13 +125,13 @@ private Series SampleSeries(Series series, DateTime start, DateTime stop, bool t
125125
{
126126
var sampled = (Series)series.Clone(empty: true);
127127

128-
var nextSampleTime = start;
128+
var nextSampleTime = start.RoundUp(Step);
129129

130130
// we can't sample a single point and it doesn't make sense to sample scatter plots
131131
// in this case just copy the raw data
132132
if (series.Values.Count < 2 || series.SeriesType == SeriesType.Scatter)
133133
{
134-
return GetIdentitySeries(sampled, series, start, stop, truncateValues);
134+
return GetIdentitySeries(sampled, series, start, stop, truncateValues, series.SeriesType == SeriesType.StackedArea);
135135
}
136136

137137
var enumerator = series.Values.Cast<ChartPoint>().GetEnumerator();
@@ -143,9 +143,9 @@ private Series SampleSeries(Series series, DateTime start, DateTime stop, bool t
143143
var current = enumerator.Current;
144144

145145
// make sure we don't start sampling before the data begins
146-
if (nextSampleTime < previous.Time)
146+
while (nextSampleTime < previous.Time)
147147
{
148-
nextSampleTime = previous.Time;
148+
nextSampleTime += Step;
149149
}
150150

151151
// make sure to advance into the requested time frame before sampling
@@ -168,7 +168,7 @@ private Series SampleSeries(Series series, DateTime start, DateTime stop, bool t
168168
}
169169
else
170170
{
171-
sampledPoint = TruncateValue(Interpolate(previous, current, nextSampleTime, (decimal)Step.TotalSeconds), truncateValues, clone: false);
171+
sampledPoint = TruncateValue(Interpolate(previous, current, nextSampleTime, (decimal)Step.TotalSeconds), truncateValues, clone: false, roundTime: false);
172172
}
173173

174174
nextSampleTime += Step;
@@ -224,7 +224,7 @@ private CandlestickSeries SampleCandlestickSeries(CandlestickSeries series, Date
224224
// we can't sample a single point, so just copy the raw data
225225
if (seriesSize < 2)
226226
{
227-
return GetIdentitySeries(sampledSeries, series, start, stop, truncateValues);
227+
return GetIdentitySeries(sampledSeries, series, start, stop, truncateValues, roundTime: false);
228228
}
229229

230230
// Make sure we don't start sampling before the data begins.
@@ -240,7 +240,7 @@ private CandlestickSeries SampleCandlestickSeries(CandlestickSeries series, Date
240240
if (startIndex < 0)
241241
{
242242
// there's not value before the start, just return identity
243-
return GetIdentitySeries(sampledSeries, series, start, stop, truncateValues);
243+
return GetIdentitySeries(sampledSeries, series, start, stop, truncateValues, roundTime: false);
244244
}
245245
if (candlesticks[startIndex].Time == nextSampleTime && nextSampleTime <= stop)
246246
{
@@ -333,7 +333,7 @@ private CandlestickSeries SampleCandlestickSeries(CandlestickSeries series, Date
333333
/// Aggregates the candlesticks in the given range into a single candlestick,
334334
/// keeping the first open and last close and calculating highest high and lowest low
335335
/// </summary>
336-
private static Candlestick AggregateCandlesticks(List<ISeriesPoint> candlesticks, int start, int end, DateTime time, bool truncateValues)
336+
private Candlestick AggregateCandlesticks(List<ISeriesPoint> candlesticks, int start, int end, DateTime time, bool truncateValues)
337337
{
338338
var aggregatedCandlestick = new Candlestick
339339
{
@@ -349,7 +349,7 @@ private static Candlestick AggregateCandlesticks(List<ISeriesPoint> candlesticks
349349
aggregatedCandlestick.Update(current.Close);
350350
}
351351

352-
return (Candlestick)TruncateValue(aggregatedCandlestick, truncateValues, clone: false);
352+
return (Candlestick)TruncateValue(aggregatedCandlestick, truncateValues, clone: false, roundTime: false);
353353
}
354354

355355
/// <summary>
@@ -424,15 +424,18 @@ private static Candlestick Interpolate(Candlestick template, Candlestick first,
424424
/// Truncates the value/values of the point after cloning it to avoid mutating the original point
425425
/// </summary>
426426
[MethodImpl(MethodImplOptions.AggressiveInlining)]
427-
private static ISeriesPoint TruncateValue(ISeriesPoint point, bool truncate, bool clone = false)
427+
private ISeriesPoint TruncateValue(ISeriesPoint point, bool truncate, bool clone = false, bool roundTime = false)
428428
{
429+
var truncatedPoint = clone ? point.Clone() : point;
430+
if (roundTime)
431+
{
432+
truncatedPoint.Time = truncatedPoint.Time.RoundUp(Step);
433+
}
429434
if (!truncate)
430435
{
431-
return point;
436+
return truncatedPoint;
432437
}
433438

434-
var truncatedPoint = clone ? point.Clone() : point;
435-
436439
if (truncatedPoint is ChartPoint chartPoint)
437440
{
438441
chartPoint.y = SafeTruncate(chartPoint.y);
@@ -451,15 +454,15 @@ private static ISeriesPoint TruncateValue(ISeriesPoint point, bool truncate, boo
451454
/// <summary>
452455
/// Gets the identity series, this is the series with no sampling applied.
453456
/// </summary>
454-
protected static T GetIdentitySeries<T>(T sampled, T series, DateTime start, DateTime stop, bool truncateValues)
457+
protected T GetIdentitySeries<T>(T sampled, T series, DateTime start, DateTime stop, bool truncateValues, bool roundTime)
455458
where T : BaseSeries
456459
{
457460
// we can minimally verify we're within the start/stop interval
458461
foreach (var point in series.Values)
459462
{
460463
if (point.Time >= start && point.Time <= stop)
461464
{
462-
sampled.Values.Add(TruncateValue(point, truncateValues, clone: true));
465+
sampled.Values.Add(TruncateValue(point, truncateValues, clone: true, roundTime));
463466
}
464467
}
465468
return sampled;

0 commit comments

Comments
 (0)