//find where in graph image each values would correspond to and add this info to a new array
        private List<DataPoint> FillOffsetList(HeartbeatMeasurement[] dataSet, RenderingOptions options, float Width, float Height)
        {
            if (dataSet == null || dataSet.Length <= 0)
            {
                return null;
            }

            var valueDiff = options.MaxValue - options.MinValue;
            float tickOffset = (Width / dataSet.Length);

            List<DataPoint> offsetList = new List<DataPoint>();

            float currentOffset = 0;

            for (int i = 0; i < dataSet.Length; i++)
            {
                var currentDiff = options.MaxValue - dataSet[i].HeartbeatValue;

                offsetList.Add(new DataPoint
                {
                    OffsetX = currentOffset,
                    OffsetY = (currentDiff / valueDiff) * Height,
                    Value = dataSet[i].HeartbeatValue //just in case we would have functionality to show the actual value, we'll store  it here
                });
                currentOffset += tickOffset;
            }

            return offsetList;
        }
        //draws the value texts
        private void DrawYAxisTexts(CanvasDrawingSession ds, float height, RenderingOptions options)
        {
            // if needed do add CanvasTextFormat
            ds.DrawText(options.MaxValueBuffered.ToString("#.#"), new Vector2(RIGHT_TEXT_MARGIN, 0), VALUESTEXT_COLOR);
            var percent = (options.MaxValueBuffered - options.MinValueBuffered) * (1.0 / (DEFAULT_GRADIENTS));

            for (int i = 1; i < DEFAULT_GRADIENTS; i++)
            {
                var percentVal = options.MaxValueBuffered - (percent * i);
                // do add CanvasTextFormat
                ds.DrawText(percentVal.ToString("#.#"), new Vector2(RIGHT_TEXT_MARGIN, (i * (height / DEFAULT_GRADIENTS))), VALUESTEXT_COLOR);
            }

            // do add CanvasTextFormat
            ds.DrawText(options.MinValueBuffered.ToString("#.#"), new Vector2(RIGHT_TEXT_MARGIN, (height - BOTTOM_TEXT_MARGIN)), VALUESTEXT_COLOR);
        }
        private void DrawCharData(CanvasDevice device, RenderingOptions options, HeartbeatMeasurement[] data)
        {
            //Size restrictions descriped in : http://microsoft.github.io/Win2D/html/P_Microsoft_Graphics_Canvas_CanvasDevice_MaximumBitmapSizeInPixels.htm
            float useHeight = (float)ChartWin2DCanvas.Size.Height > device.MaximumBitmapSizeInPixels ? device.MaximumBitmapSizeInPixels : (float)ChartWin2DCanvas.Size.Height;
            float useWidth = data.Length > device.MaximumBitmapSizeInPixels ? device.MaximumBitmapSizeInPixels : data.Length;

            //this will change the values array to array with drawing-line-points for the graph
            List<DataPoint> dataList = FillOffsetList(data, options, useWidth, useHeight);

            //reset zoom & moving values
            _zoomFactor = 100;
            _graphDrawingPoint = new Point(0, 0);
            _graphDrawingSource = new Size(useWidth, useHeight);
            //create the graph image
            _offscreenChartImage = new CanvasRenderTarget(device, useWidth, useHeight, 96);

            using (CanvasDrawingSession ds = _offscreenChartImage.CreateDrawingSession())
            {
                //This creates drawing geometry from the drawing-line-points
                CanvasGeometry chart = getDrawChartGeometry(device, dataList);
                //and then we simply draw it with defined color
                ds.DrawGeometry(chart, 0, 0, GRAPG_COLOR);
            }
        }
        private void DrawBackGround(CanvasDevice device, RenderingOptions options)
        {
            float useHeight = (float)ChartWin2DCanvas.Size.Height;
            float useWidth = (float)ChartWin2DCanvas.Size.Width;

            //this is always drawn in the size of control, so all texts drawn in it are sharp
            _offscreenBackGround = new CanvasRenderTarget(device, useWidth, useHeight, 96);

            using (CanvasDrawingSession ds = _offscreenBackGround.CreateDrawingSession())
            {
                ds.Clear(BACKGROUND_COLOR);
                //draw lines
                DrawGraphValueLines(ds, useWidth, useHeight);
                //draw value texts
                DrawYAxisTexts(ds, useHeight, options);
            }
        }
        private RenderingOptions CreateRenderingOptions(HeartbeatMeasurement[] dataSet)
        {
            RenderingOptions renderingOptions = null;
            if (dataSet != null)
            {
                renderingOptions = new RenderingOptions();
                //set initial end-of-range values
                renderingOptions.MinValue = double.MaxValue;
                renderingOptions.MaxValue = double.MinValue;

                //find if we have bigger or smaller than what we have with current values
                for (int i = 0; i < dataSet.Length; i++)
                {
                    renderingOptions.MinValue = Math.Min(dataSet[i].HeartbeatValue, renderingOptions.MinValue);
                    renderingOptions.MaxValue = Math.Max(dataSet[i].HeartbeatValue, renderingOptions.MaxValue);
                }

                //and see if default values are more suitable
                if (renderingOptions.MinValue > MIN_VALUE_DEFAULT)
                {
                    renderingOptions.MinValue = MIN_VALUE_DEFAULT;
                }

                if (renderingOptions.MaxValue < MAX_VALUE_DEFAULT)
                {
                    renderingOptions.MaxValue = MAX_VALUE_DEFAULT;
                }

                var valueDiff = renderingOptions.MaxValue - renderingOptions.MinValue;
                var diffBuffer = (valueDiff > 0) ? (valueDiff * 0.1) : 2;
                //values used with value texts
                renderingOptions.MaxValueBuffered = renderingOptions.MaxValue + diffBuffer;
                renderingOptions.MinValueBuffered = renderingOptions.MinValue - diffBuffer;
                renderingOptions.MinValueBuffered = (renderingOptions.MinValueBuffered > 0) ? renderingOptions.MinValueBuffered : 0;
            }

            return renderingOptions;
        }
        private int CreateRenderingOptions()
        {
            int startIndex = 0;
            _renderingOptions = null;
            if (_data != null)
            {
                _renderingOptions = new RenderingOptions();
                _renderingOptions.MinValue = double.MaxValue;
                _renderingOptions.MaxValue = double.MinValue;

                startIndex = (_data.Length  < DataPointCount) ? 0 : _data.Length - DataPointCount;

                System.Diagnostics.Debug.WriteLine("startIndex : " + startIndex + ", DataPointCount : " + DataPointCount + ", _data.Length : " + _data.Length);

                for (int i = startIndex; i < _data.Length; i++)
                {
                    _renderingOptions.MinValue = Math.Min(_data[i].HeartbeatValue, _renderingOptions.MinValue);
                    _renderingOptions.MaxValue = Math.Max(_data[i].HeartbeatValue, _renderingOptions.MaxValue);
                }

                if (_renderingOptions.MinValue > MIN_VALUE_DEFAULT)
                {
                    _renderingOptions.MinValue = MIN_VALUE_DEFAULT;
                }

                if (_renderingOptions.MaxValue < MAX_VALUE_DEFAULT)
                {
                    _renderingOptions.MaxValue = MAX_VALUE_DEFAULT;
                }

                var valueDiff = _renderingOptions.MaxValue - _renderingOptions.MinValue;

                var diffBuffer = (valueDiff > 0) ? (valueDiff * 0.1) : 2;
                _renderingOptions.MaxValueBuffered = _renderingOptions.MaxValue + diffBuffer;
                _renderingOptions.MinValueBuffered = _renderingOptions.MinValue - diffBuffer;
                _renderingOptions.MinValueBuffered = (_renderingOptions.MinValueBuffered > 0) ? _renderingOptions.MinValueBuffered : 0;
            }

            return startIndex;
        }