.Net Charts - X Axis with Different Intervals [dup

2020-05-03 00:57发布

问题:

This question already has an answer here:
Closed 2 years ago.

I am using .Net Charts. In that, I have displayed a line chart with an Interval of 28 Days.

Here is my code:

 Chart1.ChartAreas["ChartArea1"].AxisX.IntervalOffset = 1;
 Chart1.ChartAreas["ChartArea1"].AxisX.Minimum = min;
 Chart1.ChartAreas["ChartArea1"].AxisX.Maximum = max;
 Chart1.ChartAreas["ChartArea1"].AxisX.Interval = 28;

But, one of my situation comes like,

28 Days Interval, 35 Days Interval, 28 Days Interval etc. Is that possible to have different Intervals.

回答1:

No, Interval is an Axis property and there can only be one.

You can work around this restriction by drawing gridlines and labels on your own.


Let's assume you have a list of stop points, i.e. the indices of the DataPoints where you want a GridLine to appear:

List<int> stops = new List<int>();

After adding a few test numbers stops.AddRange(new[] { 12, 23, 42, 52, 82 }); we can code the PostPaint event of the Chart to draw lines:

private void chart_PostPaint(object sender, ChartPaintEventArgs e)
{
    Graphics g = e.ChartGraphics.Graphics;
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;

    ChartArea ca = chart.ChartAreas[0];

    Font font = ca.AxisX.LabelStyle.Font;
    Color col = ca.AxisX.MajorGrid.LineColor;
    int padding = 10; // pad the labels from the axis

    double aymin = ca.AxisY.Minimum;
    double aymax = ca.AxisY.Maximum;

    int y0 = (int)ca.AxisY.ValueToPixelPosition(aymin);
    int y1 = (int)ca.AxisY.ValueToPixelPosition(aymax);

    foreach (int sx  in stops)
    {
        int x = (int)ca.AxisX.ValueToPixelPosition(chart.Series[0].Points[sx].XValue);

        using (Pen pen = new Pen(col))
            g.DrawLine(pen, x, y0, x, y1);

        string s =  chart.Series[0].Points[sx].XValue + "";
        if (ca.AxisX.LabelStyle.Format != "") s = string.Format(ax.LabelStyle.Format, s);

        SizeF sz = g.MeasureString(s, font, 999);
        g.DrawString(s, font, Brushes.Black, (int)(x - sz.Width / 2) , y0 + padding);
    }
}

After turning off the original MajorGrid etc..

ChartArea ca = chart.ChartAreas[0];

ca.AxisX.MajorGrid.Enabled = false;
ca.AxisX.MajorTickMark.Enabled = false;
ca.AxisX.LabelStyle.Enabled = false;

..this is the result:

Notes:

  • Most of the code are just simple preparations and references. The actual drawing are 2 methods and three or four more lines to get the coordinates..

  • I have stored the DataPoint indices in my List. If you want the custom GridLines to be independent of DataPoints you can instead store the Values and change the List to a List<double> andthe two references from chart.Series[0].Points[sx].XValue to accessing the stop values sx directly.

  • Change the padding value to suit you..

  • We can access the axes' minima and maxima values freely, even if they are actually set to Auto. This is because we are in a Paintevent. Otherwise we would have to call RecalculateAxesScale() on the ChartArea..

  • Feel free to make the Black label brush dynamic as well..