title: C# Chart: How to display relative time on x axis
body: <p>I have <code>DataTable</code> with some data (measurements) that I want to display on chart. Each record contains <code>DataTime</code> value - real date-time when measurements were taken and <code>TimeSpan</code> value - relative time of measurement (time passed from the moment when 1st measurement was taken). </p>
  
  <p>I want to be able to switch between two types of x-axis values: absolute and relative.
  It's easy to switch between those values with simple</p>
  
  <pre><code>chart.DataSource = table;        // table with columns: Time, Relative, D1, D2...
  series.XValueMember = "Time";    // absolute - DateTime
  series.XValueMember = "Relative";// relative - at 1st TimeSpan, now double
  </code></pre>
  
  <p>The problem is that DataPoints do not accept <code>TimeSpan</code> as X values. I tried using <code>double</code> (<code>TimeSpan.TotalDays</code>) with label formating</p>
  
  <pre><code>chart.ChartAreas[ 0 ].AxisX.LabelStyle.Format = "dd HH:mm:ss";
  </code></pre>
  
  <p>but the value displayed for values of double below 1 (before reaching 24 hours/1 day) is 30 xx:xx:xx ...</p>
  
  <p>Where that 30 come from? or rather how can i correctly display relative time with WinForms Chart control?</p>
  
  <hr>
  
  <p>edit:
  ok, i know where that 30 came from, it's the OADate:</p>
  
  <pre><code>DateTime dt = DateTime.FromOADate( 0.0 );
  </code></pre>
  
  <p>assigns the value of <code>dt = 1899-12-30 00:00:00</code>, so in chart the double value is converted that way to DateTime (quite obvious converion now that i think about it) and then converted to string with format specified.</p>
  
  <hr>
  
  <p>I have also checked with ILSpy, that this is exactly what happens under the hood: (fragment of System.Windows.Forms.DataVisualization.Charting.Utilities.ValueConverter.FormatValue(...) method)</p>
  
  <pre><code>if (valueType == ChartValueType.DateTime || valueType == ChartValueType.DateTimeOffset || valueType == ChartValueType.Date)
      {
          ...
          text2 = string.Format(CultureInfo.CurrentCulture, text, new object[]
          {
              DateTime.FromOADate(value)
          });
      }
      else
      {
          if (valueType == ChartValueType.Time)
          {
              ...
              text2 = string.Format(CultureInfo.CurrentCulture, text, new object[]
              {
                  DateTime.FromOADate(value)
              });
          }
  </code></pre>
  
  <hr>
  
  <p>Either way, that brings me to my basic question - how to display what i want to display.
  Using DateTime this way or another will always give me positive number of days (something between 1 and 31).</p>
  
  <p>The result can be "days HH:mm:ss" or "total hours:mm:ss", where total hours can grow over 24 and don't get reset to 0 when a full day passes.</p>