Ejemplo n.º 1
0
        public Control()
        {
            if (Parent != null && Parent.Owner != null)
            {
                Parent.Owner.Run(this);
            }
            else if (DefaultController != null)
            {
                DefaultController.Run(this);
            }

            Anchor    = AnchorStyles.Left | AnchorStyles.Top;
            Controls  = new ControlCollection(this);
            Enabled   = true;
            Font      = new Drawing.Font("Arial", 12);
            ForeColor = Color.Black;
            TabIndex  = -1;
            UserGroup = true;
            _visible  = true;

#if UNITY_EDITOR
            var stackTrace = UnityEngine.StackTraceUtility.ExtractStackTrace();
            Source = stackTrace;
#endif
        }
Ejemplo n.º 2
0
        public void Recalculate(PlotDimensions dims, Drawing.Font tickFont)
        {
            if (manualTickPositions is null)
            {
                // first pass uses forced density with manual label sizes to consistently approximate labels
                if (dateFormat)
                {
                    RecalculatePositionsAutomaticDatetime(dims, 20, 24, 10);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, 15, 12, 10);
                }

                // second pass calculates density using measured labels produced by the first pass
                (maxLabelWidth, maxLabelHeight) = MaxLabelSize(tickFont);
                if (dateFormat)
                {
                    RecalculatePositionsAutomaticDatetime(dims, maxLabelWidth, maxLabelHeight, null);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, maxLabelWidth, maxLabelHeight, null);
                }
            }
            else
            {
                tickPositionsMajor = manualTickPositions;
                tickPositionsMinor = null;
                tickLabels         = manualTickLabels;
                cornerLabel        = null;
            }
        }
