Beispiel #1
0
        private void LineChart_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
        {
            if (ChartEntries?.Any() != true)
            {
                return;
            }

            var info   = e.Info;
            var canvas = e.Surface.Canvas;

            canvas.Clear();

            var frame = CreateFrame(info);
            var chart = CreateChart(frame);

            DrawFrame(canvas, frame);
            DrawVerticalLabels(canvas, frame, chart);

            if (ChartEntries.Any(x => x.IsVisible))
            {
                CalculateChartValuesXPoints(chart);

                foreach (var entry in ChartEntries.Where(x => x.IsVisible).OrderByDescending(x => x.Items.Count()))
                {
                    CalculatePoints(entry.Items, frame, chart);
                }

                DrawBars(canvas, frame, chart);
            }

            DrawHorizontalLabels(canvas, frame, chart);
        }
Beispiel #2
0
        protected void DrawHorizontalLabels(SKCanvas canvas, SKRect frame, SKRect chart)
        {
            if (HorizontalLabelMode != LabelMode.None)
            {
                if (!string.IsNullOrEmpty(MinLabel) && !string.IsNullOrEmpty(MaxLabel))
                {
                    canvas.DrawHorizontalText(MinLabel, chart.Left, frame.Bottom + HorizontalLabelTextSize, HorizontalLabelTextSize, HorizontalLabelColor.ToSKColor(), SKTextAlign.Center, isBold: true);
                    canvas.DrawHorizontalText(MaxLabel, chart.Right, frame.Bottom + HorizontalLabelTextSize, HorizontalLabelTextSize, HorizontalLabelColor.ToSKColor(), SKTextAlign.Center, isBold: true);
                }
            }

            if (!string.IsNullOrEmpty(HorizontalUnit))
            {
                canvas.DrawHorizontalText(HorizontalUnit, chart.Right, frame.Bottom + (HorizontalLabelTextSize * 2), HorizontalLabelTextSize, HorizontalLabelColor.ToSKColor(), SKTextAlign.Left);
            }

            if (DisplayHorizontalValuesBySlider && IsSliderVisible)
            {
                var x = ChartType == ChartType.Linear ? TouchedPoint.X : chart.GetInsideXValue(TouchedPoint.X);

                var valueItems = ChartEntries.GetChartValueItemFromX(x, frame, MaxItems, ChartType == ChartType.Linear);

                var entry = valueItems?.FirstOrDefault()?.ChartValueItem;

                if (string.IsNullOrEmpty(entry?.Label))
                {
                    return;
                }

                x = ChartType == ChartType.Linear ? chart.GetInsideXValue(TouchedPoint.X) : entry.Point.X;

                canvas.DrawHorizontalText(entry.Label, x, frame.Bottom + HorizontalLabelTextSize, HorizontalLabelTextSize, SliderColor.ToSKColor(), SKTextAlign.Center, isBold: true);
            }
            else if (HorizontalLabelMode == LabelMode.All)
            {
                var items = ChartValuesDistinct;

                if (items?.Any() != true)
                {
                    return;
                }

                var points = ChartEntries.FirstOrDefault().Items.Select(x => x.Point).ToArray();

                for (int i = 0; i < items.Count(); i++)
                {
                    var entry = items.ElementAt(i);
                    var point = points[i];

                    if (string.IsNullOrEmpty(entry?.Label) || entry?.Label == MinLabel || entry?.Label == MaxLabel)
                    {
                        continue;
                    }

                    canvas.DrawHorizontalText(entry.Label, point.X, frame.Bottom + HorizontalLabelTextSize, HorizontalLabelTextSize, HorizontalLabelColor.ToSKColor(), SKTextAlign.Center);
                }
            }
        }
Beispiel #3
0
        public ChartEntryEntity FindOrCreateEntry(TradingSymbol symbol, ChartRange range)
        {
            var entry = ChartEntries.Where(ce => ce.Symbol == symbol.Symbol && ce.Range == range).FirstOrDefault();

            if (entry == null)
            {
                entry = new ChartEntryEntity()
                {
                    Symbol = symbol.Symbol,
                    Range  = range,
                };
                ChartEntries.AddAsync(entry);
                SaveChangesAsync();
            }
            return(entry);
        }
Beispiel #4
0
        private void SnapToClosestBar(double position, GroupChartItem selectedItem)
        {
            var selectedValues = new SelectedChartValueItemArgs
            {
                ChartValueItems = new List <ChartValueItemParam>(),
                TouchedPoint    = TouchedPoint
            };

            foreach (var chartEntry in ChartEntries.Where(x => x.IsVisible))
            {
                var chartEntryItem = chartEntry.Items.FirstOrDefault(i => i.Tag.ToString() == selectedItem.Tag.ToString());

                if (chartEntryItem == null)
                {
                    continue;
                }

                selectedValues.ChartValueItems.Add(new ChartValueItemParam(chartEntryItem, null, chartEntry));
            }

            // Invoke command with selected items
            SelectedValuesCommand?.Execute(selectedValues);

            Device.BeginInvokeOnMainThread(async() =>
            {
                isSnapping = true;

                ScrollComponent.Scrolled -= ScrollComponent_Scrolled;

                SelectedLabel = selectedItem.Label;

                lastScrollPosition = position;

                await ScrollComponent.ScrollToAsync(lastScrollPosition, 0, false);

                ShowSwipeNotifications(lastScrollPosition);

                ScrollComponent.Scrolled += ScrollComponent_Scrolled;

                isSnapping = false;
            });
        }
Beispiel #5
0
        protected void ShowSliderValuesPosition(SKCanvas canvas, SKRect frame)
        {
            if (!IsSliderVisible)
            {
                return;
            }

            var valueItems = ChartEntries.GetChartValueItemFromX(TouchedPoint.X, frame, MaxItems);

            if (valueItems?.Any() != true)
            {
                return;
            }

            int index = 0;

            foreach (var item in valueItems)
            {
                canvas.DrawSliderCircle(item.ChartValueItem.Point.X, item.ChartValueItem.Point.Y, item.Color, this.SliderPointSize);

                string text = Math.Round(double.Parse(item.ChartValueItem.Value.ToString()), 0, MidpointRounding.AwayFromZero).ToString() + " " + this.VerticalUnit;

                canvas.DrawSliderValue(
                    text,
                    frame.GetInsideXValue(TouchedPoint.X),
                    frame.Top,
                    SliderDetailTextSize,
                    SKColors.White,
                    item.Color,
                    SliderDetailPadding,
                    SliderDetailMargin,
                    MaxValue + " " + this.VerticalUnit,
                    valueItems.Count,
                    index,
                    SliderDetailOrientation,
                    frame,
                    item.Parent?.UseDashedEffect == true);

                index++;
            }
        }
Beispiel #6
0
        private void DrawSlider(SKCanvas canvas, SKRect frame, SKRect chart)
        {
            if (!IsSliderVisible)
            {
                return;
            }

            if (!IsInitialized)
            {
                FindClosestItem(TouchedPoint.X);
            }

            float x = chart.GetInsideXValue(TouchedPoint.X);

            using (var paint = new SKPaint
            {
                Style = SKPaintStyle.Stroke,
                StrokeCap = UseItemWidthSlider ? SKStrokeCap.Butt : SKStrokeCap.Round,
                Color = this.SliderColor.ToSKColor().AsTransparency(),
                StrokeWidth = UseItemWidthSlider ? frame.GetItemWidth(MaxItems) : this.SliderWidth
            })
            {
                // Straight slider line
                canvas.DrawLine(x, chart.Top, x, DisplayHorizontalValuesBySlider && !UseItemWidthSlider ? frame.Bottom + HorizontalTextSize : chart.Bottom, paint);

                DrawSliderHint(canvas, x);
            }

            // Get items on x axis
            var valueItems = ChartEntries.GetChartValueItemFromX(x, frame, frame.GetItemWidth(MaxItems));

            // Send selected items with command
            SelectedValuesCommand?.Execute(new SelectedChartValueItemArgs
            {
                ChartValueItems = valueItems,
                TouchedPoint    = new SKPoint(x, TouchedPoint.Y)
            });
        }
Beispiel #7
0
        private void LineChart_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
        {
            if (ChartEntries?.Any() != true)
            {
                return;
            }

            var info   = e.Info;
            var canvas = e.Surface.Canvas;

            canvas.Clear();

            var frame = CreateFrame(info);
            var chart = CreateChart(frame);

            if (!IsInitialized)
            {
                // Makes slider first init in middle of frame
                TouchedPoint = new SKPoint(frame.MidX, 0);
            }

            DrawVerticalLabels(canvas, frame, chart);

            if (ChartEntries.Any(x => x.IsVisible))
            {
                CalculateChartValuesXPoints(chart);

                DrawBackground(canvas, frame);
                DrawInnerFrame(canvas, frame);

                if (!string.IsNullOrEmpty(SelectedTag) && !isTouching)
                {
                    var selectedTagPosition = ChartValueItemsXPoints.FirstOrDefault(x => x.Item1.ToString() == SelectedTag)?.Item2 ?? 0f;

                    TouchedPoint = new SKPoint(selectedTagPosition, 0f);
                }

                DrawSlider(canvas, frame, chart);

                foreach (var entry in ChartEntries.Where(x => x.IsVisible).OrderByDescending(x => x.Items.Count()))
                {
                    DrawLines(entry, canvas, CalculatePoints(entry.Items, frame, chart));
                }

                DrawHorizontalLabels(canvas, frame, chart);

                // Get items on x axis
                var valueItems = ChartEntries.GetChartValueItemFromX(chart.GetInsideXValue(TouchedPoint.X), frame, frame.GetItemWidth(MaxItems));

                // Send selected items with command
                SelectedValuesCommand?.Execute(new SelectedChartValueItemArgs
                {
                    ChartValueItems = valueItems,
                    TouchedPoint    = new SKPoint(chart.GetInsideXValue(TouchedPoint.X), TouchedPoint.Y)
                });

                DrawHorizontalLabel(valueItems?.FirstOrDefault()?.ChartValueItem, canvas, frame, chart);

                DrawFrame(canvas, frame);

                DrawSliderPoints(valueItems, canvas, chart);
            }
            else
            {
                DrawInnerFrame(canvas, frame);
                DrawFrame(canvas, frame);
            }

            IsInitialized = true;
        }
Beispiel #8
0
        private void DrawBars(SKCanvas canvas, SKRect frame, SKRect chart)
        {
            // Selected bar width
            var selectedValueItems = ChartEntries.GetChartValueItemFromX(chart.GetInsideXValue(TouchedPoint.X), chart, chart.GetItemWidth(MaxItems));
            var selectedTags       = selectedValueItems?.Select(x => x.ChartValueItem.Tag);

            // Invoke command with selected items
            SelectedValuesCommand?.Execute(new SelectedChartValueItemArgs
            {
                ChartValueItems = selectedValueItems,
                TouchedPoint    = new SKPoint(chart.GetInsideXValue(TouchedPoint.X), TouchedPoint.Y)
            });

            using (var paint = new SKPaint
            {
                IsAntialias = true,
                Style = SKPaintStyle.StrokeAndFill,
                StrokeCap = SKStrokeCap.Butt,
            })
            {
                var groupedItems = ChartEntries.Where(x => x.IsVisible).SelectMany(x => x.Items).GroupBy(x => x.Tag.ToString()).OrderBy(x => x.Key);

                // Calc max items in one group
                var maxItemsInGroups = groupedItems.Max(x => x.Count());

                // Calc how many groups there is
                var groupCount = groupedItems.Count();

                // Calc how many bars there will be
                var totalBars = groupCount * maxItemsInGroups;

                var internalGroupMargin = maxItemsInGroups == 1 ? BarMargin : GroupMargin;
                var internalBarMargin   = maxItemsInGroups == 1 ? 0 : BarMargin;
                var internalBarWidth    = MinimumBarWidth;

                float itemWidth;

                if (AllowScroll)
                {
                    // Calc total item width
                    itemWidth = internalBarWidth * maxItemsInGroups + ((maxItemsInGroups - 1) * barMargin);
                }
                else
                {
                    itemWidth = chart.Width / groupCount;

                    itemWidth -= internalGroupMargin;

                    internalBarWidth = (itemWidth / maxItemsInGroups) - ((maxItemsInGroups - 1) * barMargin);
                }

                int groupIndex = 0;

                float scrollLeftPadding = 0;
                float left      = 0;
                float groupLeft = 0;
                float right     = 0;

                groupCenters = new List <GroupChartItem>();

                foreach (var groupedItem in groupedItems)
                {
                    int itemIndex = 0;

                    groupLeft = left;

                    if (!AllowScroll && IsSliderVisible && selectedTags?.Contains(groupedItem.Key) == true)
                    {
                        var item = groupedItem.OrderByDescending(x => x.Value).First();

                        paint.Color      = SliderColor.ToSKColor();
                        paint.PathEffect = SKPathEffect.CreateCorner(SliderCornerRadius);

                        var bounds = new SKRect(
                            item.Point.X - (itemWidth * .5f) - (groupMargin * .5f),
                            item.Point.Y - (itemWidth * .5f),
                            item.Point.X + (itemWidth * .5f) + (groupMargin * .5f),
                            chart.Bottom + HorizontalTextSize);

                        paint.StrokeWidth = 0;

                        canvas.DrawRect(bounds, paint);
                    }

                    foreach (var item in groupedItem)
                    {
                        var parent = ChartEntries.FirstOrDefault(x => x.Items.Contains(item));

                        SKRect bounds = new SKRect();

                        if (AllowScroll)
                        {
                            if (left == 0)
                            {
                                left = itemWidth.FromDpiAdjusted();

                                groupLeft = left;

                                scrollLeftPadding = left;
                            }
                            else if (itemIndex != 0)
                            {
                                left += internalBarMargin;
                            }

                            right = left + internalBarWidth;

                            bounds = new SKRect(
                                left,
                                item.Point.Y,
                                right,
                                chart.Bottom);

                            left = right;
                        }
                        else
                        {
                            left  = (item.Point.X - (itemWidth * .5f)) + (internalBarWidth * itemIndex) + (internalBarMargin * itemIndex);
                            right = left + internalBarWidth;

                            bounds = new SKRect(
                                left,
                                item.Point.Y,
                                right,
                                chart.Bottom);
                        }

                        paint.StrokeWidth = 0;

                        if (parent.UseDashedEffect)
                        {
                            paint.Color      = parent.Color.ToSKColor().AsTransparency();
                            paint.PathEffect = SKPathEffect.CreateCorner(BarCornerRadius);

                            canvas.DrawRect(bounds, paint);

                            paint.Color      = parent.Color.ToSKColor();
                            paint.PathEffect = SKPathEffect.CreateDash(new float[] { StrokeDashFirst, StrokeDashSecond }, StrokeDashPhase);

                            paint.StrokeWidth = bounds.Width;

                            canvas.DrawLine(bounds.MidX, bounds.Bottom, bounds.MidX, bounds.Top, paint);
                        }
                        else
                        {
                            paint.Color      = parent.Color.ToSKColor();
                            paint.PathEffect = SKPathEffect.CreateCorner(BarCornerRadius);
                            canvas.DrawRect(bounds, paint);
                        }

                        itemIndex++;
                    }

                    left += internalGroupMargin;

                    groupIndex++;

                    var groupCenterPosition = groupLeft + (itemWidth / 2);

                    groupCenters.Add(new GroupChartItem
                    {
                        Label    = groupedItem.FirstOrDefault().Label,
                        Position = groupCenterPosition.FromDpiAdjusted(),
                        Tag      = groupedItem.Key
                    });
                }

                if (AllowScroll)
                {
                    var requestedWidth = right.FromDpiAdjusted() + frame.Left.FromDpiAdjusted();

                    if (requestedWidth != this.WidthRequest)
                    {
                        this.WidthRequest = requestedWidth;
                    }
                    else
                    {
                        SetStartPosition(groupCenters);
                        IsInitialized = true;
                    }

                    if (ScrollComponent != null)
                    {
                        var deviceWidth = Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Width;

                        var halfDeviceWidth = ((float)(deviceWidth / 2)).FromDpiAdjusted();

                        var frameLeftVal       = frame.Left.FromDpiAdjusted();
                        var rectRightMarginVal = ChartRectMargin.Right.FromDpiAdjusted();

                        var leftPadding = halfDeviceWidth - frameLeftVal - scrollLeftPadding.FromDpiAdjusted();

                        var rightPadding = halfDeviceWidth - frameLeftVal - rectRightMarginVal - itemWidth.FromDpiAdjusted();

                        ScrollComponent.Padding = new Thickness(leftPadding, 0, rightPadding, 0);
                        ScrollComponent.Margin  = new Thickness(frame.Left.FromDpiAdjusted(), 0, ChartRectMargin.Right.FromDpiAdjusted(), 0);

                        if (Selector != null)
                        {
                            Selector.WidthRequest = itemWidth.FromDpiAdjusted();
                            Selector.Margin       = new Thickness(halfDeviceWidth, 0, 0, this.Height - frame.Bottom.FromDpiAdjusted());
                        }

                        if (!isScrollEventActive)
                        {
                            ScrollComponent.Scrolled += ScrollComponent_Scrolled;
                            isScrollEventActive       = true;
                        }
                    }

                    if (SwipeNotificationLeft != null)
                    {
                        SwipeNotificationLeft.Margin       = new Thickness(frame.Left.FromDpiAdjusted(), 0, 0, this.Height - frame.Bottom.FromDpiAdjusted());
                        SwipeNotificationLeft.WidthRequest = ScrollComponent.Padding.Left;
                    }

                    if (SwipeNotificationRight != null)
                    {
                        SwipeNotificationRight.Margin       = new Thickness(0, 0, ChartRectMargin.Right.FromDpiAdjusted(), this.Height - frame.Bottom.FromDpiAdjusted());
                        SwipeNotificationRight.WidthRequest = ScrollComponent.Padding.Left;
                    }
                }
            }

            DrawHorizontalLabel(selectedValueItems?.FirstOrDefault()?.ChartValueItem, canvas, frame, chart);
        }
Beispiel #9
0
        protected void ShowExactSliderValuesPosition(SKCanvas canvas, SKRect frame)
        {
            if (!IsSliderVisible)
            {
                return;
            }

            var valueItems = ChartEntries.GetChartValueItemFromX(TouchedPoint.X, frame, MaxItems);

            if (valueItems?.Any() != true)
            {
                return;
            }

            int index = 0;

            foreach (var item in valueItems)
            {
                var chartEntry = item.ChartValueItem;

                var nextChartEntry = item.NextChartValueItem;

                float y, points;

                if (nextChartEntry != null)
                {
                    // Difference in value
                    var diffVal = nextChartEntry.Value - chartEntry.Value;

                    // Difference in Y position
                    var diffY = nextChartEntry.Point.Y - chartEntry.Point.Y;

                    // Difference in X position
                    var diffX = nextChartEntry.Point.X - chartEntry.Point.X;

                    var yValue = diffVal / diffY;
                    var xValue = diffVal / diffX;

                    // Current X position over first item
                    var x = TouchedPoint.X - chartEntry.Point.X;
                    points = x * xValue;

                    y = (points / yValue) + chartEntry.Point.Y;
                }
                else
                {
                    y      = chartEntry.Point.Y;
                    points = chartEntry.Value;
                }

                canvas.DrawSliderCircle(frame.GetInsideXValue(TouchedPoint.X), y, item.Color, SliderPointSize);

                float currentVal = 0;

                if (nextChartEntry != null)
                {
                    try
                    {
                        currentVal = chartEntry.Value + (int)Math.Round(decimal.Parse(points.ToString()), 0, MidpointRounding.AwayFromZero);
                    }
                    catch (Exception ex)
                    {
                        ex.Print();
                    }

                    if (TouchedPoint.X == chartEntry.Point.X)
                    {
                        currentVal = chartEntry.Value;
                    }
                    else if (TouchedPoint.X == nextChartEntry?.Point.X)
                    {
                        currentVal = nextChartEntry.Value;
                    }
                }
                else
                {
                    currentVal = chartEntry.Value;
                }

                string text = currentVal.ToString() + " " + this.VerticalUnit;

                canvas.DrawSliderValue(
                    text,
                    frame.GetInsideXValue(TouchedPoint.X),
                    frame.Top,
                    SliderDetailTextSize,
                    SKColors.White,
                    item.Color,
                    SliderDetailPadding,
                    SliderDetailMargin,
                    MaxValue + " " + VerticalUnit,
                    valueItems.Count,
                    index,
                    SliderDetailOrientation,
                    frame,
                    item.Parent?.UseDashedEffect == true);

                index++;
            }
        }
Beispiel #10
0
        private void DrawBars(SKCanvas canvas, SKRect frame, SKRect chart)
        {
            var itemWidth = (MaxItems >= 12 ? chart.GetItemWidth(MaxItems) : chart.GetItemWidth(12)) / 2;
            var count     = ChartEntries.Count(x => x.IsVisible);

            // Regular bar width
            var barWidth = (itemWidth / count) - 10;

            // Selected bar width
            var selectedValueItems = ChartEntries.GetChartValueItemFromX(chart.GetInsideXValue(TouchedPoint.X), chart, MaxItems, false);
            var selectedTags       = selectedValueItems?.Select(x => x.ChartValueItem.Tag);

            int index = 0;

            foreach (var item in ChartEntries.Where(x => x.IsVisible))
            {
                foreach (var valueItem in item.Items.Where(x => selectedTags?.Contains(x.Tag) != true))
                {
                    // Draw not selected bars //

                    canvas.DrawBar(
                        valueItem.Point.X,
                        valueItem.Point.Y,
                        chart.Bottom,
                        barWidth,
                        BarMargin,
                        count,
                        index,
                        IsSliderVisible ? item.Color.ToSKColor().AsTransparency() : item.Color.ToSKColor(),
                        item.UseDashedEffect);
                }

                index++;
            }

            if (!IsSliderVisible)
            {
                return;
            }

            count    = selectedValueItems?.Count() ?? 1;
            barWidth = (itemWidth / selectedValueItems?.Count() ?? 1) + 10;

            index = 0;

            foreach (var item in ChartEntries.Where(x => x.IsVisible))
            {
                var valueItems = item.Items.Where(x => selectedTags?.Contains(x.Tag) == true);

                if (valueItems?.Any() != true)
                {
                    continue;
                }

                foreach (var valueItem in valueItems)
                {
                    canvas.DrawBar(
                        valueItem.Point.X,
                        valueItem.Point.Y,
                        chart.Bottom,
                        barWidth,
                        BarMargin,
                        count,
                        index,
                        item.Color.ToSKColor(),
                        item.UseDashedEffect);

                    string text = Math.Round(double.Parse(valueItem.Value.ToString()), 0, MidpointRounding.AwayFromZero).ToString() + " " + this.VerticalUnit;

                    canvas.DrawSliderValue(
                        text,
                        frame.GetInsideXValue(valueItem.Point.X),
                        frame.Top,
                        SliderDetailTextSize,
                        SKColors.White,
                        item.Color.ToSKColor(),
                        SliderDetailPadding,
                        SliderDetailMargin,
                        MaxValue + " " + this.VerticalUnit,
                        selectedValueItems.Count,
                        index,
                        SliderDetailOrientation,
                        frame,
                        item.UseDashedEffect);
                }

                index++;
            }


            float hintX = selectedValueItems?.FirstOrDefault()?.ChartValueItem?.Point.X ?? 0;
            float hintY = selectedValueItems?.OrderByDescending(x => x.ChartValueItem.Point.Y)?.FirstOrDefault()?.ChartValueItem?.Point.Y ?? 0;

            if (hintX != 0 && hintY != 0)
            {
                DrawDragHintGraphic(
                    canvas,
                    hintX,
                    hintY + ((frame.Bottom - hintY) / 2),
                    (barWidth * count),
                    frame);
            }
        }