xref: /haiku/src/apps/debuganalyzer/gui/chart/BigtimeChartAxisLegendSource.cpp (revision 893988af824e65e49e55f517b157db8386e8002b)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "chart/BigtimeChartAxisLegendSource.h"
7 
8 #include <stdio.h>
9 
10 #include "chart/ChartDataRange.h"
11 #include "chart/StringChartLegend.h"
12 
13 
14 struct decomposed_time {
15 	bigtime_t	hours;
16 	int			minutes;
17 	int			seconds;
18 	int			micros;
19 };
20 
21 
22 static void
23 decompose_time(bigtime_t time, decomposed_time& decomposed)
24 {
25 	// microsecs
26 	decomposed.micros = time % 1000000;
27 	time /= 1000000;
28 	// secs
29 	decomposed.seconds = time % 60;
30 	time /= 60;
31 	// mins
32 	decomposed.minutes = time % 60;
33 	time /= 60;
34 	// hours
35 	decomposed.hours = time;
36 }
37 
38 
39 int32
40 BigtimeChartAxisLegendSource::GetAxisLegends(const ChartDataRange& range,
41 	ChartLegend** legends, double* values, int32 maxLegends)
42 {
43 	// interpret range as time range
44 	bigtime_t startTime = (bigtime_t)range.min;
45 	bigtime_t endTime = (bigtime_t)range.max;
46 // TODO: Handle sub-microsecs ranges!
47 	if (startTime >= endTime)
48 		return 0;
49 
50 	bigtime_t positionFactors[4];
51 	positionFactors[3] = 1;
52 	positionFactors[2] = 1000000;
53 	positionFactors[1] = positionFactors[2] * 60;
54 	positionFactors[0] = positionFactors[1] * 60;
55 
56 	// find the main position (h, m, s, us) we want to play with
57 	int32 position = 0;
58 	bigtime_t rangeTime = endTime - startTime;
59 	while (rangeTime / positionFactors[position] + 1 < maxLegends / 2
60 			&& position < 3) {
61 		position++;
62 	}
63 
64 	// adjust the factor so that we get maxLegends / 2 to maxLegends legends
65 	bigtime_t baseInterval = positionFactors[position];
66 	bigtime_t relativeFactor = 1;
67 	while (rangeTime / (baseInterval * relativeFactor) >= maxLegends) {
68 		if (relativeFactor == 1) {
69 			relativeFactor = 2;
70 		} else if (relativeFactor == 2) {
71 			relativeFactor = 5;
72 		} else if (relativeFactor == 5) {
73 			baseInterval *= 10;
74 			relativeFactor = 1;
75 		}
76 	}
77 
78 	// generate the legends
79 	int32 count = 0;
80 	bigtime_t interval = baseInterval * relativeFactor;
81 	bigtime_t time = (startTime + interval - 1) / interval * interval;
82 	for (; time <= endTime; time += interval) {
83 		decomposed_time decomposed;
84 		decompose_time(time, decomposed);
85 		char buffer[128];
86 		snprintf(buffer, sizeof(buffer), "%02lld:%02d:%02d.%06d",
87 			decomposed.hours, decomposed.minutes, decomposed.seconds,
88 			decomposed.micros);
89 // TODO: Drop superfluous micro seconds digits, or even microseconds and seconds
90 // completely.
91 
92 		StringChartLegend* legend
93 			= new(std::nothrow) StringChartLegend(buffer, 1);
94 		if (legend == NULL)
95 			return count;
96 
97 		legends[count] = legend;
98 		values[count++] = (double)time;
99 	}
100 
101 	return count;
102 }
103