Ejemplo n.º 3
0
        private (float width, float height) MaxLabelSize(Drawing.Font tickFont)
        {
            if (tickLabels is null || tickLabels.Length == 0)
            {
                return(0, 0);
            }

            string largestString = "";

            foreach (string s in tickLabels.Where(x => string.IsNullOrEmpty(x) == false))
            {
                if (s.Length > largestString.Length)
                {
                    largestString = s;
                }
            }

            if (LabelFormat == TickLabelFormat.DateTime)
            {
                // widen largest string based on the longest month name
                foreach (string s in new DateTimeFormatInfo().MonthGenitiveNames)
                {
                    string s2 = s + "\n" + "1985";
                    if (s2.Length > largestString.Length)
                    {
                        largestString = s2;
                    }
                }
            }

            var maxLabelSize = GDI.MeasureString(largestString.Trim(), tickFont);

            return(maxLabelSize.Width, maxLabelSize.Height);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Drawing.FontからFontInfoに変換します。
 /// </summary>
 public static FontInfo ConvertFont(Drawing.Font font)
 {
     return(new FontInfo()
     {
         Family = new FontFamily(font.FontFamily.Name),
         Size = font.SizeInPoints / 72.0 * 96.0,
         Style = ((font.Style & Drawing.FontStyle.Italic) == 0 ?
                  FontStyles.Normal : FontStyles.Italic),
         Weight = ((font.Style & Drawing.FontStyle.Bold) == 0 ?
                   FontWeights.Normal : FontWeights.Bold),
     });
 }
Ejemplo n.º 5
0
        public Button()
        {
            BackgroundImageLayout = ImageLayout.Center;
            Font              = new Drawing.Font("Arial", 12);
            ForeColor         = Color.FromArgb(64, 64, 64);
            ImageColor        = Color.White;
            NormalColor       = Color.FromArgb(234, 234, 234);
            NormalBorderColor = Color.FromArgb(172, 172, 172);
            HoverColor        = Color.FromArgb(223, 238, 252);
            HoverBorderColor  = Color.FromArgb(126, 180, 234);
            TextAlign         = ContentAlignment.MiddleCenter;
            Size              = new Drawing.Size(75, 23);

            currentBackColor = NormalColor;
        }
Ejemplo n.º 6
0
        public Button()
        {
            BackColor             = Color.FromArgb(234, 234, 234);
            BackgroundImageLayout = ImageLayout.Center;
            BorderColor           = Color.FromArgb(172, 172, 172);
            BorderHoverColor      = Color.FromArgb(126, 180, 234);
            BorderSelectColor     = Color.FromArgb(51, 153, 255);
            CanSelect             = true;
            Font       = new Drawing.Font("Arial", 12);
            ForeColor  = Color.FromArgb(64, 64, 64);
            ImageColor = Color.White;
            HoverColor = Color.FromArgb(223, 238, 252);
            TextAlign  = ContentAlignment.MiddleCenter;
            Size       = new Drawing.Size(75, 23);

            currentBackColor = BackColor;
        }
Ejemplo n.º 7
0
        public void Recalculate(PlotDimensions dims, Drawing.Font tickFont)
        {
            if (manualTickPositions is null)
            {
                // first pass uses forced density with manual label sizes to consistently approximate labels
                if (LabelFormat == TickLabelFormat.DateTime)
                {
                    RecalculatePositionsAutomaticDatetime(dims, 20, 24, (int)(10 * TickDensity));
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, 15, 12, (int)(10 * TickDensity));
                }

                // second pass calculates density using measured labels produced by the first pass
                (LargestLabelWidth, LargestLabelHeight) = MaxLabelSize(tickFont);
                if (LabelFormat == TickLabelFormat.DateTime)
                {
                    RecalculatePositionsAutomaticDatetime(dims, LargestLabelWidth, LargestLabelHeight, null);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, LargestLabelWidth, LargestLabelHeight, null);
                }
            }
            else
            {
                if (manualTickPositions.Length != manualTickLabels.Length)
                {
                    throw new InvalidOperationException($"{nameof(manualTickPositions)} must have the same length as {nameof(manualTickLabels)}");
                }

                double min = Orientation == AxisOrientation.Vertical ? dims.YMin : dims.XMin;
                double max = Orientation == AxisOrientation.Vertical ? dims.YMax : dims.XMax;

                var visibleIndexes = Enumerable.Range(0, manualTickPositions.Count())
                                     .Where(i => manualTickPositions[i] >= min)
                                     .Where(i => manualTickPositions[i] <= max);

                tickPositionsMajor = visibleIndexes.Select(x => manualTickPositions[x]).ToArray();
                tickPositionsMinor = null;
                tickLabels         = visibleIndexes.Select(x => manualTickLabels[x]).ToArray();
                CornerLabel        = null;
                (LargestLabelWidth, LargestLabelHeight) = MaxLabelSize(tickFont);
            }
        }
Ejemplo n.º 8
0
        public void Recalculate(PlotDimensions dims, Drawing.Font tickFont)
        {
            if (manualTickPositions is null)
            {
                // first pass uses forced density with manual label sizes to consistently approximate labels
                if (dateFormat)
                {
                    RecalculatePositionsAutomaticDatetime(dims, 20, 24, 10);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, 15, 12, 10);
                }

                // second pass calculates density using measured labels produced by the first pass
                (maxLabelWidth, maxLabelHeight) = MaxLabelSize(tickFont);
                if (dateFormat)
                {
                    RecalculatePositionsAutomaticDatetime(dims, maxLabelWidth, maxLabelHeight, null);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, maxLabelWidth, maxLabelHeight, null);
                }
            }
            else
            {
                double min = verticalAxis ? dims.YMin : dims.XMin;
                double max = verticalAxis ? dims.YMax : dims.XMax;

                var visibleIndexes = Enumerable.Range(0, manualTickPositions.Count())
                                     .Where(i => manualTickPositions[i] >= min)
                                     .Where(i => manualTickPositions[i] <= max);

                tickPositionsMajor = visibleIndexes.Select(x => manualTickPositions[x]).ToArray();
                tickPositionsMinor = null;
                tickLabels         = visibleIndexes.Select(x => manualTickLabels[x]).ToArray();
                cornerLabel        = null;
                (maxLabelWidth, maxLabelHeight) = MaxLabelSize(tickFont);
            }
        }
