Problem with bar chart in Clustered mode with DateTime scale


Author
Message
MIke Arkhipov
MIke Arkhipov
Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)
Group: Forum Members
Posts: 7, Visits: 1
I have two bar series. X axis is date-time. The series are set to be displayed adjacently (series.MultiBarMode = MultiBarMode.Clustered)

Everything is fine unless all X values are same. In this case the X scale collapses in one dot and the axis displays only seconds without date: "01". This happens when I use any MultiBarMode except MultiBarMode.Series.

The code is following:
public partial class Form1 : Form
{
public void ConfigureChart(DataView data, bool primary)
{
NChartControl chartControl = nChartControl1;
chartControl.DataBindingManager.RemoveAllBindings();
NChart chart = chartControl.Charts[0];
chart.Axis(StandardAxis.SecondaryY).Visible = true;
NBarSeries series = (NBarSeries)chart.Series.Add(SeriesType.Bar);
series.MultiBarMode = MultiBarMode.Clustered; //!!
series.DisplayOnAxis(StandardAxis.PrimaryY, primary);
series.DisplayOnAxis(StandardAxis.SecondaryY, !primary);
series.UseXValues = true;
chartControl.DataBindingManager.RemoveAllBindings();

NDateTimeScaleConfigurator xsc = new NDateTimeScaleConfigurator();
chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator = xsc;

NOrdinalScaleConfigurator ysc = new NOrdinalScaleConfigurator();
chart.Axis(StandardAxis.PrimaryY).ScaleConfigurator = ysc;

NLinearScaleConfigurator yprimesc = new NLinearScaleConfigurator();
chart.Axis(StandardAxis.SecondaryY).ScaleConfigurator = yprimesc;

int index = chart.Series.IndexOf(series);
chartControl.DataBindingManager.AddBinding(0, index, "XValues", data, "x");
chartControl.DataBindingManager.AddBinding(0, index, "Values", data, "y");

chartControl.Refresh();
}


public Form1()
{
InitializeComponent();

DataTable t = new DataTable();
t.Columns.Add("x", typeof(DateTime));
t.Columns.Add("y", typeof(double));

t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), -10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), -10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 0);
ConfigureChart(t.DefaultView, true);
ConfigureChart(t.DefaultView, false);
}

}





Am I doing something wrong? How to fix the axis label to display full date, not only seconds?


Thank you.


Mike Arkhipov

Attachments
clustered mode.png (46 views, 43.00 KB)
Blagovest Milanov
Blagovest Milanov
Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)
Group: Forum Members
Posts: 154, Visits: 15

Hi Mike,

The problem with the configuration below is that sets equal X values to all bars in the master cluster series - if you change:

t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), -10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), -10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 0);

to:

t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 10);
t.Rows.Add(new DateTime(2000, 10, 11, 1, 1, 1), -10);
t.Rows.Add(new DateTime(2000, 10, 12, 1, 1, 1), 10);
t.Rows.Add(new DateTime(2000, 10, 13, 1, 1, 1), -10);
t.Rows.Add(new DateTime(2000, 10, 14, 1, 1, 1), 0);

you will get floating cluster bars. It does not display correctly in the order case as the range length of the x axis becomes zero.

How to fix the axis label to display full date, not only seconds?

When the X axis has zero length it will display milliseconds actually - as the axis uses unit / range sensitive formatting. If you use the code above it will switch to date time formatting (day, month, year according to the current culture settings). You can also override this:

xsc.EnableUnitSensitiveFormatting = false;
xsc.LabelValueFormatter = new NDateTimeValueFormatter("MM/dd/yy");

In the case above - "MM/dd/yy" can be any date time formatting string.

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

Best regards,
Bob

 


 


MIke Arkhipov
MIke Arkhipov
Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)
Group: Forum Members
Posts: 7, Visits: 1
Well, the range sensitive formatting is a very nice feature which I wouldn't like to turn off.
And we can't control the data. In most cases we get distinct X values, but sometimes they may be all equal.
But even with equal X date values when the series.MultiBarMode is set to MultiBarMode.Simple we get a two day time range (from 10/9/2000 to 10/11/2000) on the X axis.

Is there some reason for not having same behavior with MultiBarMode.Clustered?
If not, this may be considered a clustered mode bug.


Mike Arkhipov

Blagovest Milanov
Blagovest Milanov
Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)
Group: Forum Members
Posts: 154, Visits: 15

Hi Mike,

