예제 #1
0
        protected override int Render(YGraphics g, int w, int h)
        {
            mainViewPort = new ViewPortSettings()
            {
                IRLx = 0, IRLy = 0, zoomx = 1.0, zoomy = 1.0, Lmargin = 0, Rmargin = 0, Tmargin = 0, Bmargin = 0, Capture = false
            };

            g.SmoothingMode     = SmoothingMode.HighQuality;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            drawAnnotationPanels(g, _annotationPanels, w, h, false, ref mainViewPort);

            DrawPrameters p = ComputeDrawParameters(g, w, h, mainViewPort);


            if (_path == null)
            {
                double outterlength = (2 * p.outerRadius * Math.PI) * (p.angleEnd - p.angleStart) / (2 * Math.PI);
                int    stepCount    = (int)(outterlength / SegmentMaxLength);
                double stepsize     = (p.angleEnd - p.angleStart) / stepCount;
                _path = new PointF[2 * (stepCount + 1)];
                int n = 0;
                for (int i = 0; i <= stepCount; i++)
                {
                    double a = p.angleStart + i * stepsize;
                    _path[n++] = new PointF((Single)(p.xcenter + p.outerRadius * Math.Cos(a)), (Single)(p.ycenter - p.outerRadius * Math.Sin(a)));
                }
                for (int i = stepCount; i >= 0; i--)
                {
                    double a = p.angleStart + i * stepsize;
                    _path[n++] = new PointF((Single)(p.xcenter + p.innerRadius * Math.Cos(a)), (Single)(p.ycenter - p.innerRadius * Math.Sin(a)));
                }
            }

            if (_bgBrush == null)
            {
                _bgBrush = new LinearGradientBrush(new Point(0, (int)(p.ycenter - p.heightTop)),
                                                   new Point(0, (int)(p.ycenter + p.heightBottom)), _backgroundColor1, _backgroundColor2);
            }



            if (_borderpen == null)
            {
                _borderpen          = new Pen(_borderColor, (float)_borderThickness);
                _borderpen.LineJoin = LineJoin.Round;
            }

            g.FillPolygon(_bgBrush, _path);


            if (_shownValue != _value)
            {
                double step = _maxSpeed * (_max - _min) / 100;
                if (Math.Abs(_value - _shownValue) < step)
                {
                    _shownValue = _value;
                }
                else if (_shownValue < _value)
                {
                    _shownValue += step;
                }
                else
                {
                    _shownValue -= step;
                }
            }



            double v = _shownValue;

            if (v >= _min)
            {
                if (v > _max)
                {
                    v = _max;
                }
                double   valueFactor  = (v - _min) / (_max - min);
                double   angleValue   = p.angleStart + (p.angleEnd - p.angleStart) * valueFactor;
                double   outterlength = (2 * p.outerRadius * Math.PI) * (angleValue - p.angleStart) / (2 * Math.PI);
                int      stepCount    = (int)(outterlength / SegmentMaxLength);
                double   stepsize     = (angleValue - p.angleStart) / stepCount;
                PointF[] pt           = new PointF[2 * (stepCount + 1)];
                int      n            = 0;
                for (int i = 0; i <= stepCount; i++)
                {
                    double a = p.angleEnd - i * stepsize;
                    pt[n++] = new PointF((Single)(p.xcenter + p.outerRadius * Math.Cos(a)), (Single)(p.ycenter - p.outerRadius * Math.Sin(a)));
                }
                for (int i = stepCount; i >= 0; i--)
                {
                    double a = p.angleEnd - i * stepsize;
                    pt[n++] = new PointF((Single)(p.xcenter + p.innerRadius * Math.Cos(a)), (Single)(p.ycenter - p.innerRadius * Math.Sin(a)));
                }
                Brush b;
                if (_color1 == _color2)
                {
                    b = new SolidBrush(_color1);
                }
                else
                {
                    int    A1 = (_color1.ToArgb() >> 24) & 0xFF;
                    double H1 = _color1.GetHue();
                    double S1 = _color1.GetSaturation();
                    double L1 = _color1.GetBrightness();
                    int    A2 = (_color2.ToArgb() >> 24) & 0xFF;
                    double H2 = _color2.GetHue();
                    double S2 = _color2.GetSaturation();
                    double L2 = _color2.GetBrightness();
                    int    A  = ((int)Math.Round(A1 + (double)(A2 - A1) * valueFactor)) & 0xff;

                    double H;
                    if (Math.Abs(H2 - H1) <= 180)
                    {
                        H = H1 + (double)(H2 - H1) * valueFactor;
                    }
                    else
                    {
                        H = H1 + 360 + (double)(H2 - H1 + 360) * valueFactor;
                        if (H > 360)
                        {
                            H -= 360;
                        }
                    }
                    double S = S1 + (double)(S2 - S1) * valueFactor;
                    double L = L1 + (double)(L2 - L1) * valueFactor;
                    b = new SolidBrush(Color.FromArgb(A1, Ycolor.hsl2rgb((int)((255 * H) / 360), (int)(255 * S), (int)(255 * L))));
                }
                g.FillPolygon(b, pt);
            }

            if (_borderThickness > 0)
            {
                g.DrawPolygon(_borderpen, _path);
            }

            g.DrawString(lastDrawParameters.value, _font.fontObject, _font.brushObject, p.valueRectangle, p.valueFormat);

            if (_showMinMax)
            {
                //Pen pn = new Pen(Color.Red);
                //g.DrawRectangle(pn,lastDrawParameters.minValueRectangle);
                //g.DrawRectangle(pn, lastDrawParameters.maxValueRectangle);

                g.DrawString(lastDrawParameters.minValue, _minMaxFont.fontObject, _minMaxFont.brushObject, lastDrawParameters.minValueRectangle, lastDrawParameters.minValueFormat);
                g.DrawString(lastDrawParameters.maxValue, _minMaxFont.fontObject, _minMaxFont.brushObject, lastDrawParameters.maxValueRectangle, lastDrawParameters.maxValueFormat);
            }
            drawAnnotationPanels(g, _annotationPanels, w, h, true, ref mainViewPort);
            DrawMessagePanels(g, w, h);



            return(0);
        }
        protected override int Render(YGraphics g, int w, int h)
        {
            ViewPortSettings mainViewPort = new ViewPortSettings()
            {
                IRLx = 0, IRLy = 0, zoomx = 1.0, zoomy = 1.0, Lmargin = 0, Rmargin = 0, Tmargin = 0, Bmargin = 0, Capture = false
            };

            mainViewPort.Lmargin = 0;
            mainViewPort.Rmargin = 0;
            mainViewPort.Tmargin = 0;
            mainViewPort.Bmargin = 0;

            g.SmoothingMode     = SmoothingMode.HighQuality;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            StringFormat stringFormat4Sizing = new StringFormat(StringFormatFlags.NoClip);
            StringFormat stringFormat        = new StringFormat(StringFormatFlags.NoClip);

            stringFormat.Alignment     = StringAlignment.Center;
            stringFormat.LineAlignment = StringAlignment.Center;


            drawAnnotationPanels(g, _annotationPanels, w, h, false, ref mainViewPort);
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            double xcenter = mainViewPort.Lmargin + (w - mainViewPort.Lmargin - mainViewPort.Rmargin) / 2;
            double ycenter = mainViewPort.Tmargin + (h - mainViewPort.Tmargin - mainViewPort.Bmargin) / 2;

            double radius = Math.Min((w - mainViewPort.Lmargin - mainViewPort.Rmargin) / 2,
                                     (h - mainViewPort.Tmargin - mainViewPort.Bmargin) / 2) - borderThickness;


            int    circonference = (int)(2 * radius * 3.14);
            double AngleAperture = 4 * 2 * Math.PI / 5;



            if (_path == null)
            {
                double outterlength = (2 * radius * Math.PI);
                int    stepCount    = (int)(outterlength / SegmentMaxLength);
                double stepsize     = (2 * Math.PI) / stepCount;

                _path = new PointF[stepCount];
                int n = 0;
                for (int i = 0; i < stepCount; i++)
                {
                    double a = (2 * i * Math.PI) / stepCount;
                    _path[n++] = new PointF((Single)(xcenter + radius * Math.Cos(a)), (Single)(ycenter - radius * Math.Sin(a)));
                }
            }

            if (_bgBrush == null)
            {
                _bgBrush = new LinearGradientBrush(new Point(0, (int)(ycenter - radius)),
                                                   new Point(0, (int)(ycenter + radius)), _backgroundColor1, _backgroundColor2);
            }


            if (_borderpen == null)
            {
                _borderpen          = new Pen(_borderColor, (float)_borderThickness);
                _borderpen.LineJoin = LineJoin.Round;
            }

            if (_path.Length > 3)
            {
                g.FillPolygon(_bgBrush, _path);
            }


            if (_graduationPen == null)
            {
                _graduationPen = new Pen(_graduationColor, (float)_graduationThickness);
            }
            if (_subgraduationPen == null)
            {
                _subgraduationPen = new Pen(_subgraduationColor, (float)_subgraduationThickness);
            }

            // draw unit
            string    unitDesc = ((_unitFactor != 1) ? "x" + _unitFactor.ToString() + " " : "") + _unit;
            SizeF     size     = g.MeasureString(unitDesc.ToString(), _unitFont.fontObject, 10000, stringFormat4Sizing);
            Rectangle unitPos  = new Rectangle((int)(xcenter - size.Width / 2), (int)(ycenter + radius / 2 - size.Height / 2), (int)(size.Width + 1), (int)(size.Height + 1));

            g.DrawString(unitDesc, _unitFont.fontObject, _unitFont.brushObject, unitPos, stringFormat);

            // draw status line
            if (_statusLine != "")
            {
                size = g.MeasureString(_statusLine, _statusFont.fontObject, 10000, stringFormat4Sizing);
                Rectangle statusPos = new Rectangle((int)(xcenter - size.Width / 2), (int)(ycenter - radius / 3 - size.Height / 2), (int)(size.Width + 1), (int)(size.Height + 1));
                g.DrawString(_statusLine, _statusFont.fontObject, _statusFont.brushObject, statusPos, stringFormat);
            }

            double firstGraduation;
            int    gratuationCount;
            double Angle, C, S, R1, R2;

            double outerCoef = _graduationOuterRadiusSize / 100;

            // draw zones

            for (int i = 0; i < _zones.Count; i++)
            {
                if (_zones[i].visible)
                {
                    if (_zones[i].path == null)
                    {
                        double zmin = Math.Max(_min, Math.Min(_max, _zones[i].min));
                        double zmax = Math.Max(_min, Math.Min(_max, _zones[i].max));

                        if (zmax > zmin)
                        {
                            double zOuterCoef   = _zones[i].outerRadius / 100;
                            double Angle1       = ((Math.PI - AngleAperture) / 2) + AngleAperture * (zmin - _min) / (_max - _min);
                            double Angle2       = ((Math.PI - AngleAperture) / 2) + AngleAperture * (zmax - _min) / (_max - _min);
                            double outterlength = (Angle2 - Angle1) * radius;
                            int    stepCount    = (int)(outterlength / SegmentMaxLength);
                            if (stepCount < 2)
                            {
                                stepCount = 2;
                            }
                            _zones[i].setPathSize(2 * stepCount + 2);

                            PointF[] Path = new PointF[2 * stepCount + 2];
                            for (int j = 0; j <= stepCount; j++)
                            {
                                double A = Angle1 + ((Angle2 - Angle1) * j) / stepCount;
                                _zones[i].setPathPoint(j, new PointF((float)(xcenter - radius * zOuterCoef * Math.Cos(A)), (float)(ycenter - radius * zOuterCoef * Math.Sin(A))));
                            }
                            double innerRadiusCoef = zOuterCoef - (_zones[i].width / 100);

                            for (int j = stepCount; j >= 0; j--)
                            {
                                double A = Angle1 + ((Angle2 - Angle1) * j) / stepCount;
                                _zones[i].setPathPoint(2 * stepCount + 1 - j, new PointF((float)(xcenter - radius * innerRadiusCoef * Math.Cos(A)), (float)(ycenter - radius * innerRadiusCoef * Math.Sin(A))));
                            }
                        }
                    }
                    if (_zones[i].path != null)
                    {
                        g.FillPolygon(_zones[i].zoneBrush, _zones[i].path);
                    }
                }
            }

            firstGraduation = _graduation * (int)(_min / _graduation);
            if (_min < 0)
            {
                firstGraduation -= _graduation;
            }

            while (firstGraduation < _min)
            {
                firstGraduation += _graduation;
            }
            gratuationCount = (int)((_max - _min) / _graduation) + 1;



            // draw sub graduations

            if ((_subgraduationCount > 0) && ((_subgraduationCount * gratuationCount) < circonference))
            {
                double subgraduation = _graduation / _subgraduationCount;
                firstGraduation = subgraduation * (int)(_min / subgraduation);
                if (_min < 0)
                {
                    firstGraduation -= subgraduation;
                }
                while (firstGraduation < _min)
                {
                    firstGraduation += subgraduation;
                }


                gratuationCount = (int)((_max - _min) / subgraduation) + 1;


                for (int i = 0; i < gratuationCount; i++)
                {
                    double value = firstGraduation + i * subgraduation;
                    if (value <= _max)
                    {
                        Angle = ((Math.PI - AngleAperture) / 2) + AngleAperture * (value - _min) / (_max - _min);
                        C     = Math.Cos(Angle);
                        S     = Math.Sin(Angle);
                        R1    = (outerCoef * (radius - _borderThickness / 2));
                        R2    = (100 - _subgraduationSize) * (outerCoef * (radius - _borderThickness / 2)) / 100;
                        g.DrawLine(_subgraduationPen, (float)(xcenter - R1 * C), (float)(ycenter - R1 * S),
                                   (float)(xcenter - R2 * C), (float)(ycenter - R2 * S));
                    }
                }
            }



            // draw Main graduations



            if (gratuationCount < circonference) // stop drawing graduation if too many
            {
                for (int i = 0; i < gratuationCount; i++)
                {
                    double gvalue = firstGraduation + i * _graduation;
                    if (gvalue <= _max)
                    {
                        Angle = ((Math.PI - AngleAperture) / 2) + AngleAperture * (gvalue - _min) / (_max - _min);
                        C     = Math.Cos(Angle);
                        S     = Math.Sin(Angle);
                        R1    = (outerCoef * (radius - _borderThickness / 2));
                        R2    = (100 - _graduationSize) * (outerCoef * (radius - _borderThickness / 2)) / 100;

                        g.DrawLine(_graduationPen, (float)(xcenter - R1 * C), (float)(ycenter - R1 * S),
                                   (float)(xcenter - R2 * C), (float)(ycenter - R2 * S));

                        size = g.MeasureString(gvalue.ToString().Trim(), _graduationFont.fontObject, 1000, stringFormat4Sizing);

                        double    HalfDiagonal = 0.4 * Math.Sqrt(size.Width * size.Width + size.Height * size.Height);
                        Rectangle position     = new Rectangle((int)(xcenter - (R2 - HalfDiagonal) * C - (size.Width / 2)),
                                                               (int)(ycenter - (R2 - HalfDiagonal) * S - (size.Height / 2)),
                                                               (int)size.Width + 1, (int)size.Height);

                        //  g.DrawRectangle(new Pen(Color.Red, 1), position);


                        g.DrawString(gvalue.ToString(), _graduationFont.fontObject, _graduationFont.brushObject, position, stringFormat);
                    }
                }
            }

            // draw Border

            if ((_borderThickness > 0) && (_path.Length > 3))
            {
                g.DrawPolygon(_borderpen, _path);
            }

            drawAnnotationPanels(g, _annotationPanels, w, h, true, ref mainViewPort);

            // draw Needle
            if (_showNeedle)
            {
                if (_needleValue != _value)
                {
                    double step = _unitFactor * _needleMaxSpeed * (_max - _min) / 100;
                    if (Math.Abs(_value - _needleValue) < step)
                    {
                        _needleValue = _value;
                    }
                    else if (_needleValue < value)
                    {
                        _needleValue += step;
                    }
                    else
                    {
                        _needleValue -= step;
                    }
                }


                double needlevalue     = _needleValue / _unitFactor;
                double allowedOverflow = (_max - min) * 0.05;
                if (needlevalue < _min - allowedOverflow)
                {
                    needlevalue = _min - allowedOverflow;
                }
                if (needlevalue > _max + allowedOverflow)
                {
                    needlevalue = _max + allowedOverflow;
                }

                Angle = ((Math.PI - AngleAperture) / 2) + AngleAperture * (needlevalue - _min) / (_max - _min);
                C     = Math.Cos(Angle);
                S     = Math.Sin(Angle);
                R1    = (radius * _needleLength1) / 100;
                R2    = (radius * _needleLength2) / 100;
                double R3 = (radius * _needleWidth) / 200;

                PointF[] needlepath = new PointF[4];
                needlepath[0] = new PointF((float)(xcenter - R1 * C), (float)(ycenter - R1 * S));
                needlepath[1] = new PointF((float)(xcenter + R3 * S), (float)(ycenter - R3 * C));
                needlepath[2] = new PointF((float)(xcenter + R2 * C), (float)(ycenter + R2 * S));
                needlepath[3] = new PointF((float)(xcenter - R3 * S), (float)(ycenter + R3 * C));

                if (_needleBrush == null)
                {
                    _needleBrush = new SolidBrush(_needleColor);
                }
                g.FillPolygon(_needleBrush, needlepath);

                if (_needleContourThickness > 0)
                {
                    if (_needleContourPen == null)
                    {
                        _needleContourPen          = new Pen(_needleContourColor, (float)_needleContourThickness);
                        _needleContourPen.StartCap = LineCap.Round;

                        _needleContourPen.EndCap   = LineCap.Round;
                        _needleContourPen.LineJoin = LineJoin.Round;
                    }

                    PointF[] needlepath2 = new PointF[5];
                    needlepath2[0] = needlepath[0];
                    needlepath2[1] = needlepath[1];
                    needlepath2[2] = needlepath[2];
                    needlepath2[3] = needlepath[3];
                    needlepath2[4] = needlepath[0];

                    g.DrawLines(_needleContourPen, needlepath2);
                }
            }


            DrawMessagePanels(g, w, h);
            return(0);
        }