Ejemplo n.º 9
0
        private (float width, float height) MaxLabelSize(Drawing.Font tickFont)
        {
            if (tickLabels is null || tickLabels.Length == 0)
            {
                return(0, 0);
            }

            string largestString = "";

            foreach (string s in tickLabels.Where(x => string.IsNullOrEmpty(x) == false))
            {
                if (s.Length > largestString.Length)
                {
                    largestString = s;
                }
            }

            var maxLabelSize = GDI.MeasureString(largestString.Trim(), tickFont);

            return(maxLabelSize.Width, maxLabelSize.Height);
        }
Ejemplo n.º 10
0
        public void ExecuteRecipe(Plot plt)
        {
            Random rand       = new(0);
            int    pointCount = 30;

            double[] xs        = DataGen.Consecutive(pointCount);
            double[] ys        = DataGen.Random(rand, pointCount, 10);
            string[] labels    = ys.Select(x => x.ToString("N2")).ToArray();
            var      labelFont = new Drawing.Font
            {
                Bold      = true,
                Color     = Color.Black,
                Alignment = Alignment.MiddleCenter
            };

            var myBubblePlot = plt.AddBubblePlot();

            for (int i = 0; i < xs.Length; i++)
            {
                // give each bubble a random size and make smaller ones bluer
                double randomValue = rand.NextDouble();
                double bubbleSize  = randomValue * 30 + 10;
                Color  bubbleColor = Drawing.Colormap.Jet.GetColor(randomValue, .5);

                myBubblePlot.Add(
                    x: xs[i],
                    y: ys[i],
                    radius: bubbleSize,
                    fillColor: bubbleColor,
                    edgeColor: Color.Transparent,
                    edgeWidth: 1
                    );

                plt.AddText(labels[i], xs[i], ys[i], labelFont);
            }

            plt.Title("Bubble Plot with Labels");
            plt.AxisAuto(.2, .25); // zoom out to accommodate large bubbles
        }
Ejemplo n.º 11
0
        public void SetFont(object backend, Drawing.Font font)
        {
            var c = (Html5Context)backend;

            c.Font = font;
        }
