Profile Picture

Always Show 0 on Axes for XY Scatter Charts

Posted By Alan Schofield 12 Years Ago
Author
Message
Alan Schofield
Posted 12 Years Ago
View Quick Profile
Junior Member

Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 15, Visits: 1
Hi,

Is there a simple way to always show the 0 point on both the X and Y axes in an XY Scatter Chart.

The chart works fine for most data but where there are only negative values the chart starts at the highest value (plus a bit of inflation).

For example I have two bubbles positioned on the Y Axis at -0.6 and -0.9
Under these circumstances, the Y Axis range is from -0.5 to -1.0

Ideally I would like to always show the zero position.

Regards,
Al.


Nevron Support
Posted 12 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 11 hours ago
Posts: 3,054, Visits: 4,009

Hi Alan,

The easiest way to achieve this is by having a dummy series with value 0:

   NChart chart = nChartControl1.Charts[0];

   NPointSeries point = new NPointSeries();

   point.Values.Add(10);
   point.Values.Add(20);
   point.Values.Add(30);

   chart.Series.Add(point);

   NPointSeries dummySeries = new NPointSeries();
   dummySeries.DataLabelStyle.Visible = false;
   dummySeries.Size = new NLength(0);
   dummySeries.Values.Add(0);
   dummySeries.Legend.Mode = SeriesLegendMode.None;

   chart.Series.Add(dummySeries);

   nChartControl1.Refresh();

Alternatively you can install a new content view:

  class NCustomContentAxisView : NContentAxisView
  {
   public override NRange1DD GetViewRange(NRange1DD range, ref bool isZoomed)
   {
    range = base.GetViewRange(range, ref isZoomed);

    if (!isZoomed)
    {
     range.Normalize();

     if (range.Begin > 0)
     {
      range.Begin = 0;
     }
     else if (range.End < 0)
     {
      range.End = 0;
     }
    }
    
    return range;
   }
  }

  private void button1_Click(object sender, EventArgs e)
  {
   NChart chart = nChartControl1.Charts[0];
   chart.Axis(StandardAxis.PrimaryY).View = new NCustomContentAxisView();

   NPointSeries point = new NPointSeries();

   point.Values.Add(10);
   point.Values.Add(20);
   point.Values.Add(30);

   chart.Series.Add(point);

   nChartControl1.Refresh();
  }

 

Hope this helps - let us know if you meet any problems.



Best Regards,
Nevron Support Team



Nevron Support
Posted 12 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 11 hours ago
Posts: 3,054, Visits: 4,009

A small correction - the code below is for the .NET chart - in SSRS you need to insert the following custom code:

using System;
using System.Drawing;
using Nevron.GraphicsCore;
using Nevron.Chart;
using Nevron.ReportingServices;

namespace MyNamespace
{
  class NCustomContentAxisView : NContentAxisView
  {
   public override NRange1DD GetViewRange(NRange1DD range, ref bool isZoomed)
   {
    range = base.GetViewRange(range, ref isZoomed);

    if (!isZoomed)
    {
     range.Normalize();

     if (range.Begin > 0)
     {
      range.Begin = 0;
     }
     else if (range.End < 0)
     {
      range.End = 0;
     }
    }
   
    return range;
   }
  }

 /// <summary>
 /// Sample class
 /// </summary>
 public class MyClass
 {
  /// <summary>
  /// Main entry point
  /// </summary>
  /// <param name="context"></param>
  public static void RSMain(NRSChartCodeContext context)
  {
   context.Document.Charts[0].Axis(StandardAxis.PrimaryY).View = new NCustomContentAxisView();
  }
 }
}

Let us know if you meet any probelms...



Best Regards,
Nevron Support Team



Alan Schofield
Posted 12 Years Ago
View Quick Profile
Junior Member

Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 15, Visits: 1

Hi,

Thanks for the code, I finally managed to get round to trying it.

Basically it 'works' but with some side effects.

If all Y-Axis numbers are positive the axis starts at a minus value equivalent to 1 scale interval. For example, I had a chart who's Y-Axis scale ran from 0 to 1.8 in 0.2 intervals but with the new code it now runs from -0.2 to 1.8 in 0.2 intervals.

I'm not sure what is causing this as the code seems logical. I'll need to amend it to take into account various scenarios but for now this is the biggest issue.

Can you suggest anything that I can try?

Also, I can't find the full API reference for the SSRS component, only the .NET conponent, can you point me in the right direction please.

Many thanks for your help so far.

Regards,

Al.



Nevron Support
Posted 12 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 11 hours ago
Posts: 3,054, Visits: 4,009

Hi Alan,

This is caused by view range inflate. By default the control will inflate all ranges to end on an exact tick. If the content range falls on an exact tick then an additional tick is added. This is required in order to produce better looking charts. There are two ways to turn off this feature:

1. From chart designer go to Axis \ PrimaryY \ Range  switch the inflate mode to Tick (if it is not in that mode) and uncheck "Inflate range begin".

2. From code this is achieved with the following:

NLinearScaleConfigurator scaleY = context.Document.Charts[0].Axis(StandardAxis.PrimaryY).ScaleConfigurator as NLinearScaleConfigurator;
scaleY.InflateViewRangeBegin = false;

Regarding the API - the chart for SSRS API is the same as in .NET - only the way you obtain a reference to the chart document is different. In .NET apps you need to write something like:

nChartControl.Document to gain access to the chart document whereas in SSRS the code is context.Document. All the rest is the same - objects properties, enums, methods etc.