예제 #3
0
        private DrawPrameters ComputeDrawParameters(YGraphics g, int UIw, int UIh, ViewPortSettings mainViewPort)
        {
            UIw -= mainViewPort.Lmargin + mainViewPort.Rmargin;
            UIh -= mainViewPort.Tmargin + mainViewPort.Bmargin;

            double    w              = UIw - 5 - _borderThickness;
            double    h              = UIh - 5 - _borderThickness;
            double    xcenter        = mainViewPort.Lmargin + w / 2;
            double    outerRadius    = 0;
            double    angleStart     = 0;
            double    angleEnd       = 0;
            double    ycenter        = 0;
            Rectangle ValueRectangle = new Rectangle(0, 0, 0, 0);

            ;
            StringFormat valueFormat  = new StringFormat();
            double       innerRadius  = 0;
            double       minMaxHeight = 0;
            SizeF        s1           = new SizeF();
            SizeF        s2           = new SizeF();

            lastDrawParameters.value = _valueFormater == null?_value.ToString("0") : _valueFormater(this, _value);

            if (_showMinMax)
            {
                lastDrawParameters.minValue = _minmaxFormater == null?_min.ToString("0") : _minmaxFormater(this, _min);

                lastDrawParameters.maxValue = _minmaxFormater == null?_max.ToString("0") : _minmaxFormater(this, _max);

                s1 = g.MeasureString(lastDrawParameters.minValue, _minMaxFont.fontObject, 100000);
                s2 = g.MeasureString(lastDrawParameters.maxValue, _minMaxFont.fontObject, 100000);

                lastDrawParameters.minValueFormat = new StringFormat();
                lastDrawParameters.maxValueFormat = new StringFormat();

                minMaxHeight = s1.Height;
                if (s2.Height > minMaxHeight)
                {
                    minMaxHeight = s2.Height;
                }
            }



            switch (_displayMode)
            {
            case DisplayMode.DISPLAY90:

                h = h - minMaxHeight;
                w = w - minMaxHeight;


                outerRadius = w;
                if (outerRadius > h - _borderThickness)
                {
                    outerRadius = h - _borderThickness;
                }
                if (outerRadius > w - borderThickness)
                {
                    outerRadius = w - borderThickness;
                }
                angleStart = Math.PI / 2;
                angleEnd   = Math.PI;
                lastDrawParameters.heightTop    = outerRadius;
                lastDrawParameters.heightBottom = 0;
                ycenter = mainViewPort.Tmargin + h;
                xcenter = mainViewPort.Lmargin + UIw / 2 + outerRadius / 2 - minMaxHeight;

                innerRadius               = outerRadius * (100 - _thickness) / 100;
                ValueRectangle            = new Rectangle((int)(xcenter - innerRadius), (int)(ycenter - innerRadius), (int)innerRadius, (int)innerRadius);
                valueFormat.Alignment     = StringAlignment.Far;
                valueFormat.LineAlignment = StringAlignment.Far;
                if (_showMinMax)
                {
                    lastDrawParameters.minValueRectangle            = new Rectangle((int)(xcenter - ((outerRadius + innerRadius + s1.Width) / 2)), (int)(ycenter + _borderThickness), (int)(s1.Width + 1), (int)(minMaxHeight + 1));
                    lastDrawParameters.minValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.minValueFormat.LineAlignment = StringAlignment.Near;
                    lastDrawParameters.maxValueRectangle            = new Rectangle((int)(xcenter + _borderThickness), (int)(ycenter - outerRadius + (outerRadius - innerRadius - s2.Width) / 2), (int)(minMaxHeight + 1), (int)(s2.Width + 1));
                    lastDrawParameters.maxValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.maxValueFormat.LineAlignment = StringAlignment.Near;
                    lastDrawParameters.maxValueFormat.FormatFlags   = StringFormatFlags.DirectionVertical;
                }
                break;

            case DisplayMode.DISPLAY180:


                h = h - minMaxHeight;
                SizeF s0 = new SizeF();



                s0          = g.MeasureString(lastDrawParameters.value, _font.fontObject, 100000);
                outerRadius = (w / 2) - borderThickness;
                if (outerRadius > h - _borderThickness)
                {
                    outerRadius = h - _borderThickness;
                }
                if (outerRadius > w - borderThickness)
                {
                    outerRadius = w - borderThickness;
                }
                angleStart  = 0;
                angleEnd    = Math.PI;
                ycenter     = outerRadius + _borderThickness / 2;
                innerRadius = outerRadius * (100 - _thickness) / 100;
                lastDrawParameters.heightTop    = outerRadius;
                lastDrawParameters.heightBottom = 0;
                ValueRectangle            = new Rectangle((int)(xcenter - innerRadius), (int)(ycenter + _borderThickness + minMaxHeight - s0.Height), (int)(2 * innerRadius), (int)(s0.Height + 1));
                valueFormat.Alignment     = StringAlignment.Center;
                valueFormat.LineAlignment = StringAlignment.Far;
                if (_showMinMax)
                {
                    lastDrawParameters.minValueRectangle            = new Rectangle((int)(xcenter - ((outerRadius + innerRadius + s1.Width) / 2)), (int)(ycenter + _borderThickness), (int)(s1.Width + 1), (int)(minMaxHeight + 1));
                    lastDrawParameters.minValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.minValueFormat.LineAlignment = StringAlignment.Near;
                    lastDrawParameters.maxValueRectangle            = new Rectangle((int)(xcenter + ((outerRadius + innerRadius - s2.Width) / 2)), (int)(ycenter + _borderThickness), (int)(s2.Width + 1), (int)(minMaxHeight + 1));
                    lastDrawParameters.maxValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.maxValueFormat.LineAlignment = StringAlignment.Near;
                }
                break;

            case DisplayMode.DISPLAY270:

                outerRadius = w;
                if (outerRadius > h / 2)
                {
                    outerRadius = h / 2;
                }
                if (outerRadius > w / 2)
                {
                    outerRadius = w / 2;
                }
                lastDrawParameters.heightTop    = outerRadius;
                lastDrawParameters.heightBottom = outerRadius;
                angleStart  = 0;
                angleEnd    = 3 * Math.PI / 2;
                ycenter     = mainViewPort.Tmargin + UIh / 2;
                innerRadius = outerRadius * (100 - _thickness) / 100;


                ValueRectangle            = new Rectangle((int)(xcenter - innerRadius), (int)(ycenter - innerRadius), (int)(2 * innerRadius), (int)(2 * innerRadius));
                valueFormat.Alignment     = StringAlignment.Center;
                valueFormat.LineAlignment = StringAlignment.Center;

                if (_showMinMax)
                {
                    lastDrawParameters.minValueRectangle            = new Rectangle((int)(xcenter + _borderThickness), (int)(ycenter + (innerRadius + innerRadius) / 2), (int)(s1.Width + 1), (int)(s1.Height + 1));
                    lastDrawParameters.minValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.minValueFormat.LineAlignment = StringAlignment.Near;
                    lastDrawParameters.maxValueRectangle            = new Rectangle((int)(xcenter + (innerRadius + innerRadius) / 2), (int)(ycenter + _borderThickness), (int)(s2.Height + 1), (int)(s2.Width + 1));
                    lastDrawParameters.maxValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.maxValueFormat.LineAlignment = StringAlignment.Near;
                    lastDrawParameters.maxValueFormat.FormatFlags   = StringFormatFlags.DirectionVertical;
                }



                break;

            case DisplayMode.DISPLAY360:

                outerRadius = w;
                if (outerRadius > (h / .85) / 2)
                {
                    outerRadius = (h / .85) / 2;
                }
                if (outerRadius > w / 2)
                {
                    outerRadius = w / 2;
                }
                lastDrawParameters.heightTop    = outerRadius;
                lastDrawParameters.heightBottom = outerRadius * 0.7;
                ycenter                   = mainViewPort.Tmargin + outerRadius + _borderThickness / 2;
                angleStart                = -Math.PI / 4;
                angleEnd                  = 5 * Math.PI / 4;
                innerRadius               = outerRadius * (100 - _thickness) / 100;
                ValueRectangle            = new Rectangle((int)(xcenter - innerRadius), (int)(ycenter - innerRadius), (int)(2 * innerRadius), (int)(2 * innerRadius));
                valueFormat.Alignment     = StringAlignment.Center;
                valueFormat.LineAlignment = StringAlignment.Center;

                if (_showMinMax)
                {
                    double dx = Math.Abs(innerRadius * Math.Cos(angleStart));
                    double dy = innerRadius * Math.Abs(Math.Sin(angleStart)) + 2 * Math.Abs((outerRadius - innerRadius) * Math.Sin(angleStart) / 3);


                    lastDrawParameters.minValueRectangle            = new Rectangle((int)(xcenter - dx), (int)(ycenter + dy - minMaxHeight / 2), (int)(s1.Width + 1), (int)(minMaxHeight + 1));
                    lastDrawParameters.minValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.minValueFormat.LineAlignment = StringAlignment.Center;
                    lastDrawParameters.maxValueRectangle            = new Rectangle((int)(xcenter + dx - s2.Width), (int)(ycenter + dy - minMaxHeight / 2), (int)(s2.Width + 1), (int)(minMaxHeight + 1));
                    lastDrawParameters.maxValueFormat.Alignment     = StringAlignment.Near;
                    lastDrawParameters.maxValueFormat.LineAlignment = StringAlignment.Center;
                }



                break;
            }

            lastDrawParameters.outerRadius    = outerRadius;
            lastDrawParameters.innerRadius    = innerRadius;
            lastDrawParameters.angleStart     = angleStart;
            lastDrawParameters.angleEnd       = angleEnd;
            lastDrawParameters.ycenter        = ycenter;
            lastDrawParameters.xcenter        = xcenter;
            lastDrawParameters.valueRectangle = ValueRectangle;
            lastDrawParameters.valueFormat    = valueFormat;

            return(lastDrawParameters);
        }
        protected override int Render(YGraphics g, int w, int h)
        {
            ViewPortSettings mainViewPort = new ViewPortSettings()
            {
                IRLx = 0, IRLy = 0, zoomx = 1.0, zoomy = 1.0, Lmargin = 0, Rmargin = 0, Tmargin = 0, Bmargin = 0, Capture = false
            };

            mainViewPort.Lmargin = 0;
            mainViewPort.Rmargin = 0;
            mainViewPort.Tmargin = 0;
            mainViewPort.Bmargin = 0;

            g.SmoothingMode     = SmoothingMode.HighQuality;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            StringFormat stringFormat = new StringFormat(StringFormatFlags.NoClip);

            stringFormat.Alignment = StringAlignment.Center;

            if (_bgBrush == null)
            {
                _bgBrush = new LinearGradientBrush(new Point(0, 0),
                                                   new Point(0, h), _backgroundColor1, _backgroundColor2);
            }
            g.FillRectangle(_bgBrush, 0, 0, w, h);

            drawAnnotationPanels(g, _annotationPanels, w, h, false, ref mainViewPort);
            if (mainViewPort.Tmargin >= 20)
            {
                mainViewPort.Tmargin -= 10;                        // AnnotationPanels adds at least 20px warnings
            }
            if (mainViewPort.Bmargin >= 20)
            {
                mainViewPort.Bmargin -= 10;                        // which is a bit much for digital display
            }
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            int availWidth  = w - (mainViewPort.Lmargin + mainViewPort.Rmargin);
            int availHeight = h - (mainViewPort.Tmargin + mainViewPort.Bmargin);

            if ((availWidth > 10) && (availHeight > 10))
            {// draw unit
                string svalue;
                if (_alternateValue == null)
                {
                    svalue = _valueFormater == null?value.ToString("0.0") : _valueFormater(this, value);

                    if ((!Double.IsNaN(_outOfRangeMin)) && (value < _outOfRangeMin))
                    {
                        font.alternateColor = _outOfRangeColor;
                    }
                    else if ((!Double.IsNaN(_outOfRangeMax)) && (value > _outOfRangeMax))
                    {
                        font.alternateColor = _outOfRangeColor;
                    }
                    else
                    {
                        font.alternateColor = null;
                    }
                }
                else
                {
                    _font.alternateColor = null;
                    svalue = _alternateValue;
                }

                SizeF     size = g.MeasureString(svalue, font.fontObject, 10000, stringFormat);
                Rectangle pos;

                HrzAlignment align = _hrzAlignment;
                if ((_alternateValue != null) && (align == HrzAlignment.DECIMAL))
                {
                    align = HrzAlignment.RIGHT;
                }

                switch (align)
                {
                case HrzAlignment.LEFT:
                    pos = new Rectangle(mainViewPort.Lmargin + (int)(availWidth * hrzAlignmentOfset / 100),
                                        mainViewPort.Tmargin + (int)((availHeight - size.Height) / 2),
                                        (int)(size.Width + 1), (int)(size.Height + 1));
                    g.DrawString(svalue, font.fontObject, font.brushObject, pos, stringFormat);
                    break;

                case HrzAlignment.CENTER:
                    pos = new Rectangle(mainViewPort.Lmargin + (int)((availWidth - size.Width) / 2),
                                        mainViewPort.Tmargin + (int)((availHeight - size.Height) / 2),
                                        (int)(size.Width + 1), (int)(size.Height + 1));
                    g.DrawString(svalue, font.fontObject, font.brushObject, pos, stringFormat);
                    break;

                case HrzAlignment.DECIMAL:

                    string left = "";

                    int p = svalue.LastIndexOf(',');
                    if (p < 0)
                    {
                        p = svalue.LastIndexOf('.');
                    }
                    if (p >= 0)
                    {
                        left = svalue.Substring(0, p + 1);
                    }
                    else
                    {
                        p = 0;
                        while ((p < svalue.Length) && ((svalue[p] >= '0' && svalue[p] <= '9') || (svalue[p] == '-') || (svalue[p] == '\'') || (svalue[p] == ' ')))
                        {
                            p++;
                        }
                        left = svalue.Substring(0, p);
                    }

                    SizeF lsize = g.MeasureString(left, font.fontObject, 10000, stringFormat);
                    pos = new Rectangle(mainViewPort.Lmargin + (int)(availWidth - lsize.Width - availWidth * hrzAlignmentOfset / 100),
                                        mainViewPort.Tmargin + (int)((availHeight - size.Height) / 2),
                                        (int)(size.Width + 1), (int)(size.Height + 1));
                    g.DrawString(svalue, font.fontObject, font.brushObject, pos, stringFormat);
                    break;

                case HrzAlignment.RIGHT:
                    pos = new Rectangle(mainViewPort.Lmargin + (int)(availWidth - size.Width - availWidth * hrzAlignmentOfset / 100),
                                        mainViewPort.Tmargin + (int)((availHeight - size.Height) / 2),
                                        (int)(size.Width + 1), (int)(size.Height + 1));

                    g.DrawString(svalue, font.fontObject, font.brushObject, pos, stringFormat);
                    break;
                }
            }
            drawAnnotationPanels(g, _annotationPanels, w, h, true, ref mainViewPort);
            DrawMessagePanels(g, w, h);
            return(0);
        }