In cluster mode only the master series x values will be regarded. When you use MultibarMode.Series both series x values will be taken into account. You can consider some additional inflate to the x-axis to ensure the range does not drop to zero:

NDateTimeScaleConfigurator xsc = new NDateTimeScaleConfigurator();
xsc.ViewRangeInflateMode = ScaleViewRangeInflateMode.Absolute;
xsc.AbsoluteInflate = new NRange1DL(10, 10);
chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator = xsc;

That way you'll always have 10 points from the left and right sides of the chart (or more) regardless of the range of the data. BTW I would recommend using the range timeline or value timeline scales when you display date time - they're much more informative.

Let me know if you have any questions.

Best regards,
Bob


MIke Arkhipov
MIke Arkhipov
Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)
Group: Forum Members
Posts: 7, Visits: 1
Hi Bob,

I have tried adding the code

xsc.ViewRangeInflateMode = ScaleViewRangeInflateMode.Absolute;
xsc.AbsoluteInflate = new NRange1DL(10, 10);

but I still get the same result.
I also tried NRange1DL(0, 10) and different scale configurators (RangeTimeline, ValueTimeline)

Any ideas why?

Thanks for your help!


Mike Arkhipov

Blagovest Milanov
Blagovest Milanov
Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)
Group: Forum Members
Posts: 154, Visits: 15

Hi Mike,

Are you testing with the code / data above or there are additional settings? If so can you post the code for review? It worked fine when I tested so it must be something small - so I want to make sure we use the same chart configuration.

Best regards,
Bob


MIke Arkhipov
MIke Arkhipov
Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)
Group: Forum Members
Posts: 7, Visits: 1
Same piece of code:

public partial class Form1 : Form
{
public void ConfigureChart(DataView data, bool primary)
{
NChartControl chartControl = nChartControl1;
chartControl.DataBindingManager.RemoveAllBindings();
NChart chart = chartControl.Charts[0];
chart.Axis(StandardAxis.SecondaryY).Visible = true;
NBarSeries series = (NBarSeries)chart.Series.Add(SeriesType.Bar);
series.MultiBarMode = MultiBarMode.Clustered; //!!
series.DisplayOnAxis(StandardAxis.PrimaryY, primary);
series.DisplayOnAxis(StandardAxis.SecondaryY, !primary);
series.UseXValues = true;
series.DataLabelStyle.Visible = false;
chartControl.DataBindingManager.RemoveAllBindings();

NDateTimeScaleConfigurator xsc = new NDateTimeScaleConfigurator();
xsc.ViewRangeInflateMode = ScaleViewRangeInflateMode.Absolute;
xsc.AbsoluteInflate = new NRange1DL(10, 10);
//xsc.AbsoluteInflate = new NRange1DL(0, 10);
chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator = xsc;

NOrdinalScaleConfigurator ysc = new NOrdinalScaleConfigurator();
chart.Axis(StandardAxis.PrimaryY).ScaleConfigurator = ysc;

NLinearScaleConfigurator yprimesc = new NLinearScaleConfigurator();
chart.Axis(StandardAxis.SecondaryY).ScaleConfigurator = yprimesc;

int index = chart.Series.IndexOf(series);
chartControl.DataBindingManager.AddBinding(0, index, "XValues", data, "x");
chartControl.DataBindingManager.AddBinding(0, index, "Values", data, "y");

chartControl.Refresh();
}


public Form1()
{
InitializeComponent();

DataTable t = new DataTable();
t.Columns.Add("x", typeof(DateTime));
t.Columns.Add("y", typeof(double));

t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 0);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 10);
t.Rows.Add(new DateTime(2000, 10, 10, 1, 1, 1), 20);
ConfigureChart(t.DefaultView, true);
ConfigureChart(t.DefaultView, false);
}
}


Mike Arkhipov

Blagovest Milanov
Blagovest Milanov
Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)Supreme Being (148 reputation)
Group: Forum Members
Posts: 154, Visits: 15

Hi Mike,

You have to pass different x values - in this case the length of the axis is simply zero. You can workaround the problem by assigning a fixed view range in the case where all x values are equal - for example:

chart.Axis(StandardAxis.PrimaryX).View = new NRangeAxisView(new NRange1DD(
new DateTime(2000, 10, 9, 1, 1, 1).ToOADate(),
new DateTime(2000, 10, 11, 1, 1, 1).ToOADate()));

We'll publish a SP fixing this in the next couple of days. Let me know if you meet any problems.

Best regards,
Bob





GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search