locked
Automatic nice label spacing? RRS feed

  • Question

  • How do I get the graph control to annotate the X axis at nicely spaced intervals?
    When I create a test graph, for some reason it starts the numbering at -1 and goes up in steps of 500, giving -1, 499, 999 etc...

    It would be much better for it to start at 0!

    Clearly I can program this explicitly myself using chartArea.AxisX.IntervalOffset, but is there any way to make the graph compute it automatically? It's a pain to do this when you allow the user to zoom the graph.

    It's easy to make a test app to demonstrate what I mean:

    (1) Create a default Windows Forms app. Leave everything at default, so the form name will be "Form1".
    (2) Drop a System.Windows.Forms.DataVisualization.Charting.Chart onto the form, and set Dock to Fill. (Leave the name of the control as "chart1".)
    (3) Replace the contents of "Form1.cs" with the code below.
    (4) Run the program, and observe that the numbers aren't nicely spaced.
    (5) Click and drag to select an area to zoom on. Note that after zooming the numbers are also not nicely spaced.

    using System; 
    using System.Diagnostics; 
    using System.Windows.Forms; 
    using System.Windows.Forms.DataVisualization.Charting; 
     
    namespace WindowsFormsApplication1 
        public partial class Form1: Form 
        { 
            public Form1() 
            { 
                InitializeComponent(); 
     
                this.chart1.Legends.Clear(); 
     
                Series series = this.chart1.Series[0]; 
                series.ChartType = SeriesChartType.FastLine; 
     
                series.Points.DataBindXY(calculateXValues(), calculateYValues()); 
     
                ChartArea chartArea = this.chart1.ChartAreas[0]; 
     
                chartArea.AxisX.LabelStyle.Format = "f0"
                chartArea.AxisX.ScaleView.Zoomable = true
     
                chartArea.AxisX.IntervalOffset = 1
     
                chartArea.CursorX.IsUserEnabled = true
                chartArea.CursorX.IsUserSelectionEnabled = true
            } 
     
            private double[] calculateXValues() 
            { 
                double[] result = new double[_numValues]; 
     
                for (int i = 0; i < _numValues; ++i) 
                { 
                    result[i] = i; 
                } 
     
                return result; 
            } 
     
            private double[] calculateYValues()  // Simple sine-based function. 
            { 
                double[] result = new double[_numValues]; 
     
                for (int i = 0; i < _numValues; ++i) 
                { 
                    double angle1 = Math.PI * ((i % 1000)/500.0); 
                    double angle2 = Math.PI * ((i % 100)/50.0); 
                    double angle3 = Math.PI * ((i % 10000)/5000.0); 
                    double value  = 10 * Math.Sin(angle1) + 2 * Math.Sin(angle2) + Math.Sin(angle3); 
     
                    result[i] = value; 
                } 
     
                return result; 
            } 
     
            private const int _numValues = 2002
        } 
     

    Tuesday, March 3, 2009 3:06 PM

Answers

  • Your X values are in range from 0 to 2001, chart adds a margin of 1 on each side and you got Axis scale Minimum starting from -1. What axis scale (Min/Max) do you want to get? Your solution maybe as easy as starting X values from 1 instead of 0.

    If you want to add more spacing on the sides of your data you can call Axis.RoundAxisValues method. It will create more rounded axis scale but it will still start in the negative numbers.


    Alex.


    http://blogs.msdn.com/alexgor
    Wednesday, March 4, 2009 4:23 PM

All replies

  • Try setting Axis.IsMarginVisible to false...

    Alex.


    http://blogs.msdn.com/alexgor
    Tuesday, March 3, 2009 3:55 PM
  • Hi, thanks for the reply!

    That solution works when you're not zoomed in; unfortunately, as soon as you zoom in, if you scroll away from the beginning of the graph the numbers go all uneven again.

    The code I posted shows the problem (even with IsMarginVisible set to false); just run the program, select an area of the graph to zoom it, and then scroll it around using the scroll bar.

    I can't help but think the uneven numbers were not intended...
    Tuesday, March 3, 2009 5:03 PM
  • You can use Chart.AxisViewChanging event to detect zoom operations and adjust/round axis view position and size the way you need.

    Alex.


    http://blogs.msdn.com/alexgor
    Tuesday, March 3, 2009 6:36 PM
  • Hmm, but that's just a kludgey workaround... In order to do that properly, I'd have to work out how big the labels would be (depending on their font size) and calculate a spacing and start offset so that they fit nicely. I would have to redo that calculation when the user resizes the display, since more or less labels may be displayable after resizing. What's worse is that I cannot let the graph automatically select an interval and base my calculations on that. If you have automatic intervals, the graph won't tell you what interval it has selected: If you inspect the axis' Interval property, it is always zero.

    I also discovered that if you set Axis.IntervalOffset to something other than zero, then setting Axis.LabelStyle.IsEndLabelVisible to false has no effect. (That means the right edge of the graph area moves around as you scroll the graph, since it is changing the displayed width of the graph in order to fit the last label in - which is really horrible.)

    I guess this control just doesn't support automatic nice label intervals for numbers. A shame, because we were hoping to use this instead of the ComponentOne chart that we're currently using; alas, it looks like it's not up to the job of replacing it. :(

    It's particularly weird, since if you have date/times along the X axis, it DOES do things properly - the dates and times are at nice intervals! But the feature for doing that is simply missing for ordinary numbers.

    Wednesday, March 4, 2009 9:41 AM
  • Your X values are in range from 0 to 2001, chart adds a margin of 1 on each side and you got Axis scale Minimum starting from -1. What axis scale (Min/Max) do you want to get? Your solution maybe as easy as starting X values from 1 instead of 0.

    If you want to add more spacing on the sides of your data you can call Axis.RoundAxisValues method. It will create more rounded axis scale but it will still start in the negative numbers.


    Alex.


    http://blogs.msdn.com/alexgor
    Wednesday, March 4, 2009 4:23 PM