Search code examples
c#winformschartsaxes

Setting a common zero on primary and secondary Y axes


How do I get a secondary Y-axis to share a zero point with the primary Y-axis? I don't care about the rest of the intervals lining up or anything of that sort, I just want the primary and secondary Y-axes to share the same zero.

I'm aggregating data by week by default, but my chart can change to aggregate by day or month as well. As an example, when I aggregate by week, all values are positive on both axes, so the bottom of the chart sits at 0 (see https://i.sstatic.net/f8w30.jpg), but when I aggregate daily, I get some negative values on the primary axis. At that point, I still have all positive values on the secondary axis, so the bottom of the graph jumps down to -2000 on the primary axis and stays at 0 on the secondary (see https://i.sstatic.net/gAB1c.jpg).

I've tried setting the Axis.Crossing attribute on the axes, I've tried setting the minimums equal, I've tried a number of other things and nothing seems to work. Is there any way to use a common zero so that low positive values on the secondary axis don't look like they're negative as happens in the second image?

Edit: I'm using WinForms in Visual Studio 2010


Solution

  • You can force the Axes to share their Minimum and also Maximum values by setting the Axis.Minimum and Maximum values, e.g. like this:

     ChartArea CA = chart1.ChartAreas[0];
     CA.AxisY2.Maximum = CA.AxisY.Maximum;
     CA.AxisY2.Minimum = CA.AxisY.Minimum;
    

    If you don't know how the values are spread you may want to calculate the common min and max values:

     ChartArea CA = chart1.ChartAreas[0];
    
     double min = Math.Min(CA.AxisY.Minimum, CA.AxisY2.Minimum);
     double max = Math.Max(CA.AxisY.Maximum, CA.AxisY2.Maximum);
    
     CA.AxisY.Maximum = max;
     CA.AxisY2.Maximum = max;
     CA.AxisY.Minimum = min;
     CA.AxisY2.Minimum = min; 
    

    Note that this will change the display for the Points in one or both Series..:

    enter image description hereenter image description here

    Also note that whichever way you change those values, the Axes will have to display the truth about the values; so if the two Series display values in different scales you will have to find a way to calculate the min&max values so that they share a common zero.

    If e.g. you know that the 2nd Series values are x times larger you could set its min/max values to x times of those from Series1..:

     CA.AxisY.Maximum = 15 * CA.AxisY2.Maximum;
     CA.AxisY.Minimum = 15 * CA.AxisY2.Minimum;
    

    This is a rather simple way, but it works (using different data point values):

    enter image description hereenter image description here