0

I'm using System.Windows.Forms.DataVisualization.Charting in my app and I want to add different label types on my X axis which is representing a timeline. For example, I want to use "HH:mm" format for labels but when it's 00:00 I'd like to show "dd.MM" format instead. I tried to add cutom labels but it has no effect at all.

var area = new ChartArea();
area.AxisX.LabelStyle.Format = "HH:mm";
area.AxisX.Interval = 1 / 24.0;
area.AxisX.CustomLabels.Add(1.0, DateTimeIntervalType.Days, "dd.MM");
SHKVal
  • 3
  • 5

1 Answers1

1

Adding CustomLabels will help; however if you want them to show an individual format you will have to add them individually to each DataPoint!

Doing so is not quite as simple as one could wish for; there are several overloads but none is really easy to use. The simplest way, imo, is to use one with a FromPosition and a ToPosition; these should then to be set in a way that they hit right between the DataPoints; this way they will be centered nicely..

Note that as the X-Values are really DateTimes, but as always in a chart, converted to doubles we need to convert them back to DateTime for correct formatting and also use their values to calculate the middle or rather half an interval..

Here is an example:

enter image description here

// prepare the test chart..
chart1.ChartAreas.Clear();
ChartArea CA = chart1.ChartAreas.Add("CA1");
Random R = new Random(123);
chart1.Series.Clear();
CA.AxisX.MajorTickMark.Interval = 1;
Series S = chart1.Series.Add("S1");
S.Points.Clear();
S.ChartType = SeriesChartType.Column;
S.SetCustomProperty("PixelPointWidth", "10");
// some random data:
DateTime dt0 = new DateTime(2015, 05, 01);
for (int i = 0; i< 40; i++)
{
    int p = S.Points.AddXY(dt0.AddHours(i), R.Next(100));
}


// each custom label will be placed centered in a range
// so we need an amount of half an interval..
// this assumes equal spacing..
double ih = (S.Points[0].XValue - S.Points[1].XValue) / 2d;

// now we add a custom label to each data point
for (int i = 0; i < S.Points.Count; i++)
{
    DataPoint pt = S.Points[i];
    string s = (DateTime.FromOADate(pt.XValue)).ToString("HH:mm");
    bool midnite = s == "00:00";

    if (midnite) s = DateTime.FromOADate(pt.XValue).ToString("dd.MM.yyyy");
    CustomLabel CL = CA.AxisX.CustomLabels.Add(pt.XValue - ih, pt.XValue + ih, s);
    CL.ForeColor = midnite ? Color.Blue : Color.Black;
}
TaW
  • 53,122
  • 8
  • 69
  • 111
  • Thanks for the answer very much. But what if there is no data points at 00:00? I create ChartArea and Series in different functions and don't know my data points beforehand. So I need my labels to be shown despite incoming data. Is there a way to make this? – SHKVal Sep 08 '15 at 05:49
  • Well, you asked for code that sets a date label at midnight, didn't you? - You can both: modify it for some other or more relaxed condition and also to work right while the data come in. But since I don't see how they come in (added to the points collection? or data-bound? etc..) I can't advide how to do that best.. – TaW Sep 08 '15 at 15:37
  • Yes, due to my first post I'm marking this as answer anyway.) But in your example you work with existing data points and I wanted to ask can I add my labels when there are no data points. I have a function `public Chart MakeChart(...)` that calls `private ChartArea MakeChartArea(...)` and `private Series MakeSeries(...)`. All data points are counted in `MakeSeries` functions and chart area is prepared in `MakeChartArea` where I'm trying to set my labels and where are no data points. For `MakeSeries` time interval is unknwown value. – SHKVal Sep 09 '15 at 04:16
  • Well you can add them without any DataPoints being there yet, but only if you __know the range__ of `X-Values` they are supposed to label. But if you want or need to you can always __change__ the `FromPosition` and `ToPositions` of each `AxisX.CustomLabels` element __later__.. - The `CustomLabels` will show as soon as you have added at least one `DataPoint` that fall in the range of one of the Labels – TaW Sep 09 '15 at 07:27