Merge lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode into lp:widelands
- bug-1573057-graph-relative-plotmode
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 8022 | ||||||||
Proposed branch: | lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode | ||||||||
Merge into: | lp:widelands | ||||||||
Diff against target: |
918 lines (+231/-248) 6 files modified
src/logic/cmd_calculate_statistics.cc (+1/-1) src/logic/constants.h (+4/-2) src/wui/general_statistics_menu.cc (+3/-3) src/wui/plot_area.cc (+176/-203) src/wui/plot_area.h (+35/-27) src/wui/ware_statistics_menu.cc (+12/-12) |
||||||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/bug-1573057-graph-relative-plotmode | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
TiborB | Approve | ||
kaputtnik (community) | testing | Approve | |
Review via email: mp+295198@code.launchpad.net |
Commit message
Fixed relative plot mode and flickering graphs on button click. Only draw active statistics tab. Some refactoring.
Description of the change
GunChleoc (gunchleoc) wrote : | # |
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 1139. State: failed. Details: https:/
Appveyor build 976. State: failed. Details: https:/
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 1143. State: passed. Details: https:/
Appveyor build 980. State: failed. Details: https:/
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 1143. State: passed. Details: https:/
Appveyor build 980. State: success. Details: https:/
kaputtnik (franku) wrote : | # |
Works as expected :-)
bunnybot (widelandsofficial) wrote : | # |
Bunnybot encountered an error while working on this merge proposal:
<urlopen error _ssl.c:495: The handshake operation timed out>
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 1143. State: passed. Details: https:/
Appveyor build 980. State: success. Details: https:/
bunnybot (widelandsofficial) wrote : | # |
Bunnybot encountered an error while working on this merge proposal:
The read operation timed out
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 1143. State: passed. Details: https:/
Appveyor build 980. State: success. Details: https:/
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 1156. State: failed. Details: https:/
Appveyor build 994. State: success. Details: https:/
bunnybot (widelandsofficial) wrote : | # |
Bunnybot encountered an error while working on this merge proposal:
<urlopen error _ssl.c:495: The handshake operation timed out>
bunnybot (widelandsofficial) wrote : | # |
Bunnybot encountered an error while working on this merge proposal:
<urlopen error _ssl.c:495: The handshake operation timed out>
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 1156. State: failed. Details: https:/
Appveyor build 994. State: success. Details: https:/
GunChleoc (gunchleoc) wrote : | # |
Ping?
It would be good to get this branch in so that we can go into official feature freeze.
TiborB (tiborb95) wrote : | # |
oh, too complicated for me, but it at least LOOKS good to me :)
GunChleoc (gunchleoc) wrote : | # |
Now you know how I feel when I review your AI code *lol* Thanks!
@bunnybot merge
Preview Diff
1 | === modified file 'src/logic/cmd_calculate_statistics.cc' | |||
2 | --- src/logic/cmd_calculate_statistics.cc 2015-10-24 15:42:37 +0000 | |||
3 | +++ src/logic/cmd_calculate_statistics.cc 2016-06-10 17:28:35 +0000 | |||
4 | @@ -31,7 +31,7 @@ | |||
5 | 31 | game.sample_statistics(); | 31 | game.sample_statistics(); |
6 | 32 | game.enqueue_command | 32 | game.enqueue_command |
7 | 33 | (new CmdCalculateStatistics | 33 | (new CmdCalculateStatistics |
9 | 34 | (game.get_gametime() + STATISTICS_SAMPLE_TIME)); | 34 | (game.get_gametime() + kStatisticsSampleTime)); |
10 | 35 | } | 35 | } |
11 | 36 | 36 | ||
12 | 37 | constexpr uint16_t kCurrentPacketVersion = 1; | 37 | constexpr uint16_t kCurrentPacketVersion = 1; |
13 | 38 | 38 | ||
14 | === modified file 'src/logic/constants.h' | |||
15 | --- src/logic/constants.h 2015-03-01 09:21:20 +0000 | |||
16 | +++ src/logic/constants.h 2016-06-10 17:28:35 +0000 | |||
17 | @@ -1,5 +1,5 @@ | |||
18 | 1 | /* | 1 | /* |
20 | 2 | * Copyright (C) 2006-2015 by the Widelands Development Team | 2 | * Copyright (C) 2006-2016 by the Widelands Development Team |
21 | 3 | * | 3 | * |
22 | 4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
23 | 5 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
24 | @@ -20,6 +20,8 @@ | |||
25 | 20 | #ifndef WL_LOGIC_CONSTANTS_H | 20 | #ifndef WL_LOGIC_CONSTANTS_H |
26 | 21 | #define WL_LOGIC_CONSTANTS_H | 21 | #define WL_LOGIC_CONSTANTS_H |
27 | 22 | 22 | ||
28 | 23 | #include <cstdint> | ||
29 | 24 | |||
30 | 23 | /// Maximum numbers of players in a game. The game logic code reserves 5 bits | 25 | /// Maximum numbers of players in a game. The game logic code reserves 5 bits |
31 | 24 | /// for player numbers, so it can keep track of 32 different player numbers, of | 26 | /// for player numbers, so it can keep track of 32 different player numbers, of |
32 | 25 | /// which the value 0 means neutral and the values 1 .. 31 can be used as the | 27 | /// which the value 0 means neutral and the values 1 .. 31 can be used as the |
33 | @@ -27,6 +29,6 @@ | |||
34 | 27 | #define MAX_PLAYERS 8 | 29 | #define MAX_PLAYERS 8 |
35 | 28 | 30 | ||
36 | 29 | /// How often are statistics to be sampled. | 31 | /// How often are statistics to be sampled. |
38 | 30 | #define STATISTICS_SAMPLE_TIME 30000 | 32 | constexpr uint32_t kStatisticsSampleTime = 30000; |
39 | 31 | 33 | ||
40 | 32 | #endif // end of include guard: WL_LOGIC_CONSTANTS_H | 34 | #endif // end of include guard: WL_LOGIC_CONSTANTS_H |
41 | 33 | 35 | ||
42 | === modified file 'src/wui/general_statistics_menu.cc' | |||
43 | --- src/wui/general_statistics_menu.cc 2016-01-29 08:37:22 +0000 | |||
44 | +++ src/wui/general_statistics_menu.cc 2016-06-10 17:28:35 +0000 | |||
45 | @@ -67,7 +67,9 @@ | |||
46 | 67 | 440, 400, _("General Statistics")), | 67 | 440, 400, _("General Statistics")), |
47 | 68 | my_registry_ (®istry), | 68 | my_registry_ (®istry), |
48 | 69 | box_ (this, 0, 0, UI::Box::Vertical, 0, 0, 5), | 69 | box_ (this, 0, 0, UI::Box::Vertical, 0, 0, 5), |
50 | 70 | plot_ (&box_, 0, 0, 430, PLOT_HEIGHT), | 70 | plot_ (&box_, 0, 0, 430, PLOT_HEIGHT, |
51 | 71 | kStatisticsSampleTime, | ||
52 | 72 | WuiPlotArea::Plotmode::kAbsolute), | ||
53 | 71 | selected_information_(0) | 73 | selected_information_(0) |
54 | 72 | { | 74 | { |
55 | 73 | assert (my_registry_); | 75 | assert (my_registry_); |
56 | @@ -78,8 +80,6 @@ | |||
57 | 78 | box_.set_border(5, 5, 5, 5); | 80 | box_.set_border(5, 5, 5, 5); |
58 | 79 | 81 | ||
59 | 80 | // Setup plot data | 82 | // Setup plot data |
60 | 81 | plot_.set_sample_rate(STATISTICS_SAMPLE_TIME); | ||
61 | 82 | plot_.set_plotmode(WuiPlotArea::PLOTMODE_ABSOLUTE); | ||
62 | 83 | Game & game = *parent.get_game(); | 83 | Game & game = *parent.get_game(); |
63 | 84 | const Game::GeneralStatsVector & genstats = | 84 | const Game::GeneralStatsVector & genstats = |
64 | 85 | game.get_general_statistics(); | 85 | game.get_general_statistics(); |
65 | 86 | 86 | ||
66 | === modified file 'src/wui/plot_area.cc' | |||
67 | --- src/wui/plot_area.cc 2016-03-29 17:28:15 +0000 | |||
68 | +++ src/wui/plot_area.cc 2016-06-10 17:28:35 +0000 | |||
69 | @@ -39,24 +39,24 @@ | |||
70 | 39 | 39 | ||
71 | 40 | constexpr int32_t kUpdateTimeInGametimeMs = 1000; // 1 second, gametime | 40 | constexpr int32_t kUpdateTimeInGametimeMs = 1000; // 1 second, gametime |
72 | 41 | 41 | ||
76 | 42 | const uint32_t minutes = 60 * 1000; | 42 | constexpr uint32_t kMinutes = 60 * 1000; |
77 | 43 | const uint32_t hours = 60 * 60 * 1000; | 43 | constexpr uint32_t kHours = 60 * 60 * 1000; |
78 | 44 | const uint32_t days = 24 * 60 * 60 * 1000; | 44 | constexpr uint32_t kDays = 24 * 60 * 60 * 1000; |
79 | 45 | 45 | ||
85 | 46 | const int32_t spacing = 5; | 46 | constexpr int32_t kSpacing = 5; |
86 | 47 | const int32_t space_at_bottom = 20; | 47 | constexpr int32_t kSpaceBottom = 20; |
87 | 48 | const int32_t space_at_right = 10; | 48 | constexpr int32_t kSpaceRight = 10; |
88 | 49 | const int32_t space_left_of_label = 15; | 49 | constexpr int32_t kSpaceLeftOfLabel = 15; |
89 | 50 | const uint32_t nr_samples = 30; // How many samples per diagramm when relative plotting | 50 | constexpr uint32_t KNoSamples = 30; // How many samples per diagramm when relative plotting |
90 | 51 | 51 | ||
91 | 52 | const uint32_t time_in_ms[] = { | 52 | const uint32_t time_in_ms[] = { |
99 | 53 | 15 * minutes, | 53 | 15 * kMinutes, |
100 | 54 | 30 * minutes, | 54 | 30 * kMinutes, |
101 | 55 | 1 * hours, | 55 | 1 * kHours, |
102 | 56 | 2 * hours, | 56 | 2 * kHours, |
103 | 57 | 5 * hours, | 57 | 5 * kHours, |
104 | 58 | 10 * hours, | 58 | 10 * kHours, |
105 | 59 | 30 * hours | 59 | 30 * kHours |
106 | 60 | }; | 60 | }; |
107 | 61 | 61 | ||
108 | 62 | const char BG_PIC[] = "images/wui/plot_area_bg.png"; | 62 | const char BG_PIC[] = "images/wui/plot_area_bg.png"; |
109 | @@ -99,18 +99,18 @@ | |||
110 | 99 | Units get_suggested_unit(uint32_t game_time, bool is_generic = false) { | 99 | Units get_suggested_unit(uint32_t game_time, bool is_generic = false) { |
111 | 100 | // Find a nice unit for max_x | 100 | // Find a nice unit for max_x |
112 | 101 | if (is_generic) { | 101 | if (is_generic) { |
114 | 102 | if (game_time > 4 * days) { | 102 | if (game_time > 4 * kDays) { |
115 | 103 | return Units::kDayGeneric; | 103 | return Units::kDayGeneric; |
117 | 104 | } else if (game_time > 4 * hours) { | 104 | } else if (game_time > 4 * kHours) { |
118 | 105 | return Units::kHourGeneric; | 105 | return Units::kHourGeneric; |
119 | 106 | } else { | 106 | } else { |
120 | 107 | return Units::kMinutesGeneric; | 107 | return Units::kMinutesGeneric; |
121 | 108 | } | 108 | } |
122 | 109 | } | 109 | } |
123 | 110 | else { | 110 | else { |
125 | 111 | if (game_time > 4 * days) { | 111 | if (game_time > 4 * kDays) { |
126 | 112 | return Units::kDayNarrow; | 112 | return Units::kDayNarrow; |
128 | 113 | } else if (game_time > 4 * hours) { | 113 | } else if (game_time > 4 * kHours) { |
129 | 114 | return Units::kHourNarrow; | 114 | return Units::kHourNarrow; |
130 | 115 | } else { | 115 | } else { |
131 | 116 | return Units::kMinutesNarrow; | 116 | return Units::kMinutesNarrow; |
132 | @@ -153,13 +153,13 @@ | |||
133 | 153 | switch (unit) { | 153 | switch (unit) { |
134 | 154 | case Units::kDayGeneric: | 154 | case Units::kDayGeneric: |
135 | 155 | case Units::kDayNarrow: | 155 | case Units::kDayNarrow: |
137 | 156 | return ms / days; | 156 | return ms / kDays; |
138 | 157 | case Units::kHourGeneric: | 157 | case Units::kHourGeneric: |
139 | 158 | case Units::kHourNarrow: | 158 | case Units::kHourNarrow: |
141 | 159 | return ms / hours; | 159 | return ms / kHours; |
142 | 160 | case Units::kMinutesGeneric: | 160 | case Units::kMinutesGeneric: |
143 | 161 | case Units::kMinutesNarrow: | 161 | case Units::kMinutesNarrow: |
145 | 162 | return ms / minutes; | 162 | return ms / kMinutes; |
146 | 163 | } | 163 | } |
147 | 164 | NEVER_HERE(); | 164 | NEVER_HERE(); |
148 | 165 | } | 165 | } |
149 | @@ -167,11 +167,11 @@ | |||
150 | 167 | /** | 167 | /** |
151 | 168 | * calculate how many values are taken together when plot mode is relative | 168 | * calculate how many values are taken together when plot mode is relative |
152 | 169 | */ | 169 | */ |
154 | 170 | int32_t calc_how_many(uint32_t time_ms, int32_t sample_rate) { | 170 | int32_t calc_how_many(uint32_t time_ms, uint32_t sample_rate) { |
155 | 171 | int32_t how_many = static_cast<int32_t> | 171 | int32_t how_many = static_cast<int32_t> |
156 | 172 | ((static_cast<float>(time_ms) | 172 | ((static_cast<float>(time_ms) |
157 | 173 | / | 173 | / |
159 | 174 | static_cast<float>(nr_samples)) | 174 | static_cast<float>(KNoSamples)) |
160 | 175 | / | 175 | / |
161 | 176 | static_cast<float>(sample_rate)); | 176 | static_cast<float>(sample_rate)); |
162 | 177 | 177 | ||
163 | @@ -230,28 +230,28 @@ | |||
164 | 230 | // Draw coordinate system | 230 | // Draw coordinate system |
165 | 231 | // X Axis | 231 | // X Axis |
166 | 232 | dst.draw_line_strip({ | 232 | dst.draw_line_strip({ |
169 | 233 | FloatPoint(spacing, inner_h - space_at_bottom), | 233 | FloatPoint(kSpacing, inner_h - kSpaceBottom), |
170 | 234 | FloatPoint(inner_w - space_at_right, inner_h - space_at_bottom)}, | 234 | FloatPoint(inner_w - kSpaceRight, inner_h - kSpaceBottom)}, |
171 | 235 | kAxisLineColor, kAxisLinesWidth); | 235 | kAxisLineColor, kAxisLinesWidth); |
172 | 236 | // Arrow | 236 | // Arrow |
173 | 237 | dst.draw_line_strip({ | 237 | dst.draw_line_strip({ |
177 | 238 | FloatPoint(spacing + 5, inner_h - space_at_bottom - 3), | 238 | FloatPoint(kSpacing + 5, inner_h - kSpaceBottom - 3), |
178 | 239 | FloatPoint(spacing, inner_h - space_at_bottom), | 239 | FloatPoint(kSpacing, inner_h - kSpaceBottom), |
179 | 240 | FloatPoint(spacing + 5, inner_h - space_at_bottom + 3), | 240 | FloatPoint(kSpacing + 5, inner_h - kSpaceBottom + 3), |
180 | 241 | }, kAxisLineColor, kAxisLinesWidth); | 241 | }, kAxisLineColor, kAxisLinesWidth); |
181 | 242 | 242 | ||
182 | 243 | // Y Axis | 243 | // Y Axis |
185 | 244 | dst.draw_line_strip({FloatPoint(inner_w - space_at_right, spacing), | 244 | dst.draw_line_strip({FloatPoint(inner_w - kSpaceRight, kSpacing), |
186 | 245 | FloatPoint(inner_w - space_at_right, inner_h - space_at_bottom)}, | 245 | FloatPoint(inner_w - kSpaceRight, inner_h - kSpaceBottom)}, |
187 | 246 | kAxisLineColor, kAxisLinesWidth); | 246 | kAxisLineColor, kAxisLinesWidth); |
188 | 247 | // No Arrow here, since this doesn't continue. | 247 | // No Arrow here, since this doesn't continue. |
189 | 248 | 248 | ||
192 | 249 | float sub = (xline_length - space_left_of_label) / how_many_ticks; | 249 | float sub = (xline_length - kSpaceLeftOfLabel) / how_many_ticks; |
193 | 250 | float posx = inner_w - space_at_right; | 250 | float posx = inner_w - kSpaceRight; |
194 | 251 | 251 | ||
195 | 252 | for (uint32_t i = 0; i <= how_many_ticks; ++i) { | 252 | for (uint32_t i = 0; i <= how_many_ticks; ++i) { |
198 | 253 | dst.draw_line_strip({FloatPoint(static_cast<int32_t>(posx), inner_h - space_at_bottom), | 253 | dst.draw_line_strip({FloatPoint(static_cast<int32_t>(posx), inner_h - kSpaceBottom), |
199 | 254 | FloatPoint(static_cast<int32_t>(posx), inner_h - space_at_bottom + 3)}, | 254 | FloatPoint(static_cast<int32_t>(posx), inner_h - kSpaceBottom + 3)}, |
200 | 255 | kAxisLineColor, kAxisLinesWidth); | 255 | kAxisLineColor, kAxisLinesWidth); |
201 | 256 | 256 | ||
202 | 257 | // The space at the end is intentional to have the tick centered | 257 | // The space at the end is intentional to have the tick centered |
203 | @@ -259,7 +259,7 @@ | |||
204 | 259 | const Image* xtick = UI::g_fh1->render | 259 | const Image* xtick = UI::g_fh1->render |
205 | 260 | (xtick_text_style((boost::format("-%u ") % (max_x / how_many_ticks * i)).str())); | 260 | (xtick_text_style((boost::format("-%u ") % (max_x / how_many_ticks * i)).str())); |
206 | 261 | dst.blit | 261 | dst.blit |
208 | 262 | (Point(static_cast<int32_t>(posx), inner_h - space_at_bottom + 10), | 262 | (Point(static_cast<int32_t>(posx), inner_h - kSpaceBottom + 10), |
209 | 263 | xtick, BlendMode::UseAlpha, UI::Align::kCenter); | 263 | xtick, BlendMode::UseAlpha, UI::Align::kCenter); |
210 | 264 | 264 | ||
211 | 265 | posx -= sub; | 265 | posx -= sub; |
212 | @@ -267,29 +267,32 @@ | |||
213 | 267 | 267 | ||
214 | 268 | // draw yticks, one at full, one at half | 268 | // draw yticks, one at full, one at half |
215 | 269 | dst.draw_line_strip({ | 269 | dst.draw_line_strip({ |
217 | 270 | FloatPoint(inner_w - space_at_right, spacing), FloatPoint(inner_w - space_at_right - 3, spacing)}, | 270 | FloatPoint(inner_w - kSpaceRight, kSpacing), FloatPoint(inner_w - kSpaceRight - 3, kSpacing)}, |
218 | 271 | kAxisLineColor, kAxisLinesWidth); | 271 | kAxisLineColor, kAxisLinesWidth); |
219 | 272 | dst.draw_line_strip({ | 272 | dst.draw_line_strip({ |
222 | 273 | FloatPoint(inner_w - space_at_right, spacing + ((inner_h - space_at_bottom) - spacing) / 2), | 273 | FloatPoint(inner_w - kSpaceRight, kSpacing + ((inner_h - kSpaceBottom) - kSpacing) / 2), |
223 | 274 | FloatPoint(inner_w - space_at_right - 3, spacing + ((inner_h - space_at_bottom) - spacing) / 2)}, | 274 | FloatPoint(inner_w - kSpaceRight - 3, kSpacing + ((inner_h - kSpaceBottom) - kSpacing) / 2)}, |
224 | 275 | kAxisLineColor, kAxisLinesWidth); | 275 | kAxisLineColor, kAxisLinesWidth); |
225 | 276 | 276 | ||
226 | 277 | // print the used unit | 277 | // print the used unit |
227 | 278 | const Image* xtick = UI::g_fh1->render(xtick_text_style(get_generic_unit_name(unit))); | 278 | const Image* xtick = UI::g_fh1->render(xtick_text_style(get_generic_unit_name(unit))); |
229 | 279 | dst.blit(Point(2, spacing + 2), xtick, BlendMode::UseAlpha, UI::Align::kCenterLeft); | 279 | dst.blit(Point(2, kSpacing + 2), xtick, BlendMode::UseAlpha, UI::Align::kCenterLeft); |
230 | 280 | } | 280 | } |
231 | 281 | 281 | ||
232 | 282 | } // namespace | 282 | } // namespace |
233 | 283 | 283 | ||
234 | 284 | WuiPlotArea::WuiPlotArea | 284 | WuiPlotArea::WuiPlotArea |
235 | 285 | (UI::Panel * const parent, | 285 | (UI::Panel * const parent, |
237 | 286 | int32_t const x, int32_t const y, int32_t const w, int32_t const h) | 286 | int32_t const x, int32_t const y, int32_t const w, int32_t const h, |
238 | 287 | uint32_t sample_rate, Plotmode plotmode) | ||
239 | 287 | : | 288 | : |
240 | 288 | UI::Panel (parent, x, y, w, h), | 289 | UI::Panel (parent, x, y, w, h), |
243 | 289 | plotmode_(PLOTMODE_ABSOLUTE), | 290 | plotmode_(plotmode), |
244 | 290 | sample_rate_(0), | 291 | sample_rate_(sample_rate), |
245 | 291 | needs_update_(true), | 292 | needs_update_(true), |
246 | 292 | lastupdate_(0), | 293 | lastupdate_(0), |
247 | 294 | xline_length_(get_inner_w() - kSpaceRight - kSpacing), | ||
248 | 295 | yline_length_(get_inner_h() - kSpaceBottom - kSpacing), | ||
249 | 293 | time_ms_(0), | 296 | time_ms_(0), |
250 | 294 | highest_scale_(0), | 297 | highest_scale_(0), |
251 | 295 | sub_(0.0f), | 298 | sub_(0.0f), |
252 | @@ -300,19 +303,19 @@ | |||
253 | 300 | } | 303 | } |
254 | 301 | 304 | ||
255 | 302 | 305 | ||
257 | 303 | uint32_t WuiPlotArea::get_game_time() { | 306 | uint32_t WuiPlotArea::get_game_time() const { |
258 | 304 | uint32_t game_time = 0; | 307 | uint32_t game_time = 0; |
259 | 305 | 308 | ||
260 | 306 | // Find running time of the game, based on the plot data | 309 | // Find running time of the game, based on the plot data |
261 | 307 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) | 310 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) |
264 | 308 | if (game_time < plotdata_[plot].dataset->size() * sample_rate_) | 311 | if (game_time < plotdata_[plot].absolute_data->size() * sample_rate_) |
265 | 309 | game_time = plotdata_[plot].dataset->size() * sample_rate_; | 312 | game_time = plotdata_[plot].absolute_data->size() * sample_rate_; |
266 | 310 | return game_time; | 313 | return game_time; |
267 | 311 | } | 314 | } |
268 | 312 | 315 | ||
270 | 313 | std::vector<std::string> WuiPlotArea::get_labels() { | 316 | std::vector<std::string> WuiPlotArea::get_labels() const { |
271 | 314 | std::vector<std::string> labels; | 317 | std::vector<std::string> labels; |
273 | 315 | for (int32_t i = 0; i < game_time_id_; i++) { | 318 | for (uint32_t i = 0; i < game_time_id_; i++) { |
274 | 316 | Units unit = get_suggested_unit(time_in_ms[i], false); | 319 | Units unit = get_suggested_unit(time_in_ms[i], false); |
275 | 317 | labels.push_back(get_value_with_unit(unit, ms_to_unit(unit, time_in_ms[i]))); | 320 | labels.push_back(get_value_with_unit(unit, ms_to_unit(unit, time_in_ms[i]))); |
276 | 318 | } | 321 | } |
277 | @@ -320,7 +323,7 @@ | |||
278 | 320 | return labels; | 323 | return labels; |
279 | 321 | } | 324 | } |
280 | 322 | 325 | ||
282 | 323 | uint32_t WuiPlotArea::get_plot_time() { | 326 | uint32_t WuiPlotArea::get_plot_time() const { |
283 | 324 | if (time_ == TIME_GAME) { | 327 | if (time_ == TIME_GAME) { |
284 | 325 | // Start with the game time | 328 | // Start with the game time |
285 | 326 | uint32_t time_ms = get_game_time(); | 329 | uint32_t time_ms = get_game_time(); |
286 | @@ -331,14 +334,14 @@ | |||
287 | 331 | // or a multiple of 2h | 334 | // or a multiple of 2h |
288 | 332 | // or a multiple of 20h | 335 | // or a multiple of 20h |
289 | 333 | // or a multiple of 4 days | 336 | // or a multiple of 4 days |
296 | 334 | if (time_ms > 8 * days) { | 337 | if (time_ms > 8 * kDays) { |
297 | 335 | time_ms += - (time_ms % (4 * days)) + 4 * days; | 338 | time_ms += - (time_ms % (4 * kDays)) + 4 * kDays; |
298 | 336 | } else if (time_ms > 40 * hours) { | 339 | } else if (time_ms > 40 * kHours) { |
299 | 337 | time_ms += - (time_ms % (20 * hours)) + 20 * hours; | 340 | time_ms += - (time_ms % (20 * kHours)) + 20 * kHours; |
300 | 338 | } else if (time_ms > 4 * hours) { | 341 | } else if (time_ms > 4 * kHours) { |
301 | 339 | time_ms += - (time_ms % (2 * hours)) + 2 * hours; | 342 | time_ms += - (time_ms % (2 * kHours)) + 2 * kHours; |
302 | 340 | } else { | 343 | } else { |
304 | 341 | time_ms += - (time_ms % (15 * minutes)) + 15 * minutes; | 344 | time_ms += - (time_ms % (15 * kMinutes)) + 15 * kMinutes; |
305 | 342 | } | 345 | } |
306 | 343 | return time_ms; | 346 | return time_ms; |
307 | 344 | } else { | 347 | } else { |
308 | @@ -356,7 +359,7 @@ | |||
309 | 356 | * We start to search with i=1 to ensure that at least one option besides | 359 | * We start to search with i=1 to ensure that at least one option besides |
310 | 357 | * "game" will be offered to the user. | 360 | * "game" will be offered to the user. |
311 | 358 | */ | 361 | */ |
313 | 359 | int32_t WuiPlotArea::get_game_time_id() { | 362 | uint32_t WuiPlotArea::get_game_time_id() { |
314 | 360 | uint32_t game_time = get_game_time(); | 363 | uint32_t game_time = get_game_time(); |
315 | 361 | uint32_t i; | 364 | uint32_t i; |
316 | 362 | for (i = 1; i < 7 && time_in_ms[i] <= game_time; i++) { | 365 | for (i = 1; i < 7 && time_in_ms[i] <= game_time; i++) { |
317 | @@ -376,29 +379,47 @@ | |||
318 | 376 | needs_update_ = false; | 379 | needs_update_ = false; |
319 | 377 | } | 380 | } |
320 | 378 | 381 | ||
321 | 382 | int32_t WuiPlotArea::initialize_update() { | ||
322 | 383 | // Initialize | ||
323 | 384 | for (uint32_t i = 0; i < plotdata_.size(); ++i) { | ||
324 | 385 | plotdata_[i].relative_data->clear(); | ||
325 | 386 | } | ||
326 | 387 | // Get range | ||
327 | 388 | time_ms_ = get_plot_time(); | ||
328 | 389 | if (plotmode_ == Plotmode::kAbsolute) { | ||
329 | 390 | sub_ = | ||
330 | 391 | (xline_length_ - kSpaceLeftOfLabel) | ||
331 | 392 | / | ||
332 | 393 | (static_cast<float>(time_ms_) | ||
333 | 394 | / | ||
334 | 395 | static_cast<float>(sample_rate_)); | ||
335 | 396 | } else { | ||
336 | 397 | sub_ = (xline_length_ - kSpaceLeftOfLabel) / static_cast<float>(KNoSamples); | ||
337 | 398 | } | ||
338 | 399 | |||
339 | 400 | // How many do we aggregate when relative plotting | ||
340 | 401 | return calc_how_many(time_ms_, sample_rate_); | ||
341 | 402 | } | ||
342 | 379 | 403 | ||
343 | 380 | // Find the maximum value. | 404 | // Find the maximum value. |
344 | 381 | void WuiPlotArea::update() { | 405 | void WuiPlotArea::update() { |
351 | 382 | float const xline_length = get_inner_w() - space_at_right - spacing; | 406 | const int32_t how_many = initialize_update(); |
352 | 383 | 407 | ||
353 | 384 | time_ms_ = get_plot_time(); | 408 | // Calculate highest scale |
348 | 385 | |||
349 | 386 | // How many do we take together when relative ploting | ||
350 | 387 | const int32_t how_many = calc_how_many(time_ms_, sample_rate_); | ||
354 | 388 | highest_scale_ = 0; | 409 | highest_scale_ = 0; |
356 | 389 | if (plotmode_ == PLOTMODE_ABSOLUTE) { | 410 | if (plotmode_ == Plotmode::kAbsolute) { |
357 | 390 | for (uint32_t i = 0; i < plotdata_.size(); ++i) | 411 | for (uint32_t i = 0; i < plotdata_.size(); ++i) |
358 | 391 | if (plotdata_[i].showplot) { | 412 | if (plotdata_[i].showplot) { |
362 | 392 | for (uint32_t l = 0; l < plotdata_[i].dataset->size(); ++l) | 413 | for (uint32_t l = 0; l < plotdata_[i].absolute_data->size(); ++l) { |
363 | 393 | if (highest_scale_ < (*plotdata_[i].dataset)[l]) | 414 | if (highest_scale_ < (*plotdata_[i].absolute_data)[l]) { |
364 | 394 | highest_scale_ = (*plotdata_[i].dataset)[l]; | 415 | highest_scale_ = (*plotdata_[i].absolute_data)[l]; |
365 | 416 | } | ||
366 | 417 | } | ||
367 | 395 | } | 418 | } |
368 | 396 | } else { | 419 | } else { |
369 | 397 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) { | 420 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) { |
370 | 398 | if (plotdata_[plot].showplot) { | 421 | if (plotdata_[plot].showplot) { |
374 | 399 | 422 | const std::vector<uint32_t> & dataset = *plotdata_[plot].absolute_data; | |
372 | 400 | const std::vector<uint32_t> & dataset = *plotdata_[plot].dataset; | ||
373 | 401 | |||
375 | 402 | uint32_t add = 0; | 423 | uint32_t add = 0; |
376 | 403 | // Relative data, first entry is always zero. | 424 | // Relative data, first entry is always zero. |
377 | 404 | for (uint32_t i = 0; i < dataset.size(); ++i) { | 425 | for (uint32_t i = 0; i < dataset.size(); ++i) { |
378 | @@ -413,31 +434,21 @@ | |||
379 | 413 | } | 434 | } |
380 | 414 | } | 435 | } |
381 | 415 | 436 | ||
395 | 416 | // Update the datasets | 437 | // Calculate plot data |
396 | 417 | sub_ = | 438 | if (plotmode_ == Plotmode::kRelative) { |
397 | 418 | (xline_length - space_left_of_label) | 439 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) { |
398 | 419 | / | 440 | if (plotdata_[plot].showplot) { |
399 | 420 | (static_cast<float>(time_ms_) | 441 | std::vector<uint32_t> const * dataset = plotdata_[plot].absolute_data; |
387 | 421 | / | ||
388 | 422 | static_cast<float>(sample_rate_)); | ||
389 | 423 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) { | ||
390 | 424 | if (plotdata_[plot].showplot) { | ||
391 | 425 | std::vector<uint32_t> const * dataset = plotdata_[plot].dataset; | ||
392 | 426 | |||
393 | 427 | std::vector<uint32_t> data; | ||
394 | 428 | if (plotmode_ == PLOTMODE_RELATIVE) { | ||
400 | 429 | uint32_t add = 0; | 442 | uint32_t add = 0; |
401 | 430 | // Relative data, first entry is always zero | 443 | // Relative data, first entry is always zero |
403 | 431 | data.push_back(0); | 444 | plotdata_[plot].relative_data->push_back(0); |
404 | 432 | for (uint32_t i = 0; i < dataset->size(); ++i) { | 445 | for (uint32_t i = 0; i < dataset->size(); ++i) { |
405 | 433 | add += (*dataset)[i]; | 446 | add += (*dataset)[i]; |
406 | 434 | if (0 == ((i + 1) % how_many)) { | 447 | if (0 == ((i + 1) % how_many)) { |
408 | 435 | data.push_back(add); | 448 | plotdata_[plot].relative_data->push_back(add); |
409 | 436 | add = 0; | 449 | add = 0; |
410 | 437 | } | 450 | } |
411 | 438 | } | 451 | } |
412 | 439 | dataset = &data; | ||
413 | 440 | sub_ = (xline_length - space_left_of_label) / static_cast<float>(nr_samples); | ||
414 | 441 | } | 452 | } |
415 | 442 | } | 453 | } |
416 | 443 | } | 454 | } |
417 | @@ -449,23 +460,26 @@ | |||
418 | 449 | * Draw this. This is the main function | 460 | * Draw this. This is the main function |
419 | 450 | */ | 461 | */ |
420 | 451 | void WuiPlotArea::draw(RenderTarget & dst) { | 462 | void WuiPlotArea::draw(RenderTarget & dst) { |
423 | 452 | float const xline_length = get_inner_w() - space_at_right - spacing; | 463 | draw_plot(dst, get_inner_h() - kSpaceBottom, std::to_string(highest_scale_), highest_scale_); |
424 | 453 | float const yline_length = get_inner_h() - space_at_bottom - spacing; | 464 | } |
425 | 454 | 465 | ||
427 | 455 | draw_diagram(time_ms_, get_inner_w(), get_inner_h(), xline_length, dst); | 466 | void WuiPlotArea::draw_plot(RenderTarget& dst, float yoffset, const std::string& yscale_label, |
428 | 467 | uint32_t highest_scale) { | ||
429 | 468 | draw_diagram(time_ms_, get_inner_w(), get_inner_h(), xline_length_, dst); | ||
430 | 456 | 469 | ||
431 | 457 | // print the maximal value into the top right corner | 470 | // print the maximal value into the top right corner |
432 | 458 | draw_value | 471 | draw_value |
435 | 459 | (std::to_string(highest_scale_), RGBColor(60, 125, 0), | 472 | (yscale_label, RGBColor(60, 125, 0), |
436 | 460 | Point(get_inner_w() - space_at_right - 2, spacing + 2), dst); | 473 | Point(get_inner_w() - kSpaceRight - 2, kSpacing + 2), dst); |
437 | 461 | 474 | ||
438 | 462 | // plot the pixels | 475 | // plot the pixels |
439 | 463 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) { | 476 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) { |
440 | 464 | if (plotdata_[plot].showplot) { | 477 | if (plotdata_[plot].showplot) { |
441 | 465 | RGBColor color = plotdata_[plot].plotcolor; | ||
442 | 466 | std::vector<uint32_t> const * dataset = plotdata_[plot].dataset; | ||
443 | 467 | draw_plot_line | 478 | draw_plot_line |
445 | 468 | (dst, dataset, yline_length, highest_scale_, sub_, color, get_inner_h() - space_at_bottom); | 479 | (dst, |
446 | 480 | (plotmode_ == Plotmode::kRelative) ? | ||
447 | 481 | plotdata_[plot].relative_data : plotdata_[plot].absolute_data, | ||
448 | 482 | highest_scale, sub_, plotdata_[plot].plotcolor, yoffset); | ||
449 | 469 | } | 483 | } |
450 | 470 | } | 484 | } |
451 | 471 | } | 485 | } |
452 | @@ -476,34 +490,37 @@ | |||
453 | 476 | * \param sub horizontal difference between 2 y values | 490 | * \param sub horizontal difference between 2 y values |
454 | 477 | */ | 491 | */ |
455 | 478 | void WuiPlotArea::draw_plot_line | 492 | void WuiPlotArea::draw_plot_line |
457 | 479 | (RenderTarget & dst, std::vector<uint32_t> const * dataset, float const yline_length, | 493 | (RenderTarget & dst, std::vector<uint32_t> const * dataset, |
458 | 480 | uint32_t const highest_scale, float const sub, RGBColor const color, int32_t const yoffset) | 494 | uint32_t const highest_scale, float const sub, RGBColor const color, int32_t const yoffset) |
459 | 481 | { | 495 | { |
485 | 482 | float posx = get_inner_w() - space_at_right; | 496 | if (!dataset->empty()) { |
486 | 483 | const int lx = get_inner_w() - space_at_right; | 497 | float posx = get_inner_w() - kSpaceRight; |
487 | 484 | int ly = yoffset; | 498 | const int lx = get_inner_w() - kSpaceRight; |
488 | 485 | // Init start point of the plot line with the first data value. | 499 | int ly = yoffset; |
489 | 486 | // This prevents that the plot starts always at zero | 500 | // Init start point of the plot line with the first data value. |
490 | 487 | if (int value = (*dataset)[dataset->size() - 1]) { | 501 | // This prevents that the plot starts always at zero |
491 | 488 | ly -= static_cast<int32_t>(scale_value(yline_length, highest_scale, value)); | 502 | |
492 | 489 | } | 503 | if (int value = (*dataset)[dataset->size() - 1]) { |
493 | 490 | 504 | ly -= static_cast<int32_t>(scale_value(yline_length_, highest_scale, value)); | |
494 | 491 | std::vector<FloatPoint> points; | 505 | } |
495 | 492 | points.emplace_back(lx, ly); | 506 | |
496 | 493 | 507 | std::vector<FloatPoint> points; | |
497 | 494 | for (int32_t i = dataset->size() - 1; i > 0 && posx > spacing; --i) { | 508 | points.emplace_back(lx, ly); |
498 | 495 | int32_t const curx = static_cast<int32_t>(posx); | 509 | |
499 | 496 | int32_t cury = yoffset; | 510 | for (int32_t i = dataset->size() - 1; i > 0 && posx > kSpacing; --i) { |
500 | 497 | 511 | int32_t const curx = static_cast<int32_t>(posx); | |
501 | 498 | // Scale the line to the available space | 512 | int32_t cury = yoffset; |
502 | 499 | if (int32_t value = (*dataset)[i]) { | 513 | |
503 | 500 | const float length_y = scale_value(yline_length, highest_scale, value); | 514 | // Scale the line to the available space |
504 | 501 | cury -= static_cast<int32_t>(length_y); | 515 | if (int32_t value = (*dataset)[i]) { |
505 | 502 | } | 516 | const float length_y = scale_value(yline_length_, highest_scale, value); |
506 | 503 | points.emplace_back(curx, cury); | 517 | cury -= static_cast<int32_t>(length_y); |
507 | 504 | posx -= sub; | 518 | } |
508 | 505 | } | 519 | points.emplace_back(curx, cury); |
509 | 506 | dst.draw_line_strip(points, color, kPlotLinesWidth); | 520 | posx -= sub; |
510 | 521 | } | ||
511 | 522 | dst.draw_line_strip(points, color, kPlotLinesWidth); | ||
512 | 523 | } | ||
513 | 507 | } | 524 | } |
514 | 508 | 525 | ||
515 | 509 | /* | 526 | /* |
516 | @@ -517,7 +534,8 @@ | |||
517 | 517 | if (id >= plotdata_.size()) | 534 | if (id >= plotdata_.size()) |
518 | 518 | plotdata_.resize(id + 1); | 535 | plotdata_.resize(id + 1); |
519 | 519 | 536 | ||
521 | 520 | plotdata_[id].dataset = data; | 537 | plotdata_[id].absolute_data = data; |
522 | 538 | plotdata_[id].relative_data = new std::vector<uint32_t>(); // Will be filled in the update() function. | ||
523 | 521 | plotdata_[id].showplot = false; | 539 | plotdata_[id].showplot = false; |
524 | 522 | plotdata_[id].plotcolor = color; | 540 | plotdata_[id].plotcolor = color; |
525 | 523 | 541 | ||
526 | @@ -544,17 +562,9 @@ | |||
527 | 544 | needs_update_ = true; | 562 | needs_update_ = true; |
528 | 545 | } | 563 | } |
529 | 546 | 564 | ||
530 | 547 | /* | ||
531 | 548 | * Set sample rate the data uses | ||
532 | 549 | */ | ||
533 | 550 | void WuiPlotArea::set_sample_rate(uint32_t const id) { | ||
534 | 551 | sample_rate_ = id; | ||
535 | 552 | needs_update_ = true; | ||
536 | 553 | } | ||
537 | 554 | |||
538 | 555 | 565 | ||
539 | 556 | void WuiPlotAreaSlider::draw(RenderTarget & dst) { | 566 | void WuiPlotAreaSlider::draw(RenderTarget & dst) { |
541 | 557 | int32_t new_game_time_id = plot_area_.get_game_time_id(); | 567 | uint32_t new_game_time_id = plot_area_.get_game_time_id(); |
542 | 558 | if (new_game_time_id != last_game_time_id_) { | 568 | if (new_game_time_id != last_game_time_id_) { |
543 | 559 | last_game_time_id_ = new_game_time_id; | 569 | last_game_time_id_ = new_game_time_id; |
544 | 560 | set_labels(plot_area_.get_labels()); | 570 | set_labels(plot_area_.get_labels()); |
545 | @@ -565,31 +575,27 @@ | |||
546 | 565 | 575 | ||
547 | 566 | DifferentialPlotArea::DifferentialPlotArea | 576 | DifferentialPlotArea::DifferentialPlotArea |
548 | 567 | (UI::Panel * const parent, | 577 | (UI::Panel * const parent, |
550 | 568 | int32_t const x, int32_t const y, int32_t const w, int32_t const h) | 578 | int32_t const x, int32_t const y, int32_t const w, int32_t const h, |
551 | 579 | uint32_t sample_rate, Plotmode plotmode) | ||
552 | 569 | : | 580 | : |
554 | 570 | WuiPlotArea (parent, x, y, w, h) | 581 | WuiPlotArea (parent, x, y, w, h, sample_rate, plotmode) |
555 | 571 | { | 582 | { |
556 | 572 | update(); | 583 | update(); |
557 | 573 | } | 584 | } |
558 | 574 | 585 | ||
559 | 575 | void DifferentialPlotArea::update() { | 586 | void DifferentialPlotArea::update() { |
568 | 576 | float const xline_length = get_inner_w() - space_at_right - spacing; | 587 | const int32_t how_many = initialize_update(); |
569 | 577 | 588 | ||
570 | 578 | time_ms_ = get_plot_time(); | 589 | // Calculate highest scale |
563 | 579 | |||
564 | 580 | // How many do we take together when relative ploting | ||
565 | 581 | const int32_t how_many = calc_how_many(time_ms_, sample_rate_); | ||
566 | 582 | |||
567 | 583 | // Find max and min value | ||
571 | 584 | int32_t max = 0; | 590 | int32_t max = 0; |
572 | 585 | int32_t min = 0; | 591 | int32_t min = 0; |
573 | 586 | 592 | ||
575 | 587 | if (plotmode_ == PLOTMODE_ABSOLUTE) { | 593 | if (plotmode_ == Plotmode::kAbsolute) { |
576 | 588 | for (uint32_t i = 0; i < plotdata_.size(); ++i) | 594 | for (uint32_t i = 0; i < plotdata_.size(); ++i) |
577 | 589 | if (plotdata_[i].showplot) { | 595 | if (plotdata_[i].showplot) { |
581 | 590 | for (uint32_t l = 0; l < plotdata_[i].dataset->size(); ++l) { | 596 | for (uint32_t l = 0; l < plotdata_[i].absolute_data->size(); ++l) { |
582 | 591 | int32_t temp = (*plotdata_[i].dataset)[l] - | 597 | int32_t temp = (*plotdata_[i].absolute_data)[l] - |
583 | 592 | (*negative_plotdata_[i].dataset)[l]; | 598 | (*negative_plotdata_[i].absolute_data)[l]; |
584 | 593 | if (max < temp) max = temp; | 599 | if (max < temp) max = temp; |
585 | 594 | if (min > temp) min = temp; | 600 | if (min > temp) min = temp; |
586 | 595 | } | 601 | } |
587 | @@ -598,8 +604,8 @@ | |||
588 | 598 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) | 604 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) |
589 | 599 | if (plotdata_[plot].showplot) { | 605 | if (plotdata_[plot].showplot) { |
590 | 600 | 606 | ||
593 | 601 | const std::vector<uint32_t> & dataset = *plotdata_[plot].dataset; | 607 | const std::vector<uint32_t> & dataset = *plotdata_[plot].absolute_data; |
594 | 602 | const std::vector<uint32_t> & ndataset = *negative_plotdata_[plot].dataset; | 608 | const std::vector<uint32_t> & ndataset = *negative_plotdata_[plot].absolute_data; |
595 | 603 | 609 | ||
596 | 604 | int32_t add = 0; | 610 | int32_t add = 0; |
597 | 605 | // Relative data, first entry is always zero. | 611 | // Relative data, first entry is always zero. |
598 | @@ -616,77 +622,43 @@ | |||
599 | 616 | 622 | ||
600 | 617 | // Use equal positive and negative range | 623 | // Use equal positive and negative range |
601 | 618 | min = abs(min); | 624 | min = abs(min); |
624 | 619 | highest_scale_ = 0; | 625 | highest_scale_ = (min > max) ? min : max; |
625 | 620 | if (min > max) { | 626 | |
626 | 621 | highest_scale_ = min; | 627 | // Calculate plot data |
627 | 622 | } else { | 628 | if (plotmode_ == Plotmode::kRelative) { |
628 | 623 | highest_scale_ = max; | 629 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) { |
629 | 624 | } | 630 | if (plotdata_[plot].showplot) { |
630 | 625 | 631 | std::vector<uint32_t> const * dataset = plotdata_[plot].absolute_data; | |
631 | 626 | // plot the pixels | 632 | std::vector<uint32_t> const * ndataset = negative_plotdata_[plot].absolute_data; |
632 | 627 | sub_ = | 633 | uint32_t add = 0; |
611 | 628 | xline_length | ||
612 | 629 | / | ||
613 | 630 | (static_cast<float>(time_ms_) | ||
614 | 631 | / | ||
615 | 632 | static_cast<float>(sample_rate_)); | ||
616 | 633 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) | ||
617 | 634 | if (plotdata_[plot].showplot) { | ||
618 | 635 | std::vector<uint32_t> const * dataset = plotdata_[plot].dataset; | ||
619 | 636 | std::vector<uint32_t> const * ndataset = negative_plotdata_[plot].dataset; | ||
620 | 637 | |||
621 | 638 | std::vector<uint32_t> data_; | ||
622 | 639 | if (plotmode_ == PLOTMODE_RELATIVE) { | ||
623 | 640 | int32_t add = 0; | ||
633 | 641 | // Relative data, first entry is always zero | 634 | // Relative data, first entry is always zero |
635 | 642 | data_.push_back(0); | 635 | plotdata_[plot].relative_data->push_back(0); |
636 | 643 | for (uint32_t i = 0; i < dataset->size(); ++i) { | 636 | for (uint32_t i = 0; i < dataset->size(); ++i) { |
637 | 644 | add += (*dataset)[i] - (*ndataset)[i]; | 637 | add += (*dataset)[i] - (*ndataset)[i]; |
638 | 645 | if (0 == ((i + 1) % how_many)) { | 638 | if (0 == ((i + 1) % how_many)) { |
640 | 646 | data_.push_back(add); | 639 | plotdata_[plot].relative_data->push_back(add); |
641 | 647 | add = 0; | 640 | add = 0; |
642 | 648 | } | 641 | } |
643 | 649 | } | 642 | } |
644 | 650 | dataset = &data_; | ||
645 | 651 | sub_ = xline_length / static_cast<float>(nr_samples); | ||
646 | 652 | } | 643 | } |
647 | 653 | } | 644 | } |
648 | 645 | } | ||
649 | 654 | } | 646 | } |
650 | 655 | 647 | ||
651 | 656 | void DifferentialPlotArea::draw(RenderTarget & dst) { | 648 | void DifferentialPlotArea::draw(RenderTarget & dst) { |
652 | 657 | float const xline_length = get_inner_w() - space_at_right - spacing; | ||
653 | 658 | float const yline_length = get_inner_h() - space_at_bottom - spacing; | ||
654 | 659 | // yoffset of the zero line | 649 | // yoffset of the zero line |
656 | 660 | float const yoffset = spacing + ((get_inner_h() - space_at_bottom) - spacing) / 2; | 650 | float const yoffset = kSpacing + ((get_inner_h() - kSpaceBottom) - kSpacing) / 2; |
657 | 651 | draw_plot(dst, yoffset, std::to_string(highest_scale_), 2 * highest_scale_); | ||
658 | 661 | 652 | ||
661 | 662 | time_ms_ = get_plot_time(); | 653 | // Print the min value |
662 | 663 | draw_diagram(time_ms_, get_inner_w(), get_inner_h(), xline_length, dst); | 654 | draw_value |
663 | 655 | ((boost::format("-%u") % (highest_scale_)).str(), RGBColor(125, 0, 0), | ||
664 | 656 | Point(get_inner_w() - kSpaceRight - 2, get_inner_h() - kSpacing - 15), dst); | ||
665 | 664 | 657 | ||
666 | 665 | // draw zero line | 658 | // draw zero line |
669 | 666 | dst.draw_line_strip({FloatPoint(get_inner_w() - space_at_right, yoffset), | 659 | dst.draw_line_strip({FloatPoint(get_inner_w() - kSpaceRight, yoffset), |
670 | 667 | FloatPoint(get_inner_w() - space_at_right - xline_length, yoffset)}, | 660 | FloatPoint(get_inner_w() - kSpaceRight - xline_length_, yoffset)}, |
671 | 668 | kZeroLineColor, kPlotLinesWidth); | 661 | kZeroLineColor, kPlotLinesWidth); |
672 | 669 | |||
673 | 670 | // Print the min and max values | ||
674 | 671 | draw_value | ||
675 | 672 | (std::to_string(highest_scale_), RGBColor(60, 125, 0), | ||
676 | 673 | Point(get_inner_w() - space_at_right - 2, spacing + 2), dst); | ||
677 | 674 | |||
678 | 675 | draw_value | ||
679 | 676 | ((boost::format("-%u") % highest_scale_).str(), RGBColor(125, 0, 0), | ||
680 | 677 | Point(get_inner_w() - space_at_right - 2, get_inner_h() - spacing - 15), dst); | ||
681 | 678 | |||
682 | 679 | // plot the pixels | ||
683 | 680 | for (uint32_t plot = 0; plot < plotdata_.size(); ++plot) | ||
684 | 681 | if (plotdata_[plot].showplot) { | ||
685 | 682 | |||
686 | 683 | RGBColor color = plotdata_[plot].plotcolor; | ||
687 | 684 | std::vector<uint32_t> const * dataset = plotdata_[plot].dataset; | ||
688 | 685 | |||
689 | 686 | // Highest_scale represent the space between zero line and top. | ||
690 | 687 | // -> half of the whole differential plot area | ||
691 | 688 | draw_plot_line(dst, dataset, yline_length, highest_scale_ * 2, sub_, color, yoffset); | ||
692 | 689 | } | ||
693 | 690 | } | 662 | } |
694 | 691 | 663 | ||
695 | 692 | /** | 664 | /** |
696 | @@ -696,9 +668,10 @@ | |||
697 | 696 | void DifferentialPlotArea::register_negative_plot_data | 668 | void DifferentialPlotArea::register_negative_plot_data |
698 | 697 | (uint32_t const id, std::vector<uint32_t> const * const data) { | 669 | (uint32_t const id, std::vector<uint32_t> const * const data) { |
699 | 698 | 670 | ||
701 | 699 | if (id >= negative_plotdata_.size()) | 671 | if (id >= negative_plotdata_.size()) { |
702 | 700 | negative_plotdata_.resize(id + 1); | 672 | negative_plotdata_.resize(id + 1); |
703 | 673 | } | ||
704 | 701 | 674 | ||
706 | 702 | negative_plotdata_[id].dataset = data; | 675 | negative_plotdata_[id].absolute_data = data; |
707 | 703 | needs_update_ = true; | 676 | needs_update_ = true; |
708 | 704 | } | 677 | } |
709 | 705 | 678 | ||
710 | === modified file 'src/wui/plot_area.h' | |||
711 | --- src/wui/plot_area.h 2016-03-19 17:30:37 +0000 | |||
712 | +++ src/wui/plot_area.h 2016-06-10 17:28:35 +0000 | |||
713 | @@ -44,16 +44,17 @@ | |||
714 | 44 | TIME_16_HOURS, | 44 | TIME_16_HOURS, |
715 | 45 | TIME_GAME, | 45 | TIME_GAME, |
716 | 46 | }; | 46 | }; |
723 | 47 | enum PLOTMODE { | 47 | enum class Plotmode { |
724 | 48 | // Always take the samples of some times together, so that the graph is | 48 | // Always aggregate the samples of some time periods, so that the graph is |
725 | 49 | // not completely zigg-zagged. | 49 | // not completely zig-zagged. |
726 | 50 | PLOTMODE_RELATIVE, | 50 | kRelative, |
727 | 51 | 51 | kAbsolute | |
722 | 52 | PLOTMODE_ABSOLUTE | ||
728 | 53 | }; | 52 | }; |
729 | 54 | 53 | ||
730 | 54 | // sample_rate is in in milliseconds | ||
731 | 55 | WuiPlotArea | 55 | WuiPlotArea |
733 | 56 | (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h); | 56 | (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h, |
734 | 57 | uint32_t sample_rate, Plotmode plotmode); | ||
735 | 57 | 58 | ||
736 | 58 | /// Calls update() if needed | 59 | /// Calls update() if needed |
737 | 59 | void think() override; | 60 | void think() override; |
738 | @@ -65,51 +66,54 @@ | |||
739 | 65 | needs_update_ = true; | 66 | needs_update_ = true; |
740 | 66 | } | 67 | } |
741 | 67 | 68 | ||
743 | 68 | void set_time_id(int32_t time) { | 69 | void set_time_id(uint32_t time) { |
744 | 69 | if (time == game_time_id_) | 70 | if (time == game_time_id_) |
745 | 70 | set_time(TIME_GAME); | 71 | set_time(TIME_GAME); |
746 | 71 | else | 72 | else |
747 | 72 | set_time(static_cast<TIME>(time)); | 73 | set_time(static_cast<TIME>(time)); |
748 | 73 | needs_update_ = true; | 74 | needs_update_ = true; |
749 | 74 | } | 75 | } |
752 | 75 | TIME get_time() {return static_cast<TIME>(time_); } | 76 | TIME get_time() const {return static_cast<TIME>(time_); } |
753 | 76 | int32_t get_time_id() { | 77 | int32_t get_time_id() const { |
754 | 77 | if (time_ == TIME_GAME) | 78 | if (time_ == TIME_GAME) |
755 | 78 | return game_time_id_; | 79 | return game_time_id_; |
756 | 79 | else | 80 | else |
757 | 80 | return time_; | 81 | return time_; |
758 | 81 | } | 82 | } |
759 | 82 | void set_sample_rate(uint32_t id); // in milliseconds | ||
760 | 83 | 83 | ||
762 | 84 | int32_t get_game_time_id(); | 84 | uint32_t get_game_time_id(); |
763 | 85 | 85 | ||
764 | 86 | void register_plot_data | 86 | void register_plot_data |
765 | 87 | (uint32_t id, const std::vector<uint32_t> * data, RGBColor); | 87 | (uint32_t id, const std::vector<uint32_t> * data, RGBColor); |
766 | 88 | void show_plot(uint32_t id, bool t); | 88 | void show_plot(uint32_t id, bool t); |
767 | 89 | 89 | ||
768 | 90 | void set_plotmode(int32_t id) {plotmode_ = id;} | ||
769 | 91 | |||
770 | 92 | void set_plotcolor(uint32_t id, RGBColor color); | 90 | void set_plotcolor(uint32_t id, RGBColor color); |
771 | 93 | 91 | ||
773 | 94 | std::vector<std::string> get_labels(); | 92 | std::vector<std::string> get_labels() const; |
774 | 95 | 93 | ||
775 | 96 | protected: | 94 | protected: |
776 | 95 | void draw_plot(RenderTarget& dst, float yoffset, const std::string& yscale_label, | ||
777 | 96 | uint32_t highest_scale); | ||
778 | 97 | void draw_plot_line | 97 | void draw_plot_line |
780 | 98 | (RenderTarget & dst, std::vector<uint32_t> const * dataset, float const yline_length, | 98 | (RenderTarget & dst, std::vector<uint32_t> const * dataset, |
781 | 99 | uint32_t const highest_scale, float const sub, RGBColor const color, int32_t yoffset); | 99 | uint32_t const highest_scale, float const sub, RGBColor const color, int32_t yoffset); |
783 | 100 | uint32_t get_plot_time(); | 100 | uint32_t get_plot_time() const; |
784 | 101 | /// Recalculates the data | 101 | /// Recalculates the data |
785 | 102 | virtual void update(); | 102 | virtual void update(); |
786 | 103 | // Initializes relative_dataset and time scaling. | ||
787 | 104 | // Returns how many values will be aggregated when relative plotting | ||
788 | 105 | int32_t initialize_update(); | ||
789 | 103 | 106 | ||
790 | 104 | struct PlotData { | 107 | struct PlotData { |
792 | 105 | const std::vector<uint32_t> * dataset; | 108 | const std::vector<uint32_t> * absolute_data; // The absolute dataset |
793 | 109 | std::vector<uint32_t> * relative_data; // The relative dataset | ||
794 | 106 | bool showplot; | 110 | bool showplot; |
795 | 107 | RGBColor plotcolor; | 111 | RGBColor plotcolor; |
796 | 108 | }; | 112 | }; |
797 | 109 | std::vector<PlotData> plotdata_; | 113 | std::vector<PlotData> plotdata_; |
798 | 110 | 114 | ||
801 | 111 | int32_t plotmode_; | 115 | Plotmode plotmode_; |
802 | 112 | int32_t sample_rate_; | 116 | uint32_t sample_rate_; |
803 | 113 | 117 | ||
804 | 114 | /// Whether there has ben a data update since the last time that think() was executed | 118 | /// Whether there has ben a data update since the last time that think() was executed |
805 | 115 | bool needs_update_; | 119 | bool needs_update_; |
806 | @@ -117,15 +121,17 @@ | |||
807 | 117 | uint32_t lastupdate_; | 121 | uint32_t lastupdate_; |
808 | 118 | 122 | ||
809 | 119 | /// For first updating and then plotting the data | 123 | /// For first updating and then plotting the data |
810 | 124 | float const xline_length_; | ||
811 | 125 | float const yline_length_; | ||
812 | 120 | uint32_t time_ms_; | 126 | uint32_t time_ms_; |
813 | 121 | uint32_t highest_scale_; | 127 | uint32_t highest_scale_; |
814 | 122 | float sub_; | 128 | float sub_; |
815 | 123 | 129 | ||
816 | 124 | private: | 130 | private: |
818 | 125 | uint32_t get_game_time(); | 131 | uint32_t get_game_time() const; |
819 | 126 | 132 | ||
820 | 127 | TIME time_; // How much do you want to list | 133 | TIME time_; // How much do you want to list |
822 | 128 | int32_t game_time_id_; // what label is used for TIME_GAME | 134 | uint32_t game_time_id_; // what label is used for TIME_GAME |
823 | 129 | }; | 135 | }; |
824 | 130 | 136 | ||
825 | 131 | /** | 137 | /** |
826 | @@ -161,7 +167,7 @@ | |||
827 | 161 | 167 | ||
828 | 162 | private: | 168 | private: |
829 | 163 | WuiPlotArea & plot_area_; | 169 | WuiPlotArea & plot_area_; |
831 | 164 | int32_t last_game_time_id_; | 170 | uint32_t last_game_time_id_; |
832 | 165 | }; | 171 | }; |
833 | 166 | 172 | ||
834 | 167 | /** | 173 | /** |
835 | @@ -172,7 +178,8 @@ | |||
836 | 172 | struct DifferentialPlotArea : public WuiPlotArea { | 178 | struct DifferentialPlotArea : public WuiPlotArea { |
837 | 173 | public: | 179 | public: |
838 | 174 | DifferentialPlotArea | 180 | DifferentialPlotArea |
840 | 175 | (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h); | 181 | (UI::Panel * parent, int32_t x, int32_t y, int32_t w, int32_t h, |
841 | 182 | uint32_t sample_rate, Plotmode plotmode); | ||
842 | 176 | 183 | ||
843 | 177 | void draw(RenderTarget &) override; | 184 | void draw(RenderTarget &) override; |
844 | 178 | 185 | ||
845 | @@ -184,13 +191,14 @@ | |||
846 | 184 | void update() override; | 191 | void update() override; |
847 | 185 | 192 | ||
848 | 186 | private: | 193 | private: |
849 | 187 | |||
850 | 188 | /** | 194 | /** |
852 | 189 | * for the negative plotdata only the values matter. The color and | 195 | * For the negative plotdata, only the values matter. The color and |
853 | 190 | * visibility is determined by the normal plotdata. | 196 | * visibility is determined by the normal plotdata. |
854 | 197 | * We don't need relative data to fill - this is also done in the | ||
855 | 198 | * normal plotdata | ||
856 | 191 | */ | 199 | */ |
857 | 192 | struct ReducedPlotData { | 200 | struct ReducedPlotData { |
859 | 193 | const std::vector<uint32_t> * dataset; | 201 | const std::vector<uint32_t> * absolute_data; |
860 | 194 | }; | 202 | }; |
861 | 195 | std::vector<ReducedPlotData> negative_plotdata_; | 203 | std::vector<ReducedPlotData> negative_plotdata_; |
862 | 196 | }; | 204 | }; |
863 | 197 | 205 | ||
864 | === modified file 'src/wui/ware_statistics_menu.cc' | |||
865 | --- src/wui/ware_statistics_menu.cc 2016-03-30 07:20:05 +0000 | |||
866 | +++ src/wui/ware_statistics_menu.cc 2016-06-10 17:28:35 +0000 | |||
867 | @@ -164,9 +164,9 @@ | |||
868 | 164 | plot_production_ = | 164 | plot_production_ = |
869 | 165 | new WuiPlotArea | 165 | new WuiPlotArea |
870 | 166 | (tabs, | 166 | (tabs, |
874 | 167 | 0, 0, kPlotWidth, kPlotHeight + kSpacing); | 167 | 0, 0, kPlotWidth, kPlotHeight + kSpacing, |
875 | 168 | plot_production_->set_sample_rate(STATISTICS_SAMPLE_TIME); | 168 | kStatisticsSampleTime, |
876 | 169 | plot_production_->set_plotmode(WuiPlotArea::PLOTMODE_RELATIVE); | 169 | WuiPlotArea::Plotmode::kRelative); |
877 | 170 | 170 | ||
878 | 171 | tabs->add | 171 | tabs->add |
879 | 172 | ("production", g_gr->images().get(pic_tab_production), | 172 | ("production", g_gr->images().get(pic_tab_production), |
880 | @@ -175,9 +175,9 @@ | |||
881 | 175 | plot_consumption_ = | 175 | plot_consumption_ = |
882 | 176 | new WuiPlotArea | 176 | new WuiPlotArea |
883 | 177 | (tabs, | 177 | (tabs, |
887 | 178 | 0, 0, kPlotWidth, kPlotHeight + kSpacing); | 178 | 0, 0, kPlotWidth, kPlotHeight + kSpacing, |
888 | 179 | plot_consumption_->set_sample_rate(STATISTICS_SAMPLE_TIME); | 179 | kStatisticsSampleTime, |
889 | 180 | plot_consumption_->set_plotmode(WuiPlotArea::PLOTMODE_RELATIVE); | 180 | WuiPlotArea::Plotmode::kRelative); |
890 | 181 | 181 | ||
891 | 182 | tabs->add | 182 | tabs->add |
892 | 183 | ("consumption", g_gr->images().get(pic_tab_consumption), | 183 | ("consumption", g_gr->images().get(pic_tab_consumption), |
893 | @@ -186,9 +186,9 @@ | |||
894 | 186 | plot_economy_ = | 186 | plot_economy_ = |
895 | 187 | new DifferentialPlotArea | 187 | new DifferentialPlotArea |
896 | 188 | (tabs, | 188 | (tabs, |
900 | 189 | 0, 0, kPlotWidth, kPlotHeight + kSpacing); | 189 | 0, 0, kPlotWidth, kPlotHeight + kSpacing, |
901 | 190 | plot_economy_->set_sample_rate(STATISTICS_SAMPLE_TIME); | 190 | kStatisticsSampleTime, |
902 | 191 | plot_economy_->set_plotmode(WuiPlotArea::PLOTMODE_RELATIVE); | 191 | WuiPlotArea::Plotmode::kRelative); |
903 | 192 | 192 | ||
904 | 193 | tabs->add | 193 | tabs->add |
905 | 194 | ("economy_health", g_gr->images().get(pic_tab_economy), | 194 | ("economy_health", g_gr->images().get(pic_tab_economy), |
906 | @@ -196,9 +196,9 @@ | |||
907 | 196 | 196 | ||
908 | 197 | plot_stock_ = new WuiPlotArea | 197 | plot_stock_ = new WuiPlotArea |
909 | 198 | (tabs, | 198 | (tabs, |
913 | 199 | 0, 0, kPlotWidth, kPlotHeight + kSpacing); | 199 | 0, 0, kPlotWidth, kPlotHeight + kSpacing, |
914 | 200 | plot_stock_->set_sample_rate(STATISTICS_SAMPLE_TIME); | 200 | kStatisticsSampleTime, |
915 | 201 | plot_stock_->set_plotmode(WuiPlotArea::PLOTMODE_ABSOLUTE); | 201 | WuiPlotArea::Plotmode::kAbsolute); |
916 | 202 | 202 | ||
917 | 203 | tabs->add | 203 | tabs->add |
918 | 204 | ("stock", g_gr->images().get(pic_tab_stock), | 204 | ("stock", g_gr->images().get(pic_tab_stock), |
Good savegames for testing are attached to bug https:/ /bugs.launchpad .net/widelands/ +bug/1573057