xref: /haiku/src/apps/debuganalyzer/gui/chart/NanotimeChartAxisLegendSource.cpp (revision 8a6724a0ee3803f1e9f487d8111bb3f6cb8d16db)
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 
16 int32
17 NanotimeChartAxisLegendSource::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