An axis legend source regarding the range as ordinary numbers and producing

string legends for them.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30526 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-04-30 22:58:55 +00:00
parent 707b2f9a94
commit 5664cf424e
3 changed files with 116 additions and 0 deletions

View File

@ -0,0 +1,96 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "chart/DefaultChartAxisLegendSource.h"
#include <math.h>
#include <stdio.h>
#include "chart/ChartDataRange.h"
#include "chart/StringChartLegend.h"
int32
DefaultChartAxisLegendSource::GetAxisLegends(const ChartDataRange& range,
ChartLegend** legends, double* values, int32 maxLegends)
{
// TODO: Also support scientific notation! Otherwise the numbers can get really
// long.
double start = range.min;
double end = range.max;
double rangeSpan = end - start;
if (rangeSpan >= maxLegends / 2) {
// We only need to consider the integer part.
// find an interval so that we get maxLegends / 2 to maxLegends legends
double baseInterval = 1;
double relativeFactor = 1;
while (rangeSpan / baseInterval / relativeFactor >= maxLegends) {
if (relativeFactor == 1) {
relativeFactor = 2;
} else if (relativeFactor == 2) {
relativeFactor = 5;
} else if (relativeFactor == 5) {
baseInterval *= 10;
relativeFactor = 1;
}
}
// generate the legends
int32 count = 0;
double interval = baseInterval * relativeFactor;
double value = ceil(start / interval) * interval;
for (; value <= end; value += interval) {
char buffer[128];
snprintf(buffer, sizeof(buffer), "%.0f", value);
StringChartLegend* legend
= new(std::nothrow) StringChartLegend(buffer, 1);
if (legend == NULL)
return count;
legends[count] = legend;
values[count++] = value;
}
return count;
}
// The range is so small that we need a fraction interval.
// First find out how many places after the decimal point we need.
int positions = 0;
double factor = 1;
while (rangeSpan * factor < maxLegends / 2) {
factor *= 10;
positions++;
}
double relativeFactor = 1;
if (rangeSpan * factor / relativeFactor >= maxLegends) {
relativeFactor = 2;
if (rangeSpan * factor / relativeFactor >= maxLegends)
relativeFactor = 5;
}
// generate the legends
int32 count = 0;
double interval = relativeFactor / factor;
double shiftedValue = ceil(start / interval);
for (; shiftedValue * interval <= end; shiftedValue++) {
double value = shiftedValue * interval;
char buffer[128];
snprintf(buffer, sizeof(buffer), "%.*f", positions, value);
StringChartLegend* legend
= new(std::nothrow) StringChartLegend(buffer, 1);
if (legend == NULL)
return count;
legends[count] = legend;
values[count++] = value;
}
return count;
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef DEFAULT_CHART_AXIS_LEGEND_SOURCE_H
#define DEFAULT_CHART_AXIS_LEGEND_SOURCE_H
#include "chart/ChartAxisLegendSource.h"
class DefaultChartAxisLegendSource : public ChartAxisLegendSource {
public:
virtual int32 GetAxisLegends(const ChartDataRange& range,
ChartLegend** legends, double* values,
int32 maxLegends);
};
#endif // DEFAULT_CHART_AXIS_LEGEND_SOURCE_H

View File

@ -14,6 +14,7 @@ MergeObject DebugAnalyzer_gui_chart.o
ChartDataSource.cpp
ChartLegend.cpp
ChartRenderer.cpp
DefaultChartAxisLegendSource.cpp
LegendChartAxis.cpp
LineChartRenderer.cpp
StringChartLegend.cpp