Search code examples
c#.netwinformsmschart

Chart is rescaling area for axis labels when long labels appear due to scrolling


I have some string labels that are associated with a number each. I've created a Chart element with one ChartArea and one Series which is using the SeriesChartType.Bar type to show my labels on the x-axis (which, confusingly, is the vertical axis when using the Bar type, but anyway...) and show the number as a bar next to it.

Since I have many labels that don't fit on the screen at once, I "enabled" the scrollbar using the Zoom method in my Paint event handler like this:

private void chart1_Paint(object sender, PaintEventArgs e)
{
    var scaleView = chart1.ChartAreas.First().AxisX.ScaleView;
    var pos = double.IsNaN(scaleView.Position) ? 0.0 : scaleView.Position;
    scaleView.Zoom(pos, pos + chart1.Height / 22.0);
}

I don't know if this is the proper way to do that, but it does (almost) what I want:

  • show the scrollbar if there are too many data points (labels) to fit on the screen
  • update the visible area properly when the window is resized

There is only one annoying thing: If due to scrolling a long label appears in the visible area or disappears, the area occupied by the labels is adjusted to the longest visible label. I hope these screenshots explain what I mean:

Here one long label is visible (at the bottom): with long label visible

Here I scrolled up by one unit so that the long label is not visible any more: without long label

This is super annoying during scrolling as everything gets rescaled whenver a long label appears or disappears.

How to fix the area occupied by the labels to always fit the longest label in the series, no matter if it is currently visible or not? I tried IsLabelAutoFit = false for both, x- and y-axis, but that doesn't help.


Solution

  • Ok, I've got it. I used

    chartArea.InnerPlotPosition.Auto = false;
    InnerPlotPosition.X = 33.333;
    

    to give one third of the chart area to the labels and the other two thirds to the bars. InnerPlotPosition.Auto = false makes this fixed so that it doesn't update while scrolling.