Search code examples
c#chartsgridlogarithm

Setting fixed major grid marks independent of data range


This is my first project in c# and I'm trying to create plots from data.

I'm struggling with drawing minor and major grid lines and labels on a logarithmic scale.

I've set the scale to logarithmic, set the base to 10 and both major and minor intervals to 1, and it works great, however, the interval starts with the minimum value on scale, so for example if data starts at 30M (I'm dealing with frequencies) the next major tick is at 300M and 3G, which is not as it should be.

Is there a way to set major grid to 1, 10, 100 etc, independent of what data is displayed? i've tried changing intervals, base and offset but have not achieved much.

area.AxisX.IsLogarithmic = true;
area.AxisX.LogarithmBase = 10;
area.AxisX.Interval = 1;
//area.AxisX.IntervalOffset = 10000;
area.AxisX.IntervalAutoMode = IntervalAutoMode.FixedCount;
area.AxisX.MajorGrid.Enabled = true;
area.AxisX.MajorTickMark.Enabled = true;


area.AxisX.MinorGrid.Enabled = true;
area.AxisX.MinorGrid.Interval = 1;

area.AxisX.MinorTickMark.Enabled = true;
area.AxisX.MinorTickMark.Interval = 1;
area.AxisX.Minimum = minMaxXY[0];  // in this example 30 M
area.AxisX.Maximum = minMaxXY[1];  // in this example 1 G

here's the link to the current grid https://ibb.co/3WkxLfc

Thank you for your time and answers!


Solution

  • Thanks to TaW replay I managed to get my program working.

    Here is my solution using customLabels location to draw the grid lines.

        private void Chart1_PostPaint(object sender, ChartPaintEventArgs e)
        {
            if (e.Chart.ChartAreas.Count > 0) // I don't yet truly understand when this event occurs, 
                                              // so I got plenty of null references.
            {
                Graphics g = e.ChartGraphics.Graphics;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                Color minorGridColor = Color.Gainsboro;
                ChartArea area = e.Chart.ChartAreas[0];
    
                double aymin = area.AxisY.Minimum;
                double aymax = area.AxisY.Maximum;
                int y0 = (int)area.AxisY.ValueToPixelPosition(aymin);
                int y1 = (int)area.AxisY.ValueToPixelPosition(aymax);
    
                foreach (var label in chart1.ChartAreas[0].AxisX.CustomLabels)
                {
                    double xposition = area.AxisX.ValueToPixelPosition(Math.Pow(10, label.FromPosition + 0.1));
                    if (xposition > area.AxisX.ValueToPixelPosition(minMaxXY[0]) && xposition < area.AxisX.ValueToPixelPosition(minMaxXY[1]))
                    //this prevents drawing of lines outside of the chart area
                    {
                        int x = (int)xposition;
                        using (Pen dashed_pen = new Pen(Color.FromArgb(10, 0, 0, 0), 1))
                        {
                            dashed_pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                            g.DrawLine(dashed_pen, x, y0, x, y1);
    
                        }
                    }
                }
            }
        }
    

    I also found the CustomLabel.GridTicks Property, but for some reason it did not work.