Hope this helps - let us know if you have any questions or meet any problems.



Best Regards,
Nevron Support Team



Alan Schofield
Posted 12 Years Ago
View Quick Profile
Junior Member

Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 15, Visits: 1

Hi,

Thanks for the response. Unfortunately I cannot get this to work.

To elimintae another other issues I've created a simple project that shows the issue and attached it.

If you look at the "BubbleShowZeroIssue" report and choose to show positive or negative numbers from the  report parameter, you'll see what I mean (hopefully!)

To create this report I simply added a new report and then added a chart control (XY Scatter).
I then set the X, Y and Size properties. After that I added constant lines to both axes at zero and set the stroke width. Finally I added the code supplied above. The only modification to the code was to apply it to both the X and Y axes.

I hope this helps you help me !

Thanks again.

Regards,Al.

 



Attachments
NevronBubbleZeroLinesIssueSample.zip (322 views, 40.00 KB)
Nevron Support
Posted 12 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 11 hours ago
Posts: 3,054, Visits: 4,009

Hi Alan,

The problem in this case is that you need to hook at a different stage of the axis range calculation (so that you have both the inflate generated by the bubble size and still ensure that the axis contains zero). You can try the following code:

using System;
using System.Drawing;
using Nevron.GraphicsCore;
using Nevron.Chart;
using Nevron.ReportingServices;

namespace MyNamespace
{
 /// <summary>
 /// Sample class
 /// </summary>
 public class MyClass
 {
  /// <summary>
  /// Main entry point
 /// </summary>
 /// <param name="context"></param>
 public static void RSMain(NRSChartCodeContext context)
 {
 NChart chart = context.Document.Charts[0];
 NAxis[] axesToInflateToZero = new NAxis[] { chart.Axis(StandardAxis.PrimaryX), chart.Axis(StandardAxis.PrimaryY) };

   for (int i = 0; i < axesToInflateToZero.Length; i++)
   {
    NAxis axis = axesToInflateToZero[i];

    axis.UpdateScale();

    NCustomRangeInflator customRangeInflator = new NCustomRangeInflator(new NRange1DD[] { new NRange1DD(0, 0) });
    customRangeInflator.InflateBegin = true;
    customRangeInflator.InflateEnd = true;
    axis.Scale.ViewRangeInflators.Insert(0, customRangeInflator);
   }
  }
 }
}

Let us know if you meet any problems...



Best Regards,
Nevron Support Team



Alan Schofield
Posted 12 Years Ago
View Quick Profile
Junior Member

Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 15, Visits: 1

Hi,

Thanks for the response. I think I'm almost there. The only issue now is that the axis scale intervals *can* be too small. I guess it's because it is being calculated before the update to the range? It happens when all the value are within a narrow range but not close to zero. e.g value 1,2 and 3 would be fine but value 21,22 and 23 would not be as the interval is too small for the overall range (0-23).

I've tried to find documentation relating to this to see if I can get the intervals reevaluated at the end of the process but I'm finding it hard to locate the info I need and as I'm using SSRS I don't have the luxury of intellisense to navigate round the object model. Could you point me I the right direction please.

P.S. You won't see the issue with the sample I sent as the value are too small but just to clarify. If I have values that ranged between say, 3 and 4 on the X-Axis then the axis intervals are 0.2. But now we've adjusted the X-Axis range to be 0-4 the intervals remaining at 0.2 is too cluttered. The Axis interval needs to be reevaluated for the new range (0-4).

Once again, many thanks for you help.



Nevron Support
Posted 12 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 11 hours ago
Posts: 3,054, Visits: 4,009

Hi Alan,

There is no easy workaround for this - probably one workaround will be to dynamically enable disable range inflate depending on whether the axis was inflated or not. We would recommend to stick with the original content inflate solution (and probably turn off series axis inflate and add some additional inflate to the content range):

 

using System;
using System.Drawing;
using Nevron.GraphicsCore;
using Nevron.Chart;
using Nevron.ReportingServices;

namespace MyNamespace
{
  class NCustomContentAxisView : NContentAxisView
  {
   public override NRange1DD GetViewRange(NRange1DD range, ref bool isZoomed)
   {
    range = base.GetViewRange(range, ref isZoomed);
    range.Inflate(range.GetLength() * 0.2);

    if (!isZoomed)
    {
     range.Normalize();

     if (range.Begin > 0)
     {
      range.Begin = 0;
     }
     else if (range.End < 0)
     {
      range.End = 0;
     }
    }
   
    return range;
   }
  }

 /// <summary>
 /// Sample class
 /// </summary>
 public class MyClass
 {
  /// <summary>
  /// Main entry point
  /// </summary>
  /// <param name="context"></param>
  public static void RSMain(NRSChartCodeContext context)
  {
   context.Document.Charts[0].Axis(StandardAxis.PrimaryY).View = new NCustomContentAxisView();

// Turn off Inflate margins 
   context.Document.Charts[0].Series[0].InflateMargins = false;
  }
 }
}


The drawback here is that you may have bubbles gettings outside the plot area...



Best Regards,
Nevron Support Team



Alan Schofield
Posted 12 Years Ago
View Quick Profile
Junior Member

Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)Junior Member (15 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 15, Visits: 1

Hi,

Thanks for the reply as always.

I'll have a think about it and see what I can come up with. If I get something working well, I'll post my solution here. In the shortterm I think I'll have two version of the reports and get SSRS to check the data then show or hide the respective sub reports.

Thans again,

Al.

 





Similar Topics


Reading This Topic