Jump to content
Software FX Community

AxisX - problems when working with datetimes in very high resolution


AlexeyRedko

Recommended Posts

Hello !

In our application we usually work with very large scale of datetimes from moths to microseconds.

So when I set my data as array of points with very high reslution (for example 30 points this in  of 50 microseconds between two adjacent points) I guess I'll see 30 points but acctually I see only 2.(the code examle is below).It looks like bug or I misunderstand how to work with datetime axis.

There is another point:

I see in debuger that the datetimes are actually converted into doubles in Chart.Actually it looks like that the ticks of datetime are converted into double .It works fine with low resolution like hours,minutes ,seconds but when we go into higher resolutions it becomes a little problematic (long can't be converted into double without loosing some data,so in very high resolution the datetimes will drawn be incorrect)

 

XAML:

<

Window x:Class="CustomSteps.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="MainWindow" Height="350" Width="525" xmlns:cfx="http://schemas.softwarefx.com/chartfx/wpf/80">

<Grid>

<cfx:Chart Name="chart" /></Grid>

</

Window>

 

Code behind:

amespace CustomSteps

{

/// <summary>

/// Interaction logic for MainWindow.xaml

/// </summary>

public partial class MainWindow : Window

{

public MainWindow()

{

InitializeComponent();

ReloadData();

}

public struct MyPoint

{

public double X

{

get;set;

}

public double Y

{

get;set;

}

public DateTime Time

{

get;set;

}

}

private void ReloadData()

{

MyPoint[] data1 = new MyPoint[30];

MyPoint[] data2 = new MyPoint[30];MyPoint[] data3 = new MyPoint[30];

FillData(data1, 1);

FillData(data2, 1);

FillData(data3, 1);

SeriesAttributes sa1 = new SeriesAttributes();

sa1.ItemsSource = data1;

chart.Series.Add(sa1);

Pane pane = new Pane();Axis ax1 = new Axis();

ax1.Min = 0;

ax1.Max = 10;

this.chart.Panes.Add(pane);

pane.Series.Add(sa1);

sa1.AxisY = ax1;

sa1.AxisX = chart.AxisX;

sa1.BindingPathX = "X";sa1.BindingPath = "Y";

pane.AxesY.Add(ax1);

 

chart.PanesPanel =

new StackPanePanel();

 

chart.AxisX = new Axis();

//chart.AxisX.AutoScale = false;

//chart.AxisX.ForceZero = false;chart.AxisX.DataPath = "Time";

 

chart.AxisX.DataFormat.Format = AxisFormat.Time;chart.AxisX.Labels.Format = AxisFormat.Time;

 

 

chart.AxisX.GetLabel += new AxisLabelEventHandler(AxisX_GetLabel);

 

 

}

void AxisX_GetLabel(object sender, AxisLabelEventArgs e)

{

Trace.TraceInformation("{0}",e.Text);

}

private void FillData(MyPoint[] data1, double factor)

{

DateTime time = new DateTime(2011,1,1,0,0,0,DateTimeKind.Local);for (int i = 0; i < data1.Length; i++)

{

time = time.AddTicks(500);

data1.Y = i;

data1.Time = time;

}

}

}

}

Link to comment
Share on other sites

Internally chartfx handles doubles as the values for both X and Y so we do convert datetime/timespan to doubles, additionally because of loss of precision when these numbers become too big we are only accurate to around a millisecond.

The only way to work around this would be for you to convert your datetimes to doubles differently, e.g. you could use the difference in ticks between your dates and the first date (this would make sure your numbers don't start losing precision when they become too big). Then you would have to handle how the axis labels are painted.



private void ReloadData()
{
  MyPoint[]
data1 = new MyPoint[30];
  FillData(data1, 1);
  SeriesAttributes
series = new SeriesAttributes();
  series.BindingPath = "Y";
  series.BindingPathX = "XTime";
  chart1.Series.Add(series);
  chart1.ItemsSource = data1;
  chart1.AxisX.GetLabel += new AxisLabelEventHandler(OnAxisGetLabel);
}



private void OnAxisGetLabel(object
sender, AxisLabelEventArgs e)
{
  double d =
e.Value;
  TimeSpan
ts = new TimeSpan((long) d);
  double
milliSeconds = ts.TotalMilliseconds;
  e.Text = (milliSeconds / 1000).ToString("#.####");
}



private void FillData(MyPoint[]
data1, double factor)
{
  DateTime
time = new DateTime(2011,1,1,0,0,0,DateTimeKind.Local);
  DateTime
firstTime = time;

  for (int i = 0; i < data1.Length; i++) {

  time = time.AddTicks(500);

  data1.Y = i;

  data1.Time = time;

  data1.FirstTime = firstTime;

  }

}



Hope this helps, obviously this is an oversimplification of your sample code.

JuanC

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...