/// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        /// <param name="unitsUnification">Draw a few units as one. Used when zooming is too big to show each unit - so unify them. 1 means no unification, 10 means unify 10 units together</param>
        /// <param name="clippingRectangle"></param>
        /// <param name="itemWidth"></param>
        /// <param name="itemMargin"></param>
        public override void Draw(GraphicsWrapper g, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin)
        {
            if (Visible == false)
            {
                return;
            }

            PointF drawingPoint = new PointF();

            lock (this)
            {
                if (_chartType == ChartTypeEnum.Line)
                {
                    SetChartType(SimpleChartSeries.ChartTypeEnum.Line);
                    base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);
                }
                else if (_chartType == ChartTypeEnum.Histogram)
                {
                    SetChartType(SimpleChartSeries.ChartTypeEnum.Histogram);
                    base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);
                }
                else if (_chartType == ChartTypeEnum.ColoredArea)
                {
                    SetChartType(SimpleChartSeries.ChartTypeEnum.ColoredArea);
                    base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin);
                }
                else if (_chartType == ChartTypeEnum.CandleStick || _chartType == ChartTypeEnum.BarChart)
                {// Unit unification is done trough combining many bars together.
                    List <BarData> combinationDatas = new List <BarData>();
                    bool           timeGapFound     = false;

                    int startIndex, endIndex;
                    GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin);

                    float  volumeDisplayRange         = clippingRectangle.Height / 4f;
                    double volumeDisplayMultiplicator = volumeDisplayRange / _maxVolume;

                    for (int i = startIndex; i < endIndex && i < _dataBars.Count; i++)
                    {
                        combinationDatas.Add(_dataBars[i]);

                        if (unitsUnification == 1 && ShowTimeGaps && i > 0 && _dataBars[i].DateTime - _dataBars[i - 1].DateTime != _period)
                        {
                            timeGapFound = true;
                        }

                        if (i % unitsUnification == 0)
                        {
                            BarData combinedData = BarData.CombinedBar(combinationDatas.ToArray());

                            if (i == _dataBars.Count - 1)
                            {
                                Console.WriteLine("  LAST  combinedData ######  " + combinedData);
                            }
                            combinationDatas.Clear();
                            if (combinedData.HasDataValues)
                            //&& drawingPoint.X >= clippingRectangle.X
                            //&& drawingPoint.X <= clippingRectangle.X + clippingRectangle.Width)
                            {
                                if (timeGapFound && ShowTimeGaps && _timeGapsLinePen != null)
                                {// Draw time gap.
                                    timeGapFound = false;
                                    g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, clippingRectangle.Y), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height));

                                    //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, clippingRectangle.Y), new PointF(drawingPoint.X, (float)(data.High)));
                                    //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, (float)(data.High + data.BarTotalLength / 2f)), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height));
                                }

                                if (_chartType == ChartTypeEnum.CandleStick)
                                {
                                    if (i > 0 && combinedData.Open > _dataBars[i - 1].Close)
                                    {
                                        combinedData.IsHigherPrev = true;
                                    }

                                    DrawCandleStick(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification);
                                }
                                else
                                {
                                    DrawBar(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification);
                                }

                                // Draw volume for this bar.
                                if (_showVolume)
                                {
                                    float actualHeight = (float)(combinedData.Volume * volumeDisplayMultiplicator);
                                    g.DrawLine(_volumePen, drawingPoint.X, clippingRectangle.Y, drawingPoint.X, clippingRectangle.Y + actualHeight);
                                }

                                if (combinedData.Sar != 0)
                                {
                                    float dy = drawingPoint.Y;
                                    float y  = (drawingPoint.Y + (float)combinedData.Sar);

                                    float yts = Math.Abs(g.DrawingSpaceTransform.Elements[0] / g.DrawingSpaceTransform.Elements[3]);
                                    float x   = drawingPoint.X + (1 + yts) * itemWidth * 3f / 16f;
                                    //float x = drawingPoint.X + (1 + yts) * itemWidth * 3f / 8f;
                                    if (combinedData.Sar >= combinedData.Low && combinedData.High >= combinedData.Sar)
                                    {
                                        g.DrawEllipse(new Pen(Color.White), x, y, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                    }
                                    else
                                    {
                                        g.DrawEllipse(new Pen(Color.White), x, y, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                    }

                                    if (combinedData.Boll != null)
                                    {
                                        float uy = dy + (float)combinedData.Boll[BOLL.UPPER];
                                        float my = dy + (float)combinedData.Boll[BOLL.MID];
                                        float ly = dy + (float)combinedData.Boll[BOLL.LOWER];
                                        g.DrawEllipse(new Pen(Color.Cyan), x, uy, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                        g.DrawEllipse(new Pen(Color.Cyan), x, my, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                        g.DrawEllipse(new Pen(Color.Cyan), x, ly, yts * itemWidth / 2f, yts * itemWidth / 2f);
                                    }
                                }

                                // Harry  --- Draw Signal
                                //_dataBars[i].RefreshExValues();


                                float   actualImageHeight     = _imageDown.Height / Math.Abs(g.DrawingSpaceTransform.Elements[3]);
                                float   yToXScaling           = Math.Abs(g.DrawingSpaceTransform.Elements[0] / g.DrawingSpaceTransform.Elements[3]);
                                PointF  upImageDrawingPoint   = drawingPoint;
                                PointF  downImageDrawingPoint = drawingPoint;
                                Order   order        = new Order();
                                BarData orderBarData = _dataBars[i];
                                float   lastBarX     = (itemMargin + itemWidth) * _dataBars.Count;

                                if (_dataBars[i].SignalList != null && _dataBars[i].SignalList.Count > 0)
                                {
                                    foreach (CandleSignal cs in _dataBars[i].SignalList)
                                    {
                                        cs.BarData = orderBarData;
                                        if (cs.Code == 1)
                                        {
                                            DrawSignal(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -1)
                                        {
                                            DrawSignal(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == 2)
                                        {
                                            DrawGainTip(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -2)
                                        {
                                            DrawGainTip(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == 3)
                                        {
                                            DrawStopLoss(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -3)
                                        {
                                            DrawStopLoss(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == 4)
                                        {
                                            DrawStopGain(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }

                                        if (cs.Code == -4)
                                        {
                                            DrawStopGain(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false);
                                        }
                                    }
                                }
                            }
                            drawingPoint.X = (i + 1) * (itemMargin + itemWidth);
                        }
                    }
                }
            }
        }