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#include "util/TimeUtils.h"
13
14
15int32
16BigtimeChartAxisLegendSource::GetAxisLegends(const ChartDataRange& range,
17	ChartLegend** legends, double* values, int32 maxLegends)
18{
19	// interpret range as time range
20	bigtime_t startTime = (bigtime_t)range.min;
21	bigtime_t endTime = (bigtime_t)range.max;
22// TODO: Handle sub-microsecs ranges!
23	if (startTime >= endTime)
24		return 0;
25
26	bigtime_t positionFactors[4];
27	positionFactors[3] = 1;
28	positionFactors[2] = 1000000;
29	positionFactors[1] = positionFactors[2] * 60;
30	positionFactors[0] = positionFactors[1] * 60;
31
32	// find the main position (h, m, s, us) we want to play with
33	int32 position = 0;
34	bigtime_t rangeTime = endTime - startTime;
35	while (rangeTime / positionFactors[position] + 1 < maxLegends / 2
36			&& position < 3) {
37		position++;
38	}
39
40	// adjust the factor so that we get maxLegends / 2 to maxLegends legends
41	bigtime_t baseInterval = positionFactors[position];
42	bigtime_t relativeFactor = 1;
43	while (rangeTime / (baseInterval * relativeFactor) >= maxLegends) {
44		if (relativeFactor == 1) {
45			relativeFactor = 2;
46		} else if (relativeFactor == 2) {
47			relativeFactor = 5;
48		} else if (relativeFactor == 5) {
49			baseInterval *= 10;
50			relativeFactor = 1;
51		}
52	}
53
54	// generate the legends
55	int32 count = 0;
56	bigtime_t interval = baseInterval * relativeFactor;
57	bigtime_t time = (startTime + interval - 1) / interval * interval;
58	for (; time <= endTime; time += interval) {
59		decomposed_bigtime decomposed;
60		decompose_time(time, decomposed);
61		char buffer[128];
62		snprintf(buffer, sizeof(buffer), "%02" B_PRIu64 ":%02d:%02d.%06d",
63			decomposed.hours, decomposed.minutes, decomposed.seconds,
64			decomposed.micros);
65// TODO: Drop superfluous micro seconds digits, or even microseconds and seconds
66// completely.
67
68		StringChartLegend* legend
69			= new(std::nothrow) StringChartLegend(buffer, 1);
70		if (legend == NULL)
71			return count;
72
73		legends[count] = legend;
74		values[count++] = (double)time;
75	}
76
77	return count;
78}
79