1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "chart/NanotimeChartAxisLegendSource.h"
8
9#include <stdio.h>
10
11#include "chart/ChartDataRange.h"
12#include "chart/StringChartLegend.h"
13#include "util/TimeUtils.h"
14
15
16int32
17NanotimeChartAxisLegendSource::GetAxisLegends(const ChartDataRange& range,
18	ChartLegend** legends, double* values, int32 maxLegends)
19{
20	// interpret range as time range
21	nanotime_t startTime = (nanotime_t)range.min;
22	nanotime_t endTime = (nanotime_t)range.max;
23// TODO: Handle sub-nanosecs ranges!
24	if (startTime >= endTime)
25		return 0;
26
27	nanotime_t positionFactors[4];
28	positionFactors[3] = 1;
29	positionFactors[2] = 1000000000;
30	positionFactors[1] = positionFactors[2] * 60;
31	positionFactors[0] = positionFactors[1] * 60;
32
33	// find the main position (h, m, s, us) we want to play with
34	int32 position = 0;
35	nanotime_t rangeTime = endTime - startTime;
36	while (rangeTime / positionFactors[position] + 1 < maxLegends / 2
37			&& position < 3) {
38		position++;
39	}
40
41	// adjust the factor so that we get maxLegends / 2 to maxLegends legends
42	nanotime_t baseInterval = positionFactors[position];
43	nanotime_t relativeFactor = 1;
44	while (rangeTime / (baseInterval * relativeFactor) >= maxLegends) {
45		if (relativeFactor == 1) {
46			relativeFactor = 2;
47		} else if (relativeFactor == 2) {
48			relativeFactor = 5;
49		} else if (relativeFactor == 5) {
50			baseInterval *= 10;
51			relativeFactor = 1;
52		}
53	}
54
55	// generate the legends
56	int32 count = 0;
57	nanotime_t interval = baseInterval * relativeFactor;
58	nanotime_t time = (startTime + interval - 1) / interval * interval;
59	for (; time <= endTime; time += interval) {
60		decomposed_nanotime decomposed;
61		decompose_time(time, decomposed);
62		char buffer[128];
63		snprintf(buffer, sizeof(buffer), "%02" B_PRId64 ":%02d:%02d.%09d",
64			decomposed.hours, decomposed.minutes, decomposed.seconds,
65			decomposed.nanos);
66// TODO: Drop superfluous nanoseconds digits, or even nanoseconds and seconds
67// completely.
68
69		StringChartLegend* legend
70			= new(std::nothrow) StringChartLegend(buffer, 1);
71		if (legend == NULL)
72			return count;
73
74		legends[count] = legend;
75		values[count++] = (double)time;
76	}
77
78	return count;
79}
80