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