private static void FixCounterSerieData(IList <SeriesValue> inSeriesValue, SeriesResolution inResolution, DateTime inFromDate) { // it can be the case that there is not data yet at the actualFrom date, this results in null values which should be 0 if (inSeriesValue.Any(sv => !sv.Value.HasValue)) { for (var i = 0; i < inSeriesValue.Count(v => v.End <= DateTime.UtcNow); i++) { if (inSeriesValue[i].Value.HasValue) { break; } inSeriesValue[i].Value = 0; } } while (inSeriesValue[0].Begin > inFromDate) { var value = new SeriesValue(); if (inResolution == SeriesResolution.Month) { value.Begin = inSeriesValue[0].Begin.AddMonths(-1); value.End = value.Begin.AddMonths(1); } else { value.Begin = inSeriesValue[0].Begin.AddMinutes(-1 * (int)inResolution); value.End = value.Begin.AddMinutes((int)inResolution); } value.Value = 0; inSeriesValue.Insert(0, value); } }
public override Shape Create(SeriesValue seriesValue) { var factory = calculationFactory as PieChartCalculationFactory; var drawableFactory = mainDrawableFactory as DoughnutDrawableFactory; var paint = drawableFactory.CreateArcPaint(seriesValue); var textPaint = drawableFactory.CreateTextPaint(seriesValue, paint.Color); var leftSide = Series.IndexOf(seriesValue) % 2 == 0; var text = leftSide ? $"{seriesValue.Label} {(UseCaption() ? seriesValue.Caption : CalculatePercentage(seriesValue).ToString("F0") + "%")}" : $"{(UseCaption() ? seriesValue.Caption : CalculatePercentage(seriesValue).ToString("F0") + "%")} {seriesValue.Label}"; return(new Arc(canvas) { SerieValue = seriesValue, CenterRect = CenterRect, Paint = paint, LabelPosition = drawableFactory.CreateLabelPoint(seriesValue, textPaint, text), StartAngle = factory.CalculateStartAngle(), SweepAngle = factory.CalculateSweepAngle(seriesValue), Text = text, TextPaint = textPaint }); }
/// <summary> /// Добавление в серию нового значения /// </summary> /// <param name="seriesID">Идентификатор серии (то значение, которое вернул вызов OpenSeries)</param> /// <param name="time">Дата и время значения</param> /// <param name="val">Десятичное значение</param> /// <param name="sp">Объект параметров визуализации значения</param> /// <returns>true - успешно, false - не найден Series по указанному идентификатору</returns> public bool AddSeriesValue(int seriesID, DateTime time, decimal val, ISeriesProps sp = null) { var series = _series.FirstOrDefault(r => r.SeriesID == seriesID); if (series == null) { return(false); } if (!_series_values.ContainsKey(series)) { _series_values.Add(series, new List <SeriesValue>()); } var vals = _series_values[series]; var sv = new SeriesValue(); sv.SeriesValueID = 0; sv.SeriesID = series.SeriesID; sv.Time = time; sv.Value = val; sv.Data = SeriesPropsUtil.Serialize(sp); sv.EndTime = null; sv.EndValue = null; vals.Add(sv); return(true); }
public float CalculateLabelYAxis(SeriesValue value) { var margin = AvaibleHeight / (20 / 2); var start = (chart.Series.IndexOf(value) / 2) + 1; return(chart.TextSize * 2 * start); }
public override float CalculateTop(SeriesValue value) { var percentage = value.Value / (chart.MaxEntryValue / AxisX) * 100 / AxisX; var increaseHeight = Math.Abs(percentage * ((chart.AllNegatives ? -AvaibleHeight : -MarginY) + AxisX) / 100); var result = AxisX - (value.Value > 0 ? increaseHeight : -increaseHeight); return(result); }
public SKPoint CreateValuePointPosition(SeriesValue value) { var calculationFactory = factory as BarChartCalculationFactory; var barStartingPoint = calculationFactory.CalculateBarStartingPoint(chart.Series.IndexOf(value)); return(factory is VerticalBarChartCalculationFactory ? new SKPoint(barStartingPoint, calculationFactory.GetLabelValuePointY()) : new SKPoint(calculationFactory.GetLabelValuePointY(), calculationFactory.CalculateTop(barStartingPoint))); }
public SKRect CreateBarRect(SeriesValue value) { if (factory is VerticalBarChartCalculationFactory) { return(CreateVerticalBarRect(value)); } else { return(CreateHorizontalBarRect(value)); } }
public SerieIndexFinder(List <SeriesValue> inSlots) { _slots = inSlots; // inSlots will change between calls to GetSerieIndex, but only at the end of the list. Therefore we need to store the info // about the original list. _serieBegin = inSlots.Any() ? inSlots.First().Begin : DateTime.MaxValue; _serieEnd = inSlots.Any() ? inSlots.Last().Begin : DateTime.MinValue; _nrSlots = inSlots.Count; _itemToFind = new SeriesValue(); _comparer = new SeriesValueComparer(); _lastFoundIndex = -1; }
public SKRect CreateHorizontalBarRect(SeriesValue value) { var calculationFactory = factory as BarChartCalculationFactory; var barStartingPoint = calculationFactory.CalculateBarStartingPoint(chart.Series.IndexOf(value)); var left = calculationFactory.CalculateLeft(barStartingPoint); var right = calculationFactory.CalculateRight(value); var bottom = calculationFactory.CalculateBottom(barStartingPoint); var top = calculationFactory.CalculateTop(barStartingPoint); var rect = new SKRect(left, top, right, bottom); return(rect); }
public SKPoint CreateLabelPoint(SeriesValue seriesValue, SKPaint textPaint, string text) { var calculationFactory = factory as PieChartCalculationFactory; var labelPosition = new SKPoint(calculationFactory.CalculateLabelXAxis(seriesValue), calculationFactory.CalculateLabelYAxis(seriesValue)); var leftSide = chart.Series.IndexOf(seriesValue) % 2 == 0; if (!leftSide) { var width = textPaint.MeasureText(text); labelPosition = new SKPoint(labelPosition.X - width, labelPosition.Y); } return(labelPosition); }
public SKPaint CreateTextPaint(SeriesValue seriesValue, SKColor color) { var textPaint = new SKPaint { Color = color, TextSize = chart.TextSize }; if (!seriesValue.Focused && chart.HasShapeFocused) { SKBlurStyle blurStyle = SKBlurStyle.Normal; textPaint.MaskFilter = SKMaskFilter.CreateBlur(blurStyle, chart.Sigma); } return(textPaint); }
public SKPaint CreateSlicePaint(SeriesValue seriesValue) { var paint = new SKPaint { StrokeWidth = 30, Style = SKPaintStyle.Fill, Color = seriesValue.HasColour() ? seriesValue.Colour : palette.GetAvaibleColour(), }; if (!seriesValue.Focused && chart.HasShapeFocused) { SKBlurStyle blurStyle = SKBlurStyle.Normal; paint.MaskFilter = SKMaskFilter.CreateBlur(blurStyle, chart.Sigma); } return(paint); }
public SKPaint CreateDotPaint(SeriesValue value) { var paint = new SKPaint { Color = !value.Colour.Equals(SKColor.Empty) ? value.Colour : palette.GetAvaibleColour(), StrokeWidth = 20, TextSize = chart.TextSize, TextAlign = SKTextAlign.Center }; if (!value.Focused && chart.HasShapeFocused) { SKBlurStyle blurStyle = SKBlurStyle.Normal; paint.MaskFilter = SKMaskFilter.CreateBlur(blurStyle, chart.Sigma); } return(paint); }
public override Shape Create(SeriesValue value) { var factory = calculationFactory as BarChartCalculationFactory; var drawableFactory = mainDrawableFactory as BarDrawableFactory; var paint = drawableFactory.CreateBarPaint(value); var shape = new Bar(canvas) { Paint = paint, Rect = drawableFactory.CreateBarRect(value), LabelPosition = drawableFactory.CreateLabelPointPosition(value), ValuePosition = drawableFactory.CreateValuePointPosition(value), SerieValue = value }; return(shape); }
public override float CalculateRight(SeriesValue value) { var percentage = Math.Abs(value.Value / (chart.MaxEntryValue / AvaibleWidth) * 100 / AvaibleWidth); if (!chart.HasNegativeValues) { var increase = Math.Abs(percentage * AvaibleWidth / 100); increase += AxisY; return(increase); } else { var middlePoint = (AvaibleWidth / 2); var increase = Math.Abs((percentage * middlePoint) / 100); var direction = value.Value > 0 ? increase : -increase; var result = AxisY + direction; return(result); } }
public override float CalculateTop(SeriesValue value) => throw new NotImplementedException();
public float CalculateSweepAngle(SeriesValue seriesValue) => 360f * seriesValue.Value / chart.Series.Sum(x => x.Value);
/// <summary> /// Gets the records from the file. This uses an alogrythm to increase data quality. /// </summary> /// <param name="inBegin">The begin of the period to read from the file.</param> /// <param name="inEnd">The end of the period to read from the file.</param> /// <param name="inUnit">The unit that the records will contain</param> /// <param name="ioSlots">A list of series values that are used to put the records in. This allows for empty "buckets" /// so the caller can always expect a correct period division in the resolution that was given. The series value can have /// values from othe counters (combined devices) /// see the SeriesValue for more info</param> /// <param name="inNegate">In case the call is made from a Device that has multiple counters and this is a negative counter /// the values are negated in the resulting seriesvalue</param> /// <returns></returns> public bool GetRecords(DateTime inBegin, DateTime inEnd, Unit inUnit, IList <SeriesValue> ioSlots, bool inNegate) { inBegin = inBegin.TruncateToMinute(); inEnd = inEnd.TruncateToMinute(); if (inBegin > inEnd) { throw new ArgumentOutOfRangeException("inBegin", "begin before end"); } _logger.LogTrace("GetRecords(begin = {0}, end = {1}, counter = {2}, path = {3}, refdate = {4})", inBegin, inEnd, _context.CounterId, GetFilePath(), _context.ReferenceDate); if (!FileExists) { _logger.LogWarning("File does not exist {0}", GetFilePath()); return(false); } SeriesValue previousSlot = null; Record previousLast = null; foreach (var currentSlot in ioSlots) { _logger.LogTrace("process slot {0} - {1}", currentSlot.Begin, currentSlot.End); var beginTime = currentSlot.Begin < inBegin ? inBegin : currentSlot.Begin; var endTime = currentSlot.End > inEnd ? inEnd : (currentSlot.End < beginTime ? beginTime : currentSlot.End); _logger.LogTrace("beginTime = {0}, endTime = {1}", beginTime, endTime); Record first; // Optimization: use previous last value if the end of the previous slot is the start of the current slot, // this prevents an unneeded extra file read. if (previousSlot != null && previousLast != null && previousLast.IsValidMeasurement && previousSlot.End == beginTime) { first = previousLast; } else { first = beginTime < StartOfFile?GetClosestValue(StartOfFile, true) : GetValue(beginTime); } // When for some reason the value contains an invalid measurement, search for the next valid measurement. if (first != null && !first.IsValidMeasurement) { first = GetClosestValue(beginTime, true); if (first != null && first.Time > endTime) { continue; } } _logger.LogTrace("first = {0}", first != null ? first.Raw.ToString(CultureInfo.InvariantCulture) : "null"); // todo (evalueren): als eerste waarde niet gevonden wordt heeft verder zoeken geen zin??!! if (first == null) { break; } var lastAllowedTimestamp = _context.ReferenceDate < EndOfFile ? _context.ReferenceDate : EndOfFile; var last = endTime > lastAllowedTimestamp?GetClosestValue(lastAllowedTimestamp, false) : GetValue(endTime); _logger.LogTrace("last = {0}", last != null ? last.Raw.ToString() : "null"); // Bij dag of maand resolution zoeken naar dichtsbijzijnde waarde indien first en last geen waarde heeft (qplat-73) if (first.Time <= endTime && first.IsValidMeasurement && (last == null || !last.IsValidMeasurement) && ((currentSlot.End - currentSlot.Begin).TotalDays >= 1.0)) { last = GetClosestValue(endTime, false); } if ((last != null && beginTime < EndOfFile && first.Time < last.Time) && (first.IsValidMeasurement) && (last.IsValidMeasurement)) { var delta = CalculateDelta(first, last, inUnit); _logger.LogTrace("delta = {0}", delta); currentSlot.Value = Convert.ToDecimal(inNegate ? delta * -1m : delta); if (endTime > EndOfFile) { break; } } previousSlot = currentSlot; previousLast = last; } if (_logger.IsEnabled(LogLevel.Debug)) { foreach (var seriesValue in ioSlots) { _logger.LogDebug("{0} - {1} : {2}", seriesValue.Begin, seriesValue.End, seriesValue.Value); } } _logger.LogTrace("Exit"); return(true); }
public abstract float CalculateRight(SeriesValue value);
public float CalculateLabelXAxis(SeriesValue value) => chart.Series.IndexOf(value) % 2 == 0 ? MarginX : chart.CanvasSize.Width - 20;
public float CalculatePercentage(SeriesValue value) => value.Value * 100 / chart.Series.Sum(x => x.Value);
private static void AddSerieToResult(ValueSerie inSerie, List <ValueSerie> ioResultSeries, DeviceEnergyType?inSecondaryEnergyType) { if (inSerie.Data == null) { return; } if (ioResultSeries.Any(s => s.EnergyType == inSerie.EnergyType)) { var existingSerie = ioResultSeries.First(s => s.EnergyType == inSerie.EnergyType); var serieIndexFinder = new SerieIndexFinder(existingSerie.Data); foreach (var slotToAdd in inSerie.Data) { var index = serieIndexFinder.GetIndex(slotToAdd.Begin); if (index < 0) { existingSerie.Data.Add(slotToAdd); } else { var slot = existingSerie.Data[index]; if (!slot.Value.HasValue || slot.Value == 0) { slot.Value = slotToAdd.Value; } else { slot.Value += slotToAdd.Value ?? 0; } } } existingSerie.Total = existingSerie.Data.Sum(d => d.Value ?? 0); } else { ioResultSeries.Add(inSerie); } // used to accumulate series to one type: if (inSecondaryEnergyType.HasValue) { var serie = new ValueSerie() { EnergyType = inSecondaryEnergyType.Value, Name = inSerie.Name, Data = new List <SeriesValue>() }; foreach (var data in inSerie.Data) { var seriesValue = new SeriesValue() { Begin = new DateTime(data.Begin.Ticks), End = new DateTime(data.End.Ticks), Value = data.Value }; serie.Data.Add(seriesValue); } serie.Total = serie.Data.Sum(d => d.Value ?? 0); AddSerieToResult(serie, ioResultSeries, null); } }
public abstract float CalculateTop(SeriesValue value);