ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  24:00 hour on chart
Posted by ND on Jun-18-2015 21:11
Hi,
  We are using c++ and c# to generate charts, and some charts have to have times up to 24:00 hours.

A length of data for a day is marked  as follows:


00:01 to 24:00 hours, on one date . There is no 00:00 hours. At the moment the chart represents 24:00 as 00:00 on the next day, how can we mark it as 24:00 on the same day ?

Best Regards
Neil

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-19-2015 00:21
Hi ND,

For your case, for the coordinates, you may use numbers representing the elapsed seconds
as the coordinates. So 00:00:00 to 24:00:00 would be 0 to 86400 (there is 86400 seconds
in 24 hours).

For the axis label formatting, you may use (in C#):

c.yAxis().setDateScale3("{=({value}-{value}%3600)/3600}:{value|nn:ss}");

The "{=({value}-{value}%3600)/3600}" computes the hour part, which can be 0 to 24.
The second part {value|nn:ss} shows the minute and second.

Hope this can help.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jun-19-2015 04:45
Hi Peter
  Thanks for the reply. Is this the same command in c++?

i fill fill the array with time stamp, which gets passed to the chart using the command:
Chart::chartTime(....),  is this the same, if not do you have an example how I would do this
in c++, for example date 20150615 and time 2400?

Many thanks
Neil

  Re: 24:00 hour on chart
Posted by Neil on Jun-19-2015 05:26
Hi Peter
  Following on from my last message, I wish to display the date along with the time, in C++

Regards
Neil

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-20-2015 04:17
Hi Neil,

There are many methods. If the time range is in the same date (eg. from 01:00 to 24:00
on the same date), then the date can be considered as constant text (just like the
format US$100, in which the "US$" are just constant text prepended to the value). In
this case, you can use 0 to 86400 as the x-coordinate, and just prepend the date as
text in the format string.

If you would like to use chartTime, or if the time range can span two dates (like from
17:00 of one day to 04:00 of the next day), you can add a mark at 00:00 to apply a
special format. For example:

if (.... date contain 00:00 ....) {
   // The specific date
   double t = Chart::chartTime(2015, 6, 12, 0, 0, 0);
   // Assume true date/time axis
   c->xAxis()->addMark(t, -1,
        // Use the mm/dd/yyyy of the previous date and hard coded the time to 24:00
c->formatValue(t - 60, "{value|mm/dd/yy 24:00}"))
          ->setMarkColor(Chart::Transparent, 0x000000, 0x000000);
}

Note that the above assumes the x-axis is a true date/time axis (the x-coordinates are
supplied to the layer using Layer.setXData, and the x-axis format is configured using
setDateScale. If the x-axis is a label based axis (configured using Axis.setLabels), instead
of using addMark(t, .....), the first argument should be the array index of the label.

Hope this can help.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jun-20-2015 16:15
Hi Peter
   I use the command LineLayer->setXData(DoubleArray(timeStamps + startIndex,
dataRange)); to set the date /time. Where timestamps holds Chart::chartTime(..).  So
would I use the formatValue command after the setXData()command?

Also why do you have t-60 in your command?

Many thanks
Neil

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-22-2015 18:29
Hi Neil,

In the example, the time is:

double t = Chart::chartTime(2015, 6, 12, 0, 0, 0);

As list above, the date is 2015-06-12. However. we want to show the date of the previous
day (2015-06-11), so we show the date for t - 60, which must be 2015-06-11 23:59:50,
and so the yyyy-mm-dd must be 2015-06-11. For the hour and minute part, because for
the time we are interested, we know it must be 24:00, so there is no need to ask
ChartDirector to format it. We can just hard coded it as 24:00.

If you are using setXData, you can put the code in my last message either before or after
the setXData. It does not matter.

Hope this can help.

Regards
PeteR Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jun-24-2015 21:35
Attachments:
Hi Peter,
   I cannot get this to work, below is my code, and the attachment is what I am getting.
  When adding to the timestamp, the date time range added is from 24th June 00:01 to 24th June 24:00, so the date includes the correct hours and date.

Regards
Neil

  variables:
   data[] = double and filled with values
   timeStamps = double filled with date/time with the following :
             timeStamps[..] = Chart::chartTime(Year, Month, Day,Hour,Min,0);

   times[] = unsigned char holding the hour value against each timeStamps[.] value.
   startindex, dataRange = position within data range to display, scrolling effect.

  XYChart *c = new XYChart(Width, Height, 0xeeeeee, 0x0, 1);
    c->setPlotArea(50, 49, Width-80, Height-90, 0xffffff)->setGridColor(0xcccccc, 0xcccccc);

LineLayer *layer = c->addLineLayer();
layer->addDataSet(DoubleArray(data[0] + startIndex, dataRange),(int) Colour,Heading[loop]);

layer[0]->setXData(DoubleArray(timeStamps + startIndex, dataRange));

//not sure about this?
// c->xAxis()->setDateScale("{=({value}-{value}%3600)/3600}:{value|nn:ss}");

c->xAxis()->setLabelFormat("{value|hh:nn\\nyy/mm/dd}");

       for(int st=startIndex;st<startIndex+dataRange;st++)
        if(times[st]==24)
         c->xAxis()->addMark(timeStamps[st], -1,c->formatValue(timeStamps[st],            "{value|24:00}"));
image.png

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-24-2015 23:18
Hi Neil,

The mark your code adds is transparent. It would need to call setMarkColors too:

c->xAxis()->addMark(timeStamps[st], -1,c->formatValue(timeStamps[st], "
{value|24:00}"))->setMarkColor(Chart::Transparent, 0x000000, 0x000000);

Note that if the mark text is long and overlaps with the previous or the next label, it can
cause those labels to be hidden to avoid the overlapping. However, in the above code, the
mark text seems to be quite short and there should not be any overlapping of labels.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jun-24-2015 23:31
Attachments:
Hi Peter,
  Thanks for the reply, I am now getting the result in the attached file.

The line  I have is now :
c->xAxis()->addMark(timeStamps[st], -1,c->formatValue(timeStamps[st], "{value|24:00}"))->setMarkColor(Chart::Transparent, 0x000000, 0x000000);

Regards
Neil
image.png

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-25-2015 00:49
Hi Neil,

Sorry for this issue. I think the format string is incorrect. In my earlier message, I suggest
to use the format "{value|mm/dd/yy 24:00}". It should be "{value|mm/dd/yy} 24:00". In
other words, the 24:00 is not a method to format the {value}, but is just some hard coded
text. For your case, as "24:00" is displayed regardless of what is the value, so you can just
use:

c->xAxis()->addMark(timeStamps[st], -1, "24:00")->setMarkColor(Chart::Transparent,
0x000000, 0x000000);

Hope this can help.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jun-25-2015 01:36
Hi Peter
  That worked great, thanks for your help. One thing I use clickable image by using the
setImageMap command. Even though the axis shows 24:00 on the previous day, when
hovering over it you get the same day as the bottom, but 23:59.

Regards
Neil

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-25-2015 01:57
Hi Neil,

Since your code has the "times" array which contains the hours you want to display, you
can pass it to ChartDirector and ask it to use "times" in the tooltips. It is like:

//add an extra field
layer->addExtraField(DoubleArray(times + startIndex, dataRange));

For the tooltips, you can use:

"title='{x|mm/dd/yyyy} {field0}:{x|nn} => {value}'"

The field0 above refers to your times array. The x refers to the x-coordinates
(timeStamps). So the mm/dd/yyyy and the minutes nn are taken from the x-coordinates,
but the hour is take from the times array.

If you see 23:59, is it possible the original timeStamps are not exact. For example, it
could refer to a time like 23:59:59.9999. In normal time formatting, even 23:59:59.9999
will be considered as before midnight, and therefore is 23:59, not 00:00 or 24:00. May be
you can try the followings before passing timeStamps to ChartDirector to see if it can
help:

// Make sure timeStamps are rounded to an exact integer
for (int i = 0; i < dataRange; ++i)
   timeStamps[i + startIndex] = (int)(timeStamps[i + startIndex] + 0.5);

Another method is to simply add a small number to the value before formatting.

"title='{={x}-60|mm/dd/yyyy} {field0}:{={x}+30|nn} => {value}'"

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by neil on Jun-25-2015 02:43
Hi Peter
Thanks for the reply. You mentioned :

"For the tooltips, you can use:

"title='{x|mm/dd/yyyy} {field0}:{x|nn} => {value}'"
"

What command do I put this in? Can you give me an example?

Regards
Neil

  Re: 24:00 hour on chart
Posted by Neil on Jun-25-2015 02:07
Hi Peter
  That worked great, thanks for your help. One thing I use clickable image by using the
setImageMap command. Even though the axis shows 24:00 on the previous day, when
hovering over it you get the same day as the bottom, but 23:59.

Regards
Neil

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-26-2015 01:33
Hi Neil,

You mentioned you are using setImageMap to configure the tooltip, so I suppose you have
a line like:

const char *imageMap = c->getHTMLImageMap("clickable", "",
        "title='Backlog of {dataSetName} at {x|mm/dd/yyyy}: US$ {value}M'");

viewer->setImageMap(imageMap);

The "title='xxxxx'" text string above is the code that configures the tooltip which appears
when the mouse hovers over a data point. If you are referring to this text, you can modified
the text string to change the format. An example is:

"title='{={x}-60|mm/dd/yyyy} {field0}:{={x}+30|nn} => {value}'"

Hope this can help.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jun-26-2015 16:14
Attachments:
Hi Peter ,
    Thanks for the reply. When I add the line:

   m_ChartViewer[0]->setImageMap(c->getHTMLImageMap("clickable", "","title='{={x}-60|dd/mm/yyyy} {field0}:{={x}+30|nn} => {value}'"));

I get the attached snapshot.

Regards
Neil
image.png

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-26-2015 22:57
Hi Neil,

Have you also added your times array as an extra field to your layer, like:

layer->addExtraField(DoubleArray(times + startIndex, dataRange));

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jun-28-2015 17:59
Hi Neil,

After reading your image again, I did see that the minute part is 59. Is it possible to modify
the tooltip to "title='{x|dd/mm/yyyy hh:nn:ss.fff}'" so that we can see the exact
timestamps of your data points?

Note that the label on the x-axis may not be the same as the data points coordinates. For
example, if your y data values are 17, 45, 72, 68, the y-axis labels may show 0, 20, 40, 60,
80. You can see none of the y-axis labels are exactly equal to the y values of your data
points. It is also possible the x-axis labels are not equal to your x-coordinates of your data
points. The tooltip above can help us to determine the exact value of your data point x-
coordinates, so we can determine whether it is really at 59 minutes.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jun-29-2015 15:23
Hi Peter
  Thanks for the info, I will try this today. I know the data is every 15 minutes, so there
won't be any 59minutes. I was also thinking of the rounding issue where you mentioned
24:00 could be 23:59.59. If this was the case surely we would also see it at 12:00, 13:00
etc

Regards
Neil

  Re: 24:00 hour on chart
Posted by Neil on Jul-03-2015 22:08
Attachments:
Hi Peter
   I store the date time in the timeStamp array, and store the hours in another array called hours[], this way I can see when its 2400 with the below code.

timeStamps[Position] = Chart::chartTime(Year, Month,Day,Hour,Min,0);
hours[Position++]=Hour;

I noticed I had the following code:
//to deal with 24hrs
if(Hour==24)
  timeStamps[Position-1] -=60;

So I removed the above 2 lines and now get the following attachment:

I have below to display the date/time axis..

for(int st=startIndex;st<startIndex+dataRange;st++)
if(hours[st]==24)
    c->xAxis()->addMark(timeStamps[st]-60, -1,c->formatValue(timeStamps[st]-60, "24:00\\n{value|dd/mm/yy}"))->setMarkColor(Chart::Transparent, 0x000000, 0x000000);

I know hours 24 is going to the timeStamps[] as I check the hours array. Could it be that the chart time converts it to 00:00 next day?

Regards
Neil
image.png

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jul-03-2015 23:17
Hi Neil,

Using 24:00 as input is exactly the same as 00:00 on the next day. It is
indistinguishable. This is the normal and expected behaviour. For example, the standard
C API mktime behaves in exactly the same way.

The "hh" format means to output the hours as 0 to 23, while the "hh a" format means
to output the hours as 1 to 12 and with am or pm. You can see that the output format
is not related to the input format.

In your message, you have not mentioned about how your tooltip is configured. The
code you use is only for the mark label. The mark label seems to be correct in your
chart.

As you have the hours array, for the tooltip label, I suggest you pass the hours array to
ChartDirector and specify that the tooltip should use the hours array.

In your earlier message, you mentioned your code is:

LineLayer *layer = c->addLineLayer();
layer->addDataSet(DoubleArray(data[0] + startIndex, dataRange),(int)
Colour,Heading[loop]);

layer[0]->setXData(DoubleArray(timeStamps + startIndex, dataRange));

There seems to be some error in the above code, as sometimes it uses "layer->", and
sometimes "layer[0]->". I assume the "layer->" is the correct variable. To pass the
hours array to ChartDirector, please add:

layer->addExtraField(DoubleArray(hours + startIndex, dataRange));

Then for the tooltip configuration, please use:

"title='{={x}-60|mm/dd/yyyy} {field0}:{x|nn} => {value}'"

Hope this can help.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jul-04-2015 00:28
Hi Peter,
  Thanks for the reply.

The chart I have may have up to 20 layers, below is the code(part of it) I have, but for some reason cant get the tooltip to work correctly:

Regards
Neil


    XYChart *c = new XYChart(Width, Height, 0xeeeeee, 0x0, 1);
    c->setPlotArea(50, 49, Width-80, Height-90, 0xffffff)->setGridColor(0xcccccc, 0xcccccc);
LegendBox *b = c->addLegend(50, 15, false, "", 8);
b->setWidth(Width-80);
b->setHeight(30);
b->setBackground(Chart::Transparent);
c->xAxis()->setTickDensity(55);
c->yAxis()->setMargin(0,2);


LineLayer *layer[20];
       double *data[20];
//fill in data for each layer into data[x]
for(int loop=0;loop<20;loop++)
{
if(m_Enable[loop])  //simply check if we are using layer
{
layer[loop] = c->addLineLayer();
layer[loop]->setLineWidth(1);

int Colour=COLORREF2RGB(Selected_Colour[ColorIndex]);
         ColorIndex++;

layer[loop]->addDataSet(DoubleArray(data[loop] + startIndex, dataRange),(int) Colour,Heading[loop]);

        layer[loop]->setXData(DoubleArray(timeStamps + startIndex, dataRange));
               layer[loop]->addExtraField(DoubleArray((double *)times + startIndex, dataRange));
               }
}

// to deal with 24 hours
for(int st=startIndex;st<startIndex+dataRange;st++)
if(times[st]==24)
    c->xAxis()->addMark(timeStamps[st]-60, -1,c->formatValue(timeStamps[st]-60, "24:00\\n{value|dd/mm/yy}"))->setMarkColor(Chart::Transparent, 0x000000, 0x000000);

m_ChartViewer->setChart(c);
     m_ChartViewer->setImageMap(c->getHTMLImageMap("clickable", "","title='{={x}-60|mm/dd/yyyy} {field0}:{x|nn} => {value}"));

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jul-04-2015 01:08
Hi Neil,

Would you mind to clarify what it is necessary to cast the "times" array to "double *"
(using the code "(double *)times")? Is it because times is not an array of double? If this is
the case, casting it to (double*) will not change it to an array of double. It just suppresses
the compiler error message. If this is the cause of the problem, please modify times to a
double array, or you may create another double array, and copy the contents of the times
array to that double array, and use the double array as the extra field.

If the above still cannot solve the problem, would you mind to clarify what tooltip are you
getting?

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jul-04-2015 01:49
Attachments:
Hi Peter,
  Changing it to double helped, I got the following tooltip, but is missing the value on the chart.


Regards
Neil
image.png

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jul-07-2015 01:23
Hi Neil,

Instead of using "=> {value}", please use "= {value}". I forget the ">" is a reserved
character in image maps and cannot be directly used. (If it is necessary to use ">", the
character should be escaped.)

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jul-08-2015 00:21
Attachments:
Hi Peter ,
  I am now getting the following. Its not just on 2400, its on any point.


Regards
Neil
image.png

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jul-08-2015 01:20
Hi Neil,

The code is missing a close single quote. Please modify the code to:

"title='{={x}-60|mm/dd/yyyy} {field0}:{x|nn} = {value}"'

Hope this can help.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Jul-08-2015 02:03
Hi Peter,
  That worked, thanks.  Only thing left is I have a callback as follows:
If I click on 2400 on 4/19/2015, the below shows  4/20/2015 0000.

void CChartView::OnChartClick()
{
    ImageMapHandler *handler = m_ChartViewer[0]->getImageMapHandler();
    if (0 != handler)
    {
const char *key;
if(0 != (key = handler->getKey(0)))
{
double myDate = atof(handler->getValue("x"));
int Date=Chart::getChartYMD(myDate);

               int startHMS=(int)fmod(myDate,86400);
CTime startDate = CTime(Date/ 10000, (Date% 10000) / 100, Date% 100,
startHMS / 3600, (startHMS % 3600) / 60, startHMS % 60);

int Time=startDate.GetHour()*100+startDate.GetMinute();

}
}
}

Regards
Neil

  Re: 24:00 hour on chart
Posted by Peter Kwan on Jul-08-2015 06:32
Hi Neil,

In your attached code, I did not see how your code shows the date/time.

ChartDirector only tells your code what is the date/time. Your code can display it in any
format you like. For example, your code can certainly display it as 4/19/2015 24:00 (or as
Apr 19. 2015 24:00 or 平成18年4月19日 24:00 ....). ChartDirector cannot affect how your
code shows the date/time.

Hope this can help.

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Oct-15-2015 18:57
Attachments:
Hi Peter
  I have a viewport where I display a portion of the chart, and works fine. But if I expand the viewport so there is a lot of data on the graph. The labels overlap each other and unreadable. I added the code to display 2400:

//the startIndex is the position where to start displaying the chart.
//the times[] only holds the hour value at each point. If there is 24, then I add the 2400 tick.
for(int st=startIndex;st<startIndex+noOfPoints;st++)
if(times[st]==24)
    c->xAxis()->addMark(viewPortTimeStamps[st-startIndex]-60, -1,c->formatValue(viewPortTimeStamps[st-startIndex]-60, "24:00\\n{value|dd/mm/yy}"))->setMarkColor(Chart::Transparent, 0x000000, 0x000000);

You can see in the attached where I left out the above, and you can see the time is 00:00 , and spacing is fine. If I add the above line you can see it is unreadable.

Regards
Neil
chart.JPG

  Re: 24:00 hour on chart
Posted by Peter Kwan on Oct-16-2015 02:53
Hi Neil,

Just from your attached chart images, I think the labels on the top chart are
automatically generated by ChartDirector, and not by your code. In this case, the labels
are not from your data values, but are determined based on your data range.

For example, in the original "Simple Bar Chart" sample code, the data values for the bars
are {85, 156, 179.5, 211, 123}, while the y-axis labels are {0, 50, 100, 150, 200, 250}.
You can see none of the labels come from the data values. However, the labels are
appropriate for the data range. The number of labels also are not related to the number
of data points.

The same mechanism can apply to the x-axis as well. Using this mechanism, ChartDirector
will place suitable number of labels on the x-axis to fit your data range. The labels may
not equal to any of your data points, and the number of labels may not be the same as
the number of data points.

In the second case, it seems the labels are generated by your code based on your data
points. The code generates too many labels in your case.

If you prefer the labels generated by ChartDirector, you can add marks at the label
positions generated by ChartDirector, instead of based on your data. May be you can try
something like:


.... create chart as usual .....

// Ask ChartDirector to auto-scale the axis and generate the labels
c->layoutAxes();

// Ask ChartDirector for the label positions
DoubleArray ticks = c->xAxis()->getTicks();

// Add marks at the tick values generated by ChartDirector if the time of day is 00:00:00
for (int i = 0; i < ticks.len; ++i) {
   if (fmod(ticks.data[i], 86400) == 0)
       c->xAxis()->addMark(ticks.data[i], -1, c->formatValue(ticks.data[i]-60,
"24:00\\n{value|dd/mm/yy}"))->setMarkColor(Chart::Transparent, 0x000000, 0x000000);
}

Regards
Peter Kwan

  Re: 24:00 hour on chart
Posted by Neil on Oct-19-2015 00:39
Hi Peter
   This worked perfect, thanks for all your help


Neil