widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #07662
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
GunChleoc has proposed merging lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands.
Commit message:
Fixed relative plot mode and flickering graphs on button click. Only draw active statistics tab. Some refactoring.
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #1566167 in widelands: "Ware statistic: Clicking the first time on an icon the graph flickers"
https://bugs.launchpad.net/widelands/+bug/1566167
Bug #1573057 in widelands: "ware graphs not properly scaled"
https://bugs.launchpad.net/widelands/+bug/1573057
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1573057-graph-relative-plotmode/+merge/295198
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands.
=== modified file 'src/logic/cmd_calculate_statistics.cc'
--- src/logic/cmd_calculate_statistics.cc 2015-10-24 15:42:37 +0000
+++ src/logic/cmd_calculate_statistics.cc 2016-05-19 11:15:41 +0000
@@ -31,7 +31,7 @@
game.sample_statistics();
game.enqueue_command
(new CmdCalculateStatistics
- (game.get_gametime() + STATISTICS_SAMPLE_TIME));
+ (game.get_gametime() + kStatisticsSampleTime));
}
constexpr uint16_t kCurrentPacketVersion = 1;
=== modified file 'src/logic/constants.h'
--- src/logic/constants.h 2015-03-01 09:21:20 +0000
+++ src/logic/constants.h 2016-05-19 11:15:41 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2015 by the Widelands Development Team
+ * Copyright (C) 2006-2016 by the Widelands Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,6 +20,8 @@
#ifndef WL_LOGIC_CONSTANTS_H
#define WL_LOGIC_CONSTANTS_H
+#include <cstdint>
+
/// Maximum numbers of players in a game. The game logic code reserves 5 bits
/// for player numbers, so it can keep track of 32 different player numbers, of
/// which the value 0 means neutral and the values 1 .. 31 can be used as the
@@ -27,6 +29,6 @@
#define MAX_PLAYERS 8
/// How often are statistics to be sampled.
-#define STATISTICS_SAMPLE_TIME 30000
+constexpr uint32_t kStatisticsSampleTime = 30000;
#endif // end of include guard: WL_LOGIC_CONSTANTS_H
=== modified file 'src/wui/general_statistics_menu.cc'
--- src/wui/general_statistics_menu.cc 2016-01-29 08:37:22 +0000
+++ src/wui/general_statistics_menu.cc 2016-05-19 11:15:41 +0000
@@ -67,7 +67,9 @@
440, 400, _("General Statistics")),
my_registry_ (®istry),
box_ (this, 0, 0, UI::Box::Vertical, 0, 0, 5),
- plot_ (&box_, 0, 0, 430, PLOT_HEIGHT),
+ plot_ (&box_, 0, 0, 430, PLOT_HEIGHT,
+ kStatisticsSampleTime,
+ WuiPlotArea::Plotmode::kAbsolute),
selected_information_(0)
{
assert (my_registry_);
@@ -78,8 +80,6 @@
box_.set_border(5, 5, 5, 5);
// Setup plot data
- plot_.set_sample_rate(STATISTICS_SAMPLE_TIME);
- plot_.set_plotmode(WuiPlotArea::PLOTMODE_ABSOLUTE);
Game & game = *parent.get_game();
const Game::GeneralStatsVector & genstats =
game.get_general_statistics();
=== modified file 'src/wui/plot_area.cc'
--- src/wui/plot_area.cc 2016-03-29 17:28:15 +0000
+++ src/wui/plot_area.cc 2016-05-19 11:15:41 +0000
@@ -39,24 +39,24 @@
constexpr int32_t kUpdateTimeInGametimeMs = 1000; // 1 second, gametime
-const uint32_t minutes = 60 * 1000;
-const uint32_t hours = 60 * 60 * 1000;
-const uint32_t days = 24 * 60 * 60 * 1000;
+constexpr uint32_t kMinutes = 60 * 1000;
+constexpr uint32_t kHours = 60 * 60 * 1000;
+constexpr uint32_t kDays = 24 * 60 * 60 * 1000;
-const int32_t spacing = 5;
-const int32_t space_at_bottom = 20;
-const int32_t space_at_right = 10;
-const int32_t space_left_of_label = 15;
-const uint32_t nr_samples = 30; // How many samples per diagramm when relative plotting
+constexpr int32_t kSpacing = 5;
+constexpr int32_t kSpaceBottom = 20;
+constexpr int32_t kSpaceRight = 10;
+constexpr int32_t kSpaceLeftOfLabel = 15;
+constexpr uint32_t KNoSamples = 30; // How many samples per diagramm when relative plotting
const uint32_t time_in_ms[] = {
- 15 * minutes,
- 30 * minutes,
- 1 * hours,
- 2 * hours,
- 5 * hours,
- 10 * hours,
- 30 * hours
+ 15 * kMinutes,
+ 30 * kMinutes,
+ 1 * kHours,
+ 2 * kHours,
+ 5 * kHours,
+ 10 * kHours,
+ 30 * kHours
};
const char BG_PIC[] = "images/wui/plot_area_bg.png";
@@ -99,18 +99,18 @@
Units get_suggested_unit(uint32_t game_time, bool is_generic = false) {
// Find a nice unit for max_x
if (is_generic) {
- if (game_time > 4 * days) {
+ if (game_time > 4 * kDays) {
return Units::kDayGeneric;
- } else if (game_time > 4 * hours) {
+ } else if (game_time > 4 * kHours) {
return Units::kHourGeneric;
} else {
return Units::kMinutesGeneric;
}
}
else {
- if (game_time > 4 * days) {
+ if (game_time > 4 * kDays) {
return Units::kDayNarrow;
- } else if (game_time > 4 * hours) {
+ } else if (game_time > 4 * kHours) {
return Units::kHourNarrow;
} else {
return Units::kMinutesNarrow;
@@ -153,13 +153,13 @@
switch (unit) {
case Units::kDayGeneric:
case Units::kDayNarrow:
- return ms / days;
+ return ms / kDays;
case Units::kHourGeneric:
case Units::kHourNarrow:
- return ms / hours;
+ return ms / kHours;
case Units::kMinutesGeneric:
case Units::kMinutesNarrow:
- return ms / minutes;
+ return ms / kMinutes;
}
NEVER_HERE();
}
@@ -167,11 +167,11 @@
/**
* calculate how many values are taken together when plot mode is relative
*/
-int32_t calc_how_many(uint32_t time_ms, int32_t sample_rate) {
+int32_t calc_how_many(uint32_t time_ms, uint32_t sample_rate) {
int32_t how_many = static_cast<int32_t>
((static_cast<float>(time_ms)
/
- static_cast<float>(nr_samples))
+ static_cast<float>(KNoSamples))
/
static_cast<float>(sample_rate));
@@ -230,28 +230,28 @@
// Draw coordinate system
// X Axis
dst.draw_line_strip({
- FloatPoint(spacing, inner_h - space_at_bottom),
- FloatPoint(inner_w - space_at_right, inner_h - space_at_bottom)},
+ FloatPoint(kSpacing, inner_h - kSpaceBottom),
+ FloatPoint(inner_w - kSpaceRight, inner_h - kSpaceBottom)},
kAxisLineColor, kAxisLinesWidth);
// Arrow
dst.draw_line_strip({
- FloatPoint(spacing + 5, inner_h - space_at_bottom - 3),
- FloatPoint(spacing, inner_h - space_at_bottom),
- FloatPoint(spacing + 5, inner_h - space_at_bottom + 3),
+ FloatPoint(kSpacing + 5, inner_h - kSpaceBottom - 3),
+ FloatPoint(kSpacing, inner_h - kSpaceBottom),
+ FloatPoint(kSpacing + 5, inner_h - kSpaceBottom + 3),
}, kAxisLineColor, kAxisLinesWidth);
// Y Axis
- dst.draw_line_strip({FloatPoint(inner_w - space_at_right, spacing),
- FloatPoint(inner_w - space_at_right, inner_h - space_at_bottom)},
+ dst.draw_line_strip({FloatPoint(inner_w - kSpaceRight, kSpacing),
+ FloatPoint(inner_w - kSpaceRight, inner_h - kSpaceBottom)},
kAxisLineColor, kAxisLinesWidth);
// No Arrow here, since this doesn't continue.
- float sub = (xline_length - space_left_of_label) / how_many_ticks;
- float posx = inner_w - space_at_right;
+ float sub = (xline_length - kSpaceLeftOfLabel) / how_many_ticks;
+ float posx = inner_w - kSpaceRight;
for (uint32_t i = 0; i <= how_many_ticks; ++i) {
- dst.draw_line_strip({FloatPoint(static_cast<int32_t>(posx), inner_h - space_at_bottom),
- FloatPoint(static_cast<int32_t>(posx), inner_h - space_at_bottom + 3)},
+ dst.draw_line_strip({FloatPoint(static_cast<int32_t>(posx), inner_h - kSpaceBottom),
+ FloatPoint(static_cast<int32_t>(posx), inner_h - kSpaceBottom + 3)},
kAxisLineColor, kAxisLinesWidth);
// The space at the end is intentional to have the tick centered
@@ -259,7 +259,7 @@
const Image* xtick = UI::g_fh1->render
(xtick_text_style((boost::format("-%u ") % (max_x / how_many_ticks * i)).str()));
dst.blit
- (Point(static_cast<int32_t>(posx), inner_h - space_at_bottom + 10),
+ (Point(static_cast<int32_t>(posx), inner_h - kSpaceBottom + 10),
xtick, BlendMode::UseAlpha, UI::Align::kCenter);
posx -= sub;
@@ -267,29 +267,32 @@
// draw yticks, one at full, one at half
dst.draw_line_strip({
- FloatPoint(inner_w - space_at_right, spacing), FloatPoint(inner_w - space_at_right - 3, spacing)},
+ FloatPoint(inner_w - kSpaceRight, kSpacing), FloatPoint(inner_w - kSpaceRight - 3, kSpacing)},
kAxisLineColor, kAxisLinesWidth);
dst.draw_line_strip({
- FloatPoint(inner_w - space_at_right, spacing + ((inner_h - space_at_bottom) - spacing) / 2),
- FloatPoint(inner_w - space_at_right - 3, spacing + ((inner_h - space_at_bottom) - spacing) / 2)},
+ FloatPoint(inner_w - kSpaceRight, kSpacing + ((inner_h - kSpaceBottom) - kSpacing) / 2),
+ FloatPoint(inner_w - kSpaceRight - 3, kSpacing + ((inner_h - kSpaceBottom) - kSpacing) / 2)},
kAxisLineColor, kAxisLinesWidth);
// print the used unit
const Image* xtick = UI::g_fh1->render(xtick_text_style(get_generic_unit_name(unit)));
- dst.blit(Point(2, spacing + 2), xtick, BlendMode::UseAlpha, UI::Align::kCenterLeft);
+ dst.blit(Point(2, kSpacing + 2), xtick, BlendMode::UseAlpha, UI::Align::kCenterLeft);
}
} // namespace
WuiPlotArea::WuiPlotArea
(UI::Panel * const parent,
- int32_t const x, int32_t const y, int32_t const w, int32_t const h)
+ int32_t const x, int32_t const y, int32_t const w, int32_t const h,
+ uint32_t sample_rate, Plotmode plotmode)
:
UI::Panel (parent, x, y, w, h),
-plotmode_(PLOTMODE_ABSOLUTE),
-sample_rate_(0),
+plotmode_(plotmode),
+sample_rate_(sample_rate),
needs_update_(true),
lastupdate_(0),
+xline_length_(get_inner_w() - kSpaceRight - kSpacing),
+yline_length_(get_inner_h() - kSpaceBottom - kSpacing),
time_ms_(0),
highest_scale_(0),
sub_(0.0f),
@@ -300,19 +303,19 @@
}
-uint32_t WuiPlotArea::get_game_time() {
+uint32_t WuiPlotArea::get_game_time() const {
uint32_t game_time = 0;
// Find running time of the game, based on the plot data
for (uint32_t plot = 0; plot < plotdata_.size(); ++plot)
- if (game_time < plotdata_[plot].dataset->size() * sample_rate_)
- game_time = plotdata_[plot].dataset->size() * sample_rate_;
+ if (game_time < plotdata_[plot].absolute_data->size() * sample_rate_)
+ game_time = plotdata_[plot].absolute_data->size() * sample_rate_;
return game_time;
}
-std::vector<std::string> WuiPlotArea::get_labels() {
+std::vector<std::string> WuiPlotArea::get_labels() const {
std::vector<std::string> labels;
- for (int32_t i = 0; i < game_time_id_; i++) {
+ for (uint32_t i = 0; i < game_time_id_; i++) {
Units unit = get_suggested_unit(time_in_ms[i], false);
labels.push_back(get_value_with_unit(unit, ms_to_unit(unit, time_in_ms[i])));
}
@@ -320,7 +323,7 @@
return labels;
}
-uint32_t WuiPlotArea::get_plot_time() {
+uint32_t WuiPlotArea::get_plot_time() const {
if (time_ == TIME_GAME) {
// Start with the game time
uint32_t time_ms = get_game_time();
@@ -331,14 +334,14 @@
// or a multiple of 2h
// or a multiple of 20h
// or a multiple of 4 days
- if (time_ms > 8 * days) {
- time_ms += - (time_ms % (4 * days)) + 4 * days;
- } else if (time_ms > 40 * hours) {
- time_ms += - (time_ms % (20 * hours)) + 20 * hours;
- } else if (time_ms > 4 * hours) {
- time_ms += - (time_ms % (2 * hours)) + 2 * hours;
+ if (time_ms > 8 * kDays) {
+ time_ms += - (time_ms % (4 * kDays)) + 4 * kDays;
+ } else if (time_ms > 40 * kHours) {
+ time_ms += - (time_ms % (20 * kHours)) + 20 * kHours;
+ } else if (time_ms > 4 * kHours) {
+ time_ms += - (time_ms % (2 * kHours)) + 2 * kHours;
} else {
- time_ms += - (time_ms % (15 * minutes)) + 15 * minutes;
+ time_ms += - (time_ms % (15 * kMinutes)) + 15 * kMinutes;
}
return time_ms;
} else {
@@ -356,7 +359,7 @@
* We start to search with i=1 to ensure that at least one option besides
* "game" will be offered to the user.
*/
-int32_t WuiPlotArea::get_game_time_id() {
+uint32_t WuiPlotArea::get_game_time_id() {
uint32_t game_time = get_game_time();
uint32_t i;
for (i = 1; i < 7 && time_in_ms[i] <= game_time; i++) {
@@ -376,29 +379,47 @@
needs_update_ = false;
}
+int32_t WuiPlotArea::initialize_update() {
+ // Initialize
+ for (uint32_t i = 0; i < plotdata_.size(); ++i) {
+ plotdata_[i].relative_data->clear();
+ }
+ // Get range
+ time_ms_ = get_plot_time();
+ if (plotmode_ == Plotmode::kAbsolute) {
+ sub_ =
+ (xline_length_ - kSpaceLeftOfLabel)
+ /
+ (static_cast<float>(time_ms_)
+ /
+ static_cast<float>(sample_rate_));
+ } else {
+ sub_ = (xline_length_ - kSpaceLeftOfLabel) / static_cast<float>(KNoSamples);
+ }
+
+ // How many do we aggregate when relative plotting
+ return calc_how_many(time_ms_, sample_rate_);
+}
// Find the maximum value.
void WuiPlotArea::update() {
- float const xline_length = get_inner_w() - space_at_right - spacing;
-
- time_ms_ = get_plot_time();
-
- // How many do we take together when relative ploting
- const int32_t how_many = calc_how_many(time_ms_, sample_rate_);
+ const int32_t how_many = initialize_update();
+
+ // Calculate highest scale
highest_scale_ = 0;
- if (plotmode_ == PLOTMODE_ABSOLUTE) {
+ if (plotmode_ == Plotmode::kAbsolute) {
for (uint32_t i = 0; i < plotdata_.size(); ++i)
if (plotdata_[i].showplot) {
- for (uint32_t l = 0; l < plotdata_[i].dataset->size(); ++l)
- if (highest_scale_ < (*plotdata_[i].dataset)[l])
- highest_scale_ = (*plotdata_[i].dataset)[l];
+ for (uint32_t l = 0; l < plotdata_[i].absolute_data->size(); ++l) {
+ if (highest_scale_ < (*plotdata_[i].absolute_data)[l]) {
+ highest_scale_ = (*plotdata_[i].absolute_data)[l];
+ }
+ }
}
} else {
for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) {
if (plotdata_[plot].showplot) {
-
- const std::vector<uint32_t> & dataset = *plotdata_[plot].dataset;
-
+ const std::vector<uint32_t> & dataset = *plotdata_[plot].absolute_data;
uint32_t add = 0;
// Relative data, first entry is always zero.
for (uint32_t i = 0; i < dataset.size(); ++i) {
@@ -413,31 +434,21 @@
}
}
- // Update the datasets
- sub_ =
- (xline_length - space_left_of_label)
- /
- (static_cast<float>(time_ms_)
- /
- static_cast<float>(sample_rate_));
- for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) {
- if (plotdata_[plot].showplot) {
- std::vector<uint32_t> const * dataset = plotdata_[plot].dataset;
-
- std::vector<uint32_t> data;
- if (plotmode_ == PLOTMODE_RELATIVE) {
+ // Calculate plot data
+ if (plotmode_ == Plotmode::kRelative) {
+ for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) {
+ if (plotdata_[plot].showplot) {
+ std::vector<uint32_t> const * dataset = plotdata_[plot].absolute_data;
uint32_t add = 0;
// Relative data, first entry is always zero
- data.push_back(0);
+ plotdata_[plot].relative_data->push_back(0);
for (uint32_t i = 0; i < dataset->size(); ++i) {
add += (*dataset)[i];
if (0 == ((i + 1) % how_many)) {
- data.push_back(add);
+ plotdata_[plot].relative_data->push_back(add);
add = 0;
}
}
- dataset = &data;
- sub_ = (xline_length - space_left_of_label) / static_cast<float>(nr_samples);
}
}
}
@@ -449,23 +460,22 @@
* Draw this. This is the main function
*/
void WuiPlotArea::draw(RenderTarget & dst) {
- float const xline_length = get_inner_w() - space_at_right - spacing;
- float const yline_length = get_inner_h() - space_at_bottom - spacing;
+ draw_plot(dst, get_inner_h() - kSpaceBottom, std::to_string(highest_scale_), highest_scale_);
+}
- draw_diagram(time_ms_, get_inner_w(), get_inner_h(), xline_length, dst);
+void WuiPlotArea::draw_plot(RenderTarget& dst, float const yoffset, const std::string& yscale_label, uint32_t highest_scale) {
+ draw_diagram(time_ms_, get_inner_w(), get_inner_h(), xline_length_, dst);
// print the maximal value into the top right corner
draw_value
- (std::to_string(highest_scale_), RGBColor(60, 125, 0),
- Point(get_inner_w() - space_at_right - 2, spacing + 2), dst);
+ (yscale_label, RGBColor(60, 125, 0),
+ Point(get_inner_w() - kSpaceRight - 2, kSpacing + 2), dst);
// plot the pixels
for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) {
if (plotdata_[plot].showplot) {
- RGBColor color = plotdata_[plot].plotcolor;
- std::vector<uint32_t> const * dataset = plotdata_[plot].dataset;
draw_plot_line
- (dst, dataset, yline_length, highest_scale_, sub_, color, get_inner_h() - space_at_bottom);
+ (dst, (plotmode_ == Plotmode::kRelative) ? plotdata_[plot].relative_data : plotdata_[plot].absolute_data, highest_scale, sub_, plotdata_[plot].plotcolor, yoffset);
}
}
}
@@ -476,34 +486,37 @@
* \param sub horizontal difference between 2 y values
*/
void WuiPlotArea::draw_plot_line
- (RenderTarget & dst, std::vector<uint32_t> const * dataset, float const yline_length,
+ (RenderTarget & dst, std::vector<uint32_t> const * dataset,
uint32_t const highest_scale, float const sub, RGBColor const color, int32_t const yoffset)
{
- float posx = get_inner_w() - space_at_right;
- const int lx = get_inner_w() - space_at_right;
- int ly = yoffset;
- // Init start point of the plot line with the first data value.
- // This prevents that the plot starts always at zero
- if (int value = (*dataset)[dataset->size() - 1]) {
- ly -= static_cast<int32_t>(scale_value(yline_length, highest_scale, value));
- }
-
- std::vector<FloatPoint> points;
- points.emplace_back(lx, ly);
-
- for (int32_t i = dataset->size() - 1; i > 0 && posx > spacing; --i) {
- int32_t const curx = static_cast<int32_t>(posx);
- int32_t cury = yoffset;
-
- // Scale the line to the available space
- if (int32_t value = (*dataset)[i]) {
- const float length_y = scale_value(yline_length, highest_scale, value);
- cury -= static_cast<int32_t>(length_y);
- }
- points.emplace_back(curx, cury);
- posx -= sub;
- }
- dst.draw_line_strip(points, color, kPlotLinesWidth);
+ if (!dataset->empty()) {
+ float posx = get_inner_w() - kSpaceRight;
+ const int lx = get_inner_w() - kSpaceRight;
+ int ly = yoffset;
+ // Init start point of the plot line with the first data value.
+ // This prevents that the plot starts always at zero
+
+ if (int value = (*dataset)[dataset->size() - 1]) {
+ ly -= static_cast<int32_t>(scale_value(yline_length_, highest_scale, value));
+ }
+
+ std::vector<FloatPoint> points;
+ points.emplace_back(lx, ly);
+
+ for (int32_t i = dataset->size() - 1; i > 0 && posx > kSpacing; --i) {
+ int32_t const curx = static_cast<int32_t>(posx);
+ int32_t cury = yoffset;
+
+ // Scale the line to the available space
+ if (int32_t value = (*dataset)[i]) {
+ const float length_y = scale_value(yline_length_, highest_scale, value);
+ cury -= static_cast<int32_t>(length_y);
+ }
+ points.emplace_back(curx, cury);
+ posx -= sub;
+ }
+ dst.draw_line_strip(points, color, kPlotLinesWidth);
+ }
}
/*
@@ -517,7 +530,8 @@
if (id >= plotdata_.size())
plotdata_.resize(id + 1);
- plotdata_[id].dataset = data;
+ plotdata_[id].absolute_data = data;
+ plotdata_[id].relative_data = new std::vector<uint32_t>(); // Will be filled in the update() function.
plotdata_[id].showplot = false;
plotdata_[id].plotcolor = color;
@@ -544,17 +558,9 @@
needs_update_ = true;
}
-/*
- * Set sample rate the data uses
- */
-void WuiPlotArea::set_sample_rate(uint32_t const id) {
- sample_rate_ = id;
- needs_update_ = true;
-}
-
void WuiPlotAreaSlider::draw(RenderTarget & dst) {
- int32_t new_game_time_id = plot_area_.get_game_time_id();
+ uint32_t new_game_time_id = plot_area_.get_game_time_id();
if (new_game_time_id != last_game_time_id_) {
last_game_time_id_ = new_game_time_id;
set_labels(plot_area_.get_labels());
@@ -565,31 +571,27 @@
DifferentialPlotArea::DifferentialPlotArea
(UI::Panel * const parent,
- int32_t const x, int32_t const y, int32_t const w, int32_t const h)
+ int32_t const x, int32_t const y, int32_t const w, int32_t const h,
+ uint32_t sample_rate, Plotmode plotmode)
:
-WuiPlotArea (parent, x, y, w, h)
+WuiPlotArea (parent, x, y, w, h, sample_rate, plotmode)
{
update();
}
void DifferentialPlotArea::update() {
- float const xline_length = get_inner_w() - space_at_right - spacing;
-
- time_ms_ = get_plot_time();
-
- // How many do we take together when relative ploting
- const int32_t how_many = calc_how_many(time_ms_, sample_rate_);
-
- // Find max and min value
+ const int32_t how_many = initialize_update();
+
+ // Calculate highest scale
int32_t max = 0;
int32_t min = 0;
- if (plotmode_ == PLOTMODE_ABSOLUTE) {
+ if (plotmode_ == Plotmode::kAbsolute) {
for (uint32_t i = 0; i < plotdata_.size(); ++i)
if (plotdata_[i].showplot) {
- for (uint32_t l = 0; l < plotdata_[i].dataset->size(); ++l) {
- int32_t temp = (*plotdata_[i].dataset)[l] -
- (*negative_plotdata_[i].dataset)[l];
+ for (uint32_t l = 0; l < plotdata_[i].absolute_data->size(); ++l) {
+ int32_t temp = (*plotdata_[i].absolute_data)[l] -
+ (*negative_plotdata_[i].absolute_data)[l];
if (max < temp) max = temp;
if (min > temp) min = temp;
}
@@ -598,8 +600,8 @@
for (uint32_t plot = 0; plot < plotdata_.size(); ++plot)
if (plotdata_[plot].showplot) {
- const std::vector<uint32_t> & dataset = *plotdata_[plot].dataset;
- const std::vector<uint32_t> & ndataset = *negative_plotdata_[plot].dataset;
+ const std::vector<uint32_t> & dataset = *plotdata_[plot].absolute_data;
+ const std::vector<uint32_t> & ndataset = *negative_plotdata_[plot].absolute_data;
int32_t add = 0;
// Relative data, first entry is always zero.
@@ -616,77 +618,43 @@
// Use equal positive and negative range
min = abs(min);
- highest_scale_ = 0;
- if (min > max) {
- highest_scale_ = min;
- } else {
- highest_scale_ = max;
- }
-
- // plot the pixels
- sub_ =
- xline_length
- /
- (static_cast<float>(time_ms_)
- /
- static_cast<float>(sample_rate_));
- for (uint32_t plot = 0; plot < plotdata_.size(); ++plot)
- if (plotdata_[plot].showplot) {
- std::vector<uint32_t> const * dataset = plotdata_[plot].dataset;
- std::vector<uint32_t> const * ndataset = negative_plotdata_[plot].dataset;
-
- std::vector<uint32_t> data_;
- if (plotmode_ == PLOTMODE_RELATIVE) {
- int32_t add = 0;
+ highest_scale_ = (min > max) ? min : max;
+
+ // Calculate plot data
+ if (plotmode_ == Plotmode::kRelative) {
+ for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) {
+ if (plotdata_[plot].showplot) {
+ std::vector<uint32_t> const * dataset = plotdata_[plot].absolute_data;
+ std::vector<uint32_t> const * ndataset = negative_plotdata_[plot].absolute_data;
+ uint32_t add = 0;
// Relative data, first entry is always zero
- data_.push_back(0);
+ plotdata_[plot].relative_data->push_back(0);
for (uint32_t i = 0; i < dataset->size(); ++i) {
add += (*dataset)[i] - (*ndataset)[i];
if (0 == ((i + 1) % how_many)) {
- data_.push_back(add);
+ plotdata_[plot].relative_data->push_back(add);
add = 0;
}
}
- dataset = &data_;
- sub_ = xline_length / static_cast<float>(nr_samples);
}
}
+ }
}
void DifferentialPlotArea::draw(RenderTarget & dst) {
- float const xline_length = get_inner_w() - space_at_right - spacing;
- float const yline_length = get_inner_h() - space_at_bottom - spacing;
// yoffset of the zero line
- float const yoffset = spacing + ((get_inner_h() - space_at_bottom) - spacing) / 2;
+ float const yoffset = kSpacing + ((get_inner_h() - kSpaceBottom) - kSpacing) / 2;
+ draw_plot(dst, yoffset, std::to_string(highest_scale_), 2 * highest_scale_);
- time_ms_ = get_plot_time();
- draw_diagram(time_ms_, get_inner_w(), get_inner_h(), xline_length, dst);
+ // Print the min value
+ draw_value
+ ((boost::format("-%u") % (highest_scale_)).str(), RGBColor(125, 0, 0),
+ Point(get_inner_w() - kSpaceRight - 2, get_inner_h() - kSpacing - 15), dst);
// draw zero line
- dst.draw_line_strip({FloatPoint(get_inner_w() - space_at_right, yoffset),
- FloatPoint(get_inner_w() - space_at_right - xline_length, yoffset)},
+ dst.draw_line_strip({FloatPoint(get_inner_w() - kSpaceRight, yoffset),
+ FloatPoint(get_inner_w() - kSpaceRight - xline_length_, yoffset)},
kZeroLineColor, kPlotLinesWidth);
-
- // Print the min and max values
- draw_value
- (std::to_string(highest_scale_), RGBColor(60, 125, 0),
- Point(get_inner_w() - space_at_right - 2, spacing + 2), dst);
-
- draw_value
- ((boost::format("-%u") % highest_scale_).str(), RGBColor(125, 0, 0),
- Point(get_inner_w() - space_at_right - 2, get_inner_h() - spacing - 15), dst);
-
- // plot the pixels
- for (uint32_t plot = 0; plot < plotdata_.size(); ++plot)
- if (plotdata_[plot].showplot) {
-
- RGBColor color = plotdata_[plot].plotcolor;
- std::vector<uint32_t> const * dataset = plotdata_[plot].dataset;
-
- // Highest_scale represent the space between zero line and top.
- // -> half of the whole differential plot area
- draw_plot_line(dst, dataset, yline_length, highest_scale_ * 2, sub_, color, yoffset);
- }
}
/**
@@ -696,9 +664,10 @@
void DifferentialPlotArea::register_negative_plot_data
(uint32_t const id, std::vector<uint32_t> const * const data) {
- if (id >= negative_plotdata_.size())
+ if (id >= negative_plotdata_.size()) {
negative_plotdata_.resize(id + 1);
+ }
- negative_plotdata_[id].dataset = data;
+ negative_plotdata_[id].absolute_data = data;
needs_update_ = true;
}
=== modified file 'src/wui/plot_area.h'
--- src/wui/plot_area.h 2016-03-19 17:30:37 +0000
+++ src/wui/plot_area.h 2016-05-19 11:15:41 +0000
@@ -44,16 +44,17 @@
TIME_16_HOURS,
TIME_GAME,
};
- enum PLOTMODE {
- // Always take the samples of some times together, so that the graph is
- // not completely zigg-zagged.
- PLOTMODE_RELATIVE,
-
- PLOTMODE_ABSOLUTE
+ enum class Plotmode {
+ // Always aggregate the samples of some time periods, so that the graph is
+ // not completely zig-zagged.
+ kRelative,
+ kAbsolute
};
+ // sample_rate is in in milliseconds
WuiPlotArea
- (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h);
+ (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h,
+ uint32_t sample_rate, Plotmode plotmode);
/// Calls update() if needed
void think() override;
@@ -65,51 +66,53 @@
needs_update_ = true;
}
- void set_time_id(int32_t time) {
+ void set_time_id(uint32_t time) {
if (time == game_time_id_)
set_time(TIME_GAME);
else
set_time(static_cast<TIME>(time));
needs_update_ = true;
}
- TIME get_time() {return static_cast<TIME>(time_); }
- int32_t get_time_id() {
+ TIME get_time() const {return static_cast<TIME>(time_); }
+ int32_t get_time_id() const {
if (time_ == TIME_GAME)
return game_time_id_;
else
return time_;
}
- void set_sample_rate(uint32_t id); // in milliseconds
- int32_t get_game_time_id();
+ uint32_t get_game_time_id();
void register_plot_data
(uint32_t id, const std::vector<uint32_t> * data, RGBColor);
void show_plot(uint32_t id, bool t);
- void set_plotmode(int32_t id) {plotmode_ = id;}
-
void set_plotcolor(uint32_t id, RGBColor color);
- std::vector<std::string> get_labels();
+ std::vector<std::string> get_labels() const;
protected:
+ void draw_plot(RenderTarget& dst, float const yoffset, const std::string& yscale_label, uint32_t highest_scale);
void draw_plot_line
- (RenderTarget & dst, std::vector<uint32_t> const * dataset, float const yline_length,
+ (RenderTarget & dst, std::vector<uint32_t> const * dataset,
uint32_t const highest_scale, float const sub, RGBColor const color, int32_t yoffset);
- uint32_t get_plot_time();
+ uint32_t get_plot_time() const;
/// Recalculates the data
virtual void update();
+ // Initializes relative_dataset and time scaling.
+ // Returns how many values will be aggregated when relative plotting
+ int32_t initialize_update();
struct PlotData {
- const std::vector<uint32_t> * dataset;
+ const std::vector<uint32_t> * absolute_data; // The absolute dataset
+ std::vector<uint32_t> * relative_data; // The relative dataset
bool showplot;
RGBColor plotcolor;
};
std::vector<PlotData> plotdata_;
- int32_t plotmode_;
- int32_t sample_rate_;
+ Plotmode plotmode_;
+ uint32_t sample_rate_;
/// Whether there has ben a data update since the last time that think() was executed
bool needs_update_;
@@ -117,15 +120,17 @@
uint32_t lastupdate_;
/// For first updating and then plotting the data
+ float const xline_length_;
+ float const yline_length_;
uint32_t time_ms_;
uint32_t highest_scale_;
float sub_;
private:
- uint32_t get_game_time();
+ uint32_t get_game_time() const;
TIME time_; // How much do you want to list
- int32_t game_time_id_; // what label is used for TIME_GAME
+ uint32_t game_time_id_; // what label is used for TIME_GAME
};
/**
@@ -161,7 +166,7 @@
private:
WuiPlotArea & plot_area_;
- int32_t last_game_time_id_;
+ uint32_t last_game_time_id_;
};
/**
@@ -172,7 +177,8 @@
struct DifferentialPlotArea : public WuiPlotArea {
public:
DifferentialPlotArea
- (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h);
+ (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h,
+ uint32_t sample_rate, Plotmode plotmode);
void draw(RenderTarget &) override;
@@ -184,13 +190,14 @@
void update() override;
private:
-
/**
- * for the negative plotdata only the values matter. The color and
+ * For the negative plotdata, only the values matter. The color and
* visibility is determined by the normal plotdata.
+ * We don't need relative data to fill - this is also done in the
+ * normal plotdata
*/
struct ReducedPlotData {
- const std::vector<uint32_t> * dataset;
+ const std::vector<uint32_t> * absolute_data;
};
std::vector<ReducedPlotData> negative_plotdata_;
};
=== modified file 'src/wui/ware_statistics_menu.cc'
--- src/wui/ware_statistics_menu.cc 2016-03-30 07:20:05 +0000
+++ src/wui/ware_statistics_menu.cc 2016-05-19 11:15:41 +0000
@@ -164,9 +164,9 @@
plot_production_ =
new WuiPlotArea
(tabs,
- 0, 0, kPlotWidth, kPlotHeight + kSpacing);
- plot_production_->set_sample_rate(STATISTICS_SAMPLE_TIME);
- plot_production_->set_plotmode(WuiPlotArea::PLOTMODE_RELATIVE);
+ 0, 0, kPlotWidth, kPlotHeight + kSpacing,
+ kStatisticsSampleTime,
+ WuiPlotArea::Plotmode::kRelative);
tabs->add
("production", g_gr->images().get(pic_tab_production),
@@ -175,9 +175,9 @@
plot_consumption_ =
new WuiPlotArea
(tabs,
- 0, 0, kPlotWidth, kPlotHeight + kSpacing);
- plot_consumption_->set_sample_rate(STATISTICS_SAMPLE_TIME);
- plot_consumption_->set_plotmode(WuiPlotArea::PLOTMODE_RELATIVE);
+ 0, 0, kPlotWidth, kPlotHeight + kSpacing,
+ kStatisticsSampleTime,
+ WuiPlotArea::Plotmode::kRelative);
tabs->add
("consumption", g_gr->images().get(pic_tab_consumption),
@@ -186,9 +186,9 @@
plot_economy_ =
new DifferentialPlotArea
(tabs,
- 0, 0, kPlotWidth, kPlotHeight + kSpacing);
- plot_economy_->set_sample_rate(STATISTICS_SAMPLE_TIME);
- plot_economy_->set_plotmode(WuiPlotArea::PLOTMODE_RELATIVE);
+ 0, 0, kPlotWidth, kPlotHeight + kSpacing,
+ kStatisticsSampleTime,
+ WuiPlotArea::Plotmode::kRelative);
tabs->add
("economy_health", g_gr->images().get(pic_tab_economy),
@@ -196,9 +196,9 @@
plot_stock_ = new WuiPlotArea
(tabs,
- 0, 0, kPlotWidth, kPlotHeight + kSpacing);
- plot_stock_->set_sample_rate(STATISTICS_SAMPLE_TIME);
- plot_stock_->set_plotmode(WuiPlotArea::PLOTMODE_ABSOLUTE);
+ 0, 0, kPlotWidth, kPlotHeight + kSpacing,
+ kStatisticsSampleTime,
+ WuiPlotArea::Plotmode::kAbsolute);
tabs->add
("stock", g_gr->images().get(pic_tab_stock),
Follow ups
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: noreply, 2016-06-21
-
Re: [Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: GunChleoc, 2016-06-21
-
Re: [Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: TiborB, 2016-06-20
-
Re: [Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: GunChleoc, 2016-06-20
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-06-20
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-06-20
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-06-20
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-06-10
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-06-08
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-06-08
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-05-24
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-05-24
-
Re: [Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: kaputtnik, 2016-05-20
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-05-20
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-05-20
-
[Merge] lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
From: bunnybot, 2016-05-19