diff --git a/src/apps/debuganalyzer/gui/chart/DefaultChartAxisLegendSource.cpp b/src/apps/debuganalyzer/gui/chart/DefaultChartAxisLegendSource.cpp new file mode 100644 index 0000000000..d7e4e7d612 --- /dev/null +++ b/src/apps/debuganalyzer/gui/chart/DefaultChartAxisLegendSource.cpp @@ -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 +#include + +#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; +} diff --git a/src/apps/debuganalyzer/gui/chart/DefaultChartAxisLegendSource.h b/src/apps/debuganalyzer/gui/chart/DefaultChartAxisLegendSource.h new file mode 100644 index 0000000000..ec655ba4ee --- /dev/null +++ b/src/apps/debuganalyzer/gui/chart/DefaultChartAxisLegendSource.h @@ -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 diff --git a/src/apps/debuganalyzer/gui/chart/Jamfile b/src/apps/debuganalyzer/gui/chart/Jamfile index a2df2deb25..1902f25a90 100644 --- a/src/apps/debuganalyzer/gui/chart/Jamfile +++ b/src/apps/debuganalyzer/gui/chart/Jamfile @@ -14,6 +14,7 @@ MergeObject DebugAnalyzer_gui_chart.o ChartDataSource.cpp ChartLegend.cpp ChartRenderer.cpp + DefaultChartAxisLegendSource.cpp LegendChartAxis.cpp LineChartRenderer.cpp StringChartLegend.cpp