Ejemplo n.º 12
0
        public static void RenderTickLabels(PlotDimensions dims, Graphics gfx, TickCollection tc, Drawing.Font tickFont, Edge edge, float rotation, bool rulerMode, float PixelOffset, float MajorTickLength, float MinorTickLength)
        {
            if (tc.tickLabels is null || tc.tickLabels.Length == 0)
            {
                return;
            }

            using (var font = GDI.Font(tickFont))
                using (var brush = GDI.Brush(tickFont.Color))
                    using (var sf = GDI.StringFormat())
                    {
                        // TODO: Refactor to improve rotated tick label rendering:
                        //  1) rotation should always be assumed
                        //  2) a separate function should translate/rotate/render/reset
                        //  3) all edges should support rotation
                        if (edge == Edge.Bottom)
                        {
                            if (rotation == 0)
                            {
                                sf.Alignment     = rulerMode ? StringAlignment.Near : StringAlignment.Center;
                                sf.LineAlignment = StringAlignment.Near;
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                                   x: dims.GetPixelX(tc.tickPositionsMajor[i]),
                                                   y: dims.DataOffsetY + dims.DataHeight + PixelOffset + MajorTickLength);
                                }

                                sf.Alignment = StringAlignment.Far;
                                gfx.DrawString(tc.cornerLabel, font, brush, format: sf,
                                               x: dims.DataOffsetX + dims.DataWidth,
                                               y: dims.DataOffsetY + dims.DataHeight + MajorTickLength + tc.maxLabelHeight);
                            }
                            else
                            {
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    float x = dims.GetPixelX(tc.tickPositionsMajor[i]);
                                    float y = dims.DataOffsetY + dims.DataHeight + MajorTickLength + 3;

                                    gfx.TranslateTransform(x, y);
                                    gfx.RotateTransform(-rotation);
                                    sf.Alignment     = StringAlignment.Far;
                                    sf.LineAlignment = StringAlignment.Center;
                                    gfx.DrawString(tc.tickLabels[i], font, brush, 0, 0, sf);
                                    gfx.ResetTransform();
                                }
                            }
                        }
                        else if (edge == Edge.Top)
                        {
                            sf.Alignment     = rulerMode ? StringAlignment.Near : StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Far;
                            for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                            {
                                gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                               x: dims.GetPixelX(tc.tickPositionsMajor[i]),
                                               y: dims.DataOffsetY - PixelOffset - MajorTickLength);
                            }
                        }
                        else if (edge == Edge.Left)
                        {
                            if (rotation == 0)
                            {
                                sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                                sf.Alignment     = StringAlignment.Far;
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                                   x: dims.DataOffsetX - PixelOffset - MajorTickLength,
                                                   y: dims.GetPixelY(tc.tickPositionsMajor[i]));
                                }

                                sf.LineAlignment = StringAlignment.Far;
                                sf.Alignment     = StringAlignment.Near;
                                gfx.DrawString(tc.cornerLabel, font, brush, dims.DataOffsetX, dims.DataOffsetY, sf);
                            }
                            else
                            {
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    float x = dims.DataOffsetX - PixelOffset - MajorTickLength;
                                    float y = dims.GetPixelY(tc.tickPositionsMajor[i]);

                                    gfx.TranslateTransform(x, y);
                                    gfx.RotateTransform(-rotation);
                                    sf.Alignment     = StringAlignment.Far;
                                    sf.LineAlignment = StringAlignment.Center;
                                    gfx.DrawString(tc.tickLabels[i], font, brush, 0, 0, sf);
                                    gfx.ResetTransform();
                                }
                            }
                        }
                        else if (edge == Edge.Right)
                        {
                            sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                            sf.Alignment     = StringAlignment.Near;
                            for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                            {
                                gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                               x: dims.DataOffsetX + PixelOffset + MajorTickLength + dims.DataWidth,
                                               y: dims.GetPixelY(tc.tickPositionsMajor[i]));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
        }
        public void SetFont(object backend, Drawing.Font font)
        {
            var c = (DroidContext)backend;

            c.Font = (FontData)font.GetBackend();
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Required method for Designer support - do not modify
 /// the contents of this method with the code editor.
 /// </summary>
 private void InitializeComponent()
 {
     btnCancel  = new Button();
     btnOK      = new Button();
     groupBox2  = new GroupBox();
     chkEnd     = new RadioButton();
     chkCurrent = new RadioButton();
     chkBegin   = new RadioButton();
     groupBox3  = new GroupBox();
     chkDec     = new RadioButton();
     chkHex     = new RadioButton();
     label1     = new Label();
     txtOffset  = new TextBox();
     groupBox2.SuspendLayout();
     groupBox3.SuspendLayout();
     SuspendLayout();
     //
     // btnCancel
     //
     btnCancel.Anchor       = (AnchorStyles.Bottom | AnchorStyles.Right);
     btnCancel.DialogResult = DialogResult.Cancel;
     btnCancel.Location     = new Drawing.Point(164, 188);
     btnCancel.Name         = "btnCancel";
     btnCancel.Size         = new Drawing.Size(75, 23);
     btnCancel.TabIndex     = 1;
     btnCancel.Text         = "Cancel";
     btnCancel.Click       += btnCancel_Click;
     //
     // btnOK
     //
     btnOK.Anchor       = (AnchorStyles.Bottom | AnchorStyles.Right);
     btnOK.DialogResult = DialogResult.OK;
     btnOK.Location     = new Drawing.Point(84, 188);
     btnOK.Name         = "btnOK";
     btnOK.Size         = new Drawing.Size(75, 23);
     btnOK.TabIndex     = 2;
     btnOK.Text         = "OK";
     btnOK.Click       += btnOK_Click;
     //
     // groupBox2
     //
     groupBox2.Controls.Add(chkEnd);
     groupBox2.Controls.Add(chkCurrent);
     groupBox2.Controls.Add(chkBegin);
     groupBox2.Location = new Drawing.Point(11, 89);
     groupBox2.Name     = "groupBox2";
     groupBox2.Size     = new Drawing.Size(225, 93);
     groupBox2.TabIndex = 12;
     groupBox2.TabStop  = false;
     groupBox2.Text     = "Offset relative to";
     //
     // chkEnd
     //
     chkEnd.AutoSize = true;
     chkEnd.Location = new Drawing.Point(7, 68);
     chkEnd.Name     = "chkEnd";
     chkEnd.Size     = new Drawing.Size(109, 17);
     chkEnd.TabIndex = 2;
     chkEnd.Text     = "End (Backwards)";
     chkEnd.UseVisualStyleBackColor = true;
     //
     // chkCurrent
     //
     chkCurrent.AutoSize = true;
     chkCurrent.Location = new Drawing.Point(7, 45);
     chkCurrent.Name     = "chkCurrent";
     chkCurrent.Size     = new Drawing.Size(97, 17);
     chkCurrent.TabIndex = 1;
     chkCurrent.Text     = "Current offset";
     chkCurrent.UseVisualStyleBackColor = true;
     //
     // chkBegin
     //
     chkBegin.AutoSize = true;
     chkBegin.Checked  = true;
     chkBegin.Location = new Drawing.Point(7, 22);
     chkBegin.Name     = "chkBegin";
     chkBegin.Size     = new Drawing.Size(55, 17);
     chkBegin.TabIndex = 0;
     chkBegin.TabStop  = true;
     chkBegin.Text     = "Begin";
     chkBegin.UseVisualStyleBackColor = true;
     //
     // groupBox3
     //
     groupBox3.Controls.Add(chkDec);
     groupBox3.Controls.Add(chkHex);
     groupBox3.Location = new Drawing.Point(12, 47);
     groupBox3.Name     = "groupBox3";
     groupBox3.Size     = new Drawing.Size(224, 36);
     groupBox3.TabIndex = 13;
     groupBox3.TabStop  = false;
     //
     // chkDec
     //
     chkDec.AutoSize = true;
     chkDec.Location = new Drawing.Point(56, 12);
     chkDec.Name     = "chkDec";
     chkDec.Size     = new Drawing.Size(65, 17);
     chkDec.TabIndex = 4;
     chkDec.Text     = "Decimal";
     chkDec.UseVisualStyleBackColor = true;
     //
     // chkHex
     //
     chkHex.AutoSize = true;
     chkHex.Checked  = true;
     chkHex.Location = new Drawing.Point(6, 12);
     chkHex.Name     = "chkHex";
     chkHex.Size     = new Drawing.Size(44, 17);
     chkHex.TabIndex = 3;
     chkHex.TabStop  = true;
     chkHex.Text     = "Hex";
     chkHex.UseVisualStyleBackColor = true;
     chkHex.CheckedChanged         += chkHex_CheckedChanged;
     //
     // label1
     //
     label1.AutoSize = true;
     label1.Location = new Drawing.Point(13, 9);
     label1.Name     = "label1";
     label1.Size     = new Drawing.Size(42, 13);
     label1.TabIndex = 14;
     label1.Text     = "Offset:";
     //
     // txtOffset
     //
     txtOffset.Location     = new Drawing.Point(12, 25);
     txtOffset.Name         = "txtOffset";
     txtOffset.Size         = new Drawing.Size(224, 22);
     txtOffset.TabIndex     = 15;
     txtOffset.TextChanged += textBox1_TextChanged;
     //
     // FormGoTo
     //
     AutoScaleBaseSize = new Drawing.Size(5, 15);
     BackColor         = Drawing.SystemColors.Control;
     ClientSize        = new Drawing.Size(248, 218);
     Controls.Add(txtOffset);
     Controls.Add(label1);
     Controls.Add(groupBox3);
     Controls.Add(groupBox2);
     Controls.Add(btnOK);
     Controls.Add(btnCancel);
     Font            = new Drawing.Font("Segoe UI", 8.25F);
     FormBorderStyle = FormBorderStyle.FixedDialog;
     MaximizeBox     = false;
     MinimizeBox     = false;
     Name            = "FormGoTo";
     ShowInTaskbar   = false;
     StartPosition   = FormStartPosition.CenterScreen;
     Text            = "Goto";
     Activated      += FormGoTo_Activated;
     groupBox2.ResumeLayout(false);
     groupBox2.PerformLayout();
     groupBox3.ResumeLayout(false);
     groupBox3.PerformLayout();
     ResumeLayout(false);
     PerformLayout();
 }
Ejemplo n.º 15
0
        public static void RenderTickLabels(PlotDimensions dims, Graphics gfx, TickCollection tc, Drawing.Font tickFont, Edge edge, float rotation, bool rulerMode, float PixelOffset, float MajorTickLength, float MinorTickLength)
        {
            if (tc.tickLabels is null || tc.tickLabels.Length == 0)
            {
                return;
            }

            using var font  = GDI.Font(tickFont);
            using var brush = GDI.Brush(tickFont.Color);
            using var sf    = GDI.StringFormat();

            Tick[] visibleMajorTicks = tc.GetVisibleMajorTicks(dims);

            switch (edge)
            {
            case Edge.Bottom:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.GetPixelX(visibleMajorTicks[i].Position);
                    float y = dims.DataOffsetY + dims.DataHeight + MajorTickLength;

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment = rotation == 0 ? StringAlignment.Center : StringAlignment.Far;
                    if (rulerMode)
                    {
                        sf.Alignment = StringAlignment.Near;
                    }
                    sf.LineAlignment = rotation == 0 ? StringAlignment.Near : StringAlignment.Center;
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            case Edge.Top:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.GetPixelX(visibleMajorTicks[i].Position);
                    float y = dims.DataOffsetY - MajorTickLength;

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment = rotation == 0 ? StringAlignment.Center : StringAlignment.Near;
                    if (rulerMode)
                    {
                        sf.Alignment = StringAlignment.Near;
                    }
                    sf.LineAlignment = rotation == 0 ? StringAlignment.Far : StringAlignment.Center;
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            case Edge.Left:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.DataOffsetX - PixelOffset - MajorTickLength;
                    float y = dims.GetPixelY(visibleMajorTicks[i].Position);

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment     = StringAlignment.Far;
                    sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                    if (rotation == 90)
                    {
                        sf.Alignment     = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Far;
                    }
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            case Edge.Right:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.DataOffsetX + PixelOffset + MajorTickLength + dims.DataWidth;
                    float y = dims.GetPixelY(visibleMajorTicks[i].Position);

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment     = StringAlignment.Near;
                    sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                    if (rotation == 90)
                    {
                        sf.Alignment     = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Near;
                    }
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            default:
                throw new NotImplementedException($"unsupported edge type {edge}");
            }

            if (!string.IsNullOrWhiteSpace(tc.CornerLabel))
            {
                switch (edge)
                {
                case Edge.Bottom:
                    sf.Alignment     = StringAlignment.Far;
                    sf.LineAlignment = StringAlignment.Near;
                    gfx.DrawString(s: "\n" + tc.CornerLabel,
                                   x: dims.DataOffsetX + dims.DataWidth,
                                   y: dims.DataOffsetY + dims.DataHeight + MajorTickLength,
                                   font: font, brush: brush, format: sf);
                    break;

                case Edge.Left:
                    sf.Alignment     = StringAlignment.Near;
                    sf.LineAlignment = StringAlignment.Far;
                    gfx.DrawString(s: "\n" + tc.CornerLabel,
                                   x: dims.DataOffsetX,
                                   y: dims.DataOffsetY,
                                   font: font, brush: brush, format: sf);
                    break;

                case Edge.Top:
                    throw new NotImplementedException("multiplier and offset notation is not supported for right and top axes");

                case Edge.Right:
                    throw new NotImplementedException("multiplier and offset notation is not supported for right and top axes");

                default:
                    throw new NotImplementedException($"unsupported edge type {edge}");
                }
            }
        }