Example #1
0
        public override IChartInteractiveObject LoadObject(XmlElement objectNode, CandleChartControl owner, bool trimObjectsOutOfHistory = false)
        {
            var obj = new ChartEllipse();

            obj.LoadFromXML(objectNode, owner);
            obj.Owner = this;
            data.Add(obj);
            return(obj);
        }
Example #2
0
        protected override void OnMouseDown(List <SeriesEditParameter> parameters,
                                            MouseEventArgs e, Keys modifierKeys, out IChartInteractiveObject objectToEdit)
        {
            objectToEdit = null;
            if (e.Button != MouseButtons.Left)
            {
                return;
            }
            // получить время и цену
            var pointD        = Chart.Owner.MouseToWorldCoords(e.X, e.Y);
            var editedEllipse = data.FirstOrDefault(el => el.IsBeingCreated);

            var shiftPressed   = (Control.ModifierKeys & Keys.Shift) == Keys.Shift;
            var controlPressed = (Control.ModifierKeys & Keys.Control) == Keys.Control;

            if (editedEllipse == null)
            {// начинается редактирование - выбрана первая точка
                var lineColor    = SeriesEditParameter.TryGetParamValue(parameters, "Stroke", Color.Black);
                var buildAuto    = SeriesEditParameter.TryGetParamValue(parameters, "ByTwoPoints", false) ^ controlPressed;
                var buildTangent = SeriesEditParameter.TryGetParamValue(parameters, "Tangent", false) ^ shiftPressed;
                var tangentType  = SeriesEditParameter.TryGetParamValue(parameters, "TangentView",
                                                                        ChartEllipse.EllipseTangentType.Отрезок);
                data.Add(new ChartEllipse
                {
                    Owner        = this,
                    Color        = lineColor,
                    BuildTangent = buildTangent,
                    TangentType  = tangentType,
                    buildAuto    = buildAuto
                });
                editedEllipse = data[data.Count - 1];
                editedEllipse.IsBeingCreated = true;
                if (Owner.Owner.Owner.AdjustObjectColorsOnCreation)
                {
                    editedEllipse.AjustColorScheme(Owner.Owner.Owner);
                }
            }

            // добавить точку в эллипс
            editedEllipse.points.Add(pointD.ToPointF());
            // ... или сразу две
            if (editedEllipse.points.Count == 1)
            {
                editedEllipse.points.Add(pointD.ToPointF());
            }

            ellipseBeingSized = editedEllipse;
        }
Example #3
0
        protected override bool OnMouseUp(List <SeriesEditParameter> parameters, MouseEventArgs e,
                                          Keys modifierKeys, out IChartInteractiveObject objectToEdit)
        {
            objectToEdit = null;
            if (ellipseBeingSized == null)
            {
                return(false);
            }

            // полуось эллипса не выродилась в точку?
            var lenPx = Conversion.GetSpanLenInScreenCoords(ellipseBeingSized.points[0],
                                                            ellipseBeingSized.points[1], Chart.StockPane.WorldRect, Chart.StockPane.CanvasRect);

            if (lenPx < 3)
            {
                data.Remove(ellipseBeingSized);
                ellipseBeingSized = null;
                return(true);
            }

            ellipseBeingSized.buildAuto = false;

            // если в эллипсе все три точки - завершить редактирование
            if (ellipseBeingSized.points.Count == 3)
            {
                // проставить время - по первой точке
                var minIndex = ellipseBeingSized.points.Min(p => p.X);
                ellipseBeingSized.DateStart      = Chart.StockSeries.GetCandleOpenTimeByIndex((int)minIndex);
                ellipseBeingSized.IsBeingCreated = false;
                objectToEdit = ellipseBeingSized;
            }

            // иначе - просто завершить режим "резинки" до след. нажатия
            ellipseBeingSized = null;
            return(true);
        }
Example #4
0
        /// <summary>
        /// построить эллипс по двум точкам так, чтобы он опоясывал тени свечей в своих пределах
        /// </summary>
        private bool BuildEllipseAuto(ChartEllipse editedEllipse)
        {
            if (editedEllipse.points[0].X == editedEllipse.points[1].X)
            {
                return(false);                                                        // эллипс вырожден
            }
            if (Owner.CanvasRect.Width == 0 || Owner.CanvasRect.Height == 0 ||
                Owner.WorldRect.Width == 0 || Owner.WorldRect.Height == 0)
            {
                return(false);
            }

            // если точки эллипса следуют задом наперед - поменять их местами
            if (editedEllipse.points[0].X > editedEllipse.points[1].X)
            {
                var pt = editedEllipse.points[1];
                editedEllipse.points[1] = editedEllipse.points[0];
                editedEllipse.points[0] = pt;
            }

            // координаты в масштабе экрана
            PointF a = editedEllipse.points[0], b = editedEllipse.points[1];
            PointF aScale = Conversion.WorldToScreen(new PointD(a.X, a.Y),
                                                     Owner.WorldRect, Owner.CanvasRect).ToPointF();
            PointF bScale = Conversion.WorldToScreen(new PointD(b.X, b.Y),
                                                     Owner.WorldRect, Owner.CanvasRect).ToPointF();

            var candles = Chart.StockSeries.Data.Candles;

            var start = Math.Max((int)a.X + 1, 0);
            var end   = Math.Min((int)b.X - 1, candles.Count - 1);

            if (start >= end)
            {
                return(false);
            }

            // по каждой свече - эллипс должен охватывать оную
            Cortege2 <PointF, float>?maxEllipsePtrs = null;

            for (var i = start; i <= end; i++)
            {
                // кончик свечки (хай или лоу)
                PointF candleTip = Conversion.WorldToScreen(new PointD(i, (double)candles[i].high),
                                                            Owner.WorldRect, Owner.CanvasRect).ToPointF();

                var ellipsePtrs = TryMakeChartEllipse(aScale, bScale, candleTip, true);
                if (!maxEllipsePtrs.HasValue && ellipsePtrs.HasValue)
                {
                    maxEllipsePtrs = ellipsePtrs;
                }
                else
                {
                    if (ellipsePtrs.HasValue)
                    {
                        if (ellipsePtrs.Value.b > maxEllipsePtrs.Value.b)
                        {
                            maxEllipsePtrs = ellipsePtrs;
                        }
                    }
                }
                // тупой копипаст для лоу
                candleTip = Conversion.WorldToScreen(new PointD(i, (double)candles[i].low),
                                                     Owner.WorldRect, Owner.CanvasRect).ToPointF();
                ellipsePtrs = TryMakeChartEllipse(aScale, bScale, candleTip, true);
                if (!maxEllipsePtrs.HasValue && ellipsePtrs.HasValue)
                {
                    maxEllipsePtrs = ellipsePtrs;
                }
                else
                {
                    if (ellipsePtrs.HasValue)
                    {
                        if (ellipsePtrs.Value.b > maxEllipsePtrs.Value.b)
                        {
                            maxEllipsePtrs = ellipsePtrs;
                        }
                    }
                }
            }
            // если описывающий эллипс существует
            if (maxEllipsePtrs.HasValue)
            {
                var pt = Conversion.ScreenToWorld(new PointD(maxEllipsePtrs.Value.a.X, maxEllipsePtrs.Value.a.Y),
                                                  Owner.WorldRect, Owner.CanvasRect).ToPointF();
                if (editedEllipse.points.Count == 2)
                {
                    editedEllipse.points.Add(pt);
                }
                else
                {
                    editedEllipse.points[2] = pt;
                }
            }
            else
            {
                if (editedEllipse.points.Count == 3)
                {
                    editedEllipse.points.RemoveAt(editedEllipse.points.Count - 1);
                }
            }
            return(true);
        }
Example #5
0
        /// <summary>
        /// построить эллипс по двум точкам так, чтобы он опоясывал тени свечей в своих пределах
        /// </summary>        
        private bool BuildEllipseAuto(ChartEllipse editedEllipse)
        {
            if (editedEllipse.points[0].X == editedEllipse.points[1].X) return false; // эллипс вырожден
            if (Owner.CanvasRect.Width == 0 || Owner.CanvasRect.Height == 0 ||
                Owner.WorldRect.Width == 0 || Owner.WorldRect.Height == 0) return false;

            // если точки эллипса следуют задом наперед - поменять их местами
            if (editedEllipse.points[0].X > editedEllipse.points[1].X)
            {
                var pt = editedEllipse.points[1];
                editedEllipse.points[1] = editedEllipse.points[0];
                editedEllipse.points[0] = pt;
            }

            // координаты в масштабе экрана
            PointF a = editedEllipse.points[0], b = editedEllipse.points[1];
            PointF aScale = Conversion.WorldToScreen(new PointD(a.X, a.Y),
                                                     Owner.WorldRect, Owner.CanvasRect).ToPointF();
            PointF bScale = Conversion.WorldToScreen(new PointD(b.X, b.Y),
                                                     Owner.WorldRect, Owner.CanvasRect).ToPointF();

            var candles = Chart.StockSeries.Data.Candles;

            var start = Math.Max((int) a.X + 1, 0);
            var end = Math.Min((int) b.X - 1, candles.Count - 1);
            if (start >= end) return false;

            // по каждой свече - эллипс должен охватывать оную
            Cortege2<PointF, float>? maxEllipsePtrs = null;
            for (var i = start; i <= end; i++)
            {
                // кончик свечки (хай или лоу)
                PointF candleTip = Conversion.WorldToScreen(new PointD(i, (double)candles[i].high),
                                                     Owner.WorldRect, Owner.CanvasRect).ToPointF();

                var ellipsePtrs = TryMakeChartEllipse(aScale, bScale, candleTip, true);
                if (!maxEllipsePtrs.HasValue && ellipsePtrs.HasValue) maxEllipsePtrs = ellipsePtrs;
                else
                {
                    if (ellipsePtrs.HasValue)
                        if (ellipsePtrs.Value.b > maxEllipsePtrs.Value.b)
                            maxEllipsePtrs = ellipsePtrs;
                }
                // тупой копипаст для лоу
                candleTip = Conversion.WorldToScreen(new PointD(i, (double)candles[i].low),
                                                     Owner.WorldRect, Owner.CanvasRect).ToPointF();
                ellipsePtrs = TryMakeChartEllipse(aScale, bScale, candleTip, true);
                if (!maxEllipsePtrs.HasValue && ellipsePtrs.HasValue) maxEllipsePtrs = ellipsePtrs;
                else
                {
                    if (ellipsePtrs.HasValue)
                        if (ellipsePtrs.Value.b > maxEllipsePtrs.Value.b)
                            maxEllipsePtrs = ellipsePtrs;
                }
            }
            // если описывающий эллипс существует
            if (maxEllipsePtrs.HasValue)
            {
                var pt = Conversion.ScreenToWorld(new PointD(maxEllipsePtrs.Value.a.X, maxEllipsePtrs.Value.a.Y),
                                                  Owner.WorldRect, Owner.CanvasRect).ToPointF();
                if (editedEllipse.points.Count == 2)
                    editedEllipse.points.Add(pt);
                else
                    editedEllipse.points[2] = pt;
            }
            else
            {
                if (editedEllipse.points.Count == 3)
                    editedEllipse.points.RemoveAt(editedEllipse.points.Count - 1);
            }
            return true;
        }
Example #6
0
        protected override bool OnMouseUp(List<SeriesEditParameter> parameters, MouseEventArgs e, 
            Keys modifierKeys, out IChartInteractiveObject objectToEdit)
        {
            objectToEdit = null;
            if (ellipseBeingSized == null) return false;

            // полуось эллипса не выродилась в точку?
            var lenPx = Conversion.GetSpanLenInScreenCoords(ellipseBeingSized.points[0],
                ellipseBeingSized.points[1], Chart.StockPane.WorldRect, Chart.StockPane.CanvasRect);
            if (lenPx < 3)
            {
                data.Remove(ellipseBeingSized);
                ellipseBeingSized = null;
                return true;
            }

            ellipseBeingSized.buildAuto = false;

            // если в эллипсе все три точки - завершить редактирование
            if (ellipseBeingSized.points.Count == 3)
            {
                // проставить время - по первой точке
                var minIndex = ellipseBeingSized.points.Min(p => p.X);
                ellipseBeingSized.DateStart = Chart.StockSeries.GetCandleOpenTimeByIndex((int)minIndex);
                ellipseBeingSized.IsBeingCreated = false;
                objectToEdit = ellipseBeingSized;
            }

            // иначе - просто завершить режим "резинки" до след. нажатия
            ellipseBeingSized = null;
            return true;
        }
Example #7
0
        protected override void OnMouseDown(List<SeriesEditParameter> parameters,
            MouseEventArgs e, Keys modifierKeys, out IChartInteractiveObject objectToEdit)
        {
            objectToEdit = null;
            if (e.Button != MouseButtons.Left) return;
            // получить время и цену
            var pointD = Chart.Owner.MouseToWorldCoords(e.X, e.Y);
            var editedEllipse = data.FirstOrDefault(el => el.IsBeingCreated);

            var shiftPressed = (Control.ModifierKeys & Keys.Shift) == Keys.Shift;
            var controlPressed = (Control.ModifierKeys & Keys.Control) == Keys.Control;

            if (editedEllipse == null)
            {// начинается редактирование - выбрана первая точка
                var lineColor = SeriesEditParameter.TryGetParamValue(parameters, "Stroke", Color.Black);
                var buildAuto = SeriesEditParameter.TryGetParamValue(parameters, "ByTwoPoints", false) ^ controlPressed;
                var buildTangent = SeriesEditParameter.TryGetParamValue(parameters, "Tangent", false) ^ shiftPressed;
                var tangentType = SeriesEditParameter.TryGetParamValue(parameters, "TangentView",
                    ChartEllipse.EllipseTangentType.Отрезок);
                data.Add(new ChartEllipse
                             {
                                 Owner = this,
                                 Color = lineColor,
                                 BuildTangent = buildTangent,
                                 TangentType = tangentType,
                                 buildAuto = buildAuto
                             });
                editedEllipse = data[data.Count - 1];
                editedEllipse.IsBeingCreated = true;
                if (Owner.Owner.Owner.AdjustObjectColorsOnCreation)
                    editedEllipse.AjustColorScheme(Owner.Owner.Owner);
            }

            // добавить точку в эллипс
            editedEllipse.points.Add(pointD.ToPointF());
            // ... или сразу две
            if (editedEllipse.points.Count == 1)
                editedEllipse.points.Add(pointD.ToPointF());

            ellipseBeingSized = editedEllipse;
        }
Example #8
0
 public override IChartInteractiveObject LoadObject(XmlElement objectNode, CandleChartControl owner, bool trimObjectsOutOfHistory = false)
 {
     var obj = new ChartEllipse();
     obj.LoadFromXML(objectNode, owner);
     obj.Owner = this;
     data.Add(obj);
     return obj;
 }
        /// <summary>
        /// Получить описывающий визуальный
        /// </summary>
        /// <param name="candles"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private ChartEllipse BuildVisualInclusiveEllipse(StockSeriesData candles, int start, int end)
        {
            if (start == end) return null;
            float startvalue, endvalue;
            if (candles[start].high > candles[end].high)
            {
                startvalue = candles[start].high;
                endvalue = candles[end].low;
            }
            else
            {
                startvalue = candles[start].low;
                endvalue = candles[end].high;
            }
            var A = Conversion.WorldToScreen(new PointD(start, Convert.ToDouble(startvalue)), worldRect, canvasRect).ToPointF();
            var B = Conversion.WorldToScreen(new PointD(end, Convert.ToDouble(endvalue)), worldRect, canvasRect).ToPointF();
            var C = new PointF();

            double angle;
            float cx, cy, a, b;
            var S = float.NaN;
            var correctEllipse = false;
            // поиск охватывающего эллипса
            for (var i = start; i <= end; i++)
            {
                var d = Conversion.WorldToScreen(new PointD(i, Convert.ToDouble(candles[i].high)), worldRect, canvasRect).ToPointF();
                correctEllipse = Geometry.GetEllipseParams(A, B, d, out angle, out a, out b, out cx, out cy);
                if (float.IsNaN(S) || (correctEllipse && S < b))
                {
                    S = b;
                    C = d;
                }

                d = Conversion.WorldToScreen(new PointD(i, Convert.ToDouble(candles[i].low)), worldRect, canvasRect).ToPointF();
                correctEllipse = Geometry.GetEllipseParams(A, B, d, out angle, out a, out b, out cx, out cy);
                if (float.IsNaN(S) || (correctEllipse && S < b))
                {
                    S = b;
                    C = d;
                }
            }

            correctEllipse = // пересчитываем параметры эллипса
                Geometry.GetEllipseParams(A, B, C, out angle, out a, out b, out cx, out cy);
            if (correctEllipse)
            {   // можно построить эллипс - рисуем его
                var newEllipse = new ChartEllipse { BuildTangent = true, angle = angle, a = a, b = b, cx = cx, cy = cy };

                newEllipse.points.Add(Conversion.ScreenToWorld(new PointD(A.X, A.Y), worldRect, canvasRect).ToPointF());
                newEllipse.points.Add(Conversion.ScreenToWorld(new PointD(B.X, B.Y), worldRect, canvasRect).ToPointF());
                newEllipse.points.Add(Conversion.ScreenToWorld(new PointD(C.X, C.Y), worldRect, canvasRect).ToPointF());

                var minIndex = newEllipse.points.Min(p => p.X);
                newEllipse.DateStart = owner.StockSeries.GetCandleOpenTimeByIndex((int)minIndex);
                return newEllipse;
            }
            return null;
        }