diff --git a/client/mainmenu/CHighScoreScreen.cpp b/client/mainmenu/CHighScoreScreen.cpp index df7e947d9..89e4d3c6c 100644 --- a/client/mainmenu/CHighScoreScreen.cpp +++ b/client/mainmenu/CHighScoreScreen.cpp @@ -209,8 +209,8 @@ CHighScoreInputScreen::CHighScoreInputScreen(bool won, HighScoreCalculation calc if (settings["general"]["enableUiEnhancements"].Bool()) { - statisticButton = std::make_shared(Point(736, 0), AnimationPath::builtin("TPTAV02.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.statisticWindow.statistic")), [this](){ GH.windows().createAndPushWindow(stat); }, EShortcut::HIGH_SCORES_STATISTIC); - texts.push_back(std::make_shared(Rect(0, 0, 726, 32), FONT_HIGH_SCORE, ETextAlignment::CENTERRIGHT, Colors::WHITE, CGI->generaltexth->translate("vcmi.statisticWindow.statistic") + ":")); + statisticButton = std::make_shared(Point(726, 10), AnimationPath::builtin("TPTAV02.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.statisticWindow.statistic")), [this](){ GH.windows().createAndPushWindow(stat); }, EShortcut::HIGH_SCORES_STATISTIC); + texts.push_back(std::make_shared(716, 25, EFonts::FONT_HIGH_SCORE, ETextAlignment::CENTERRIGHT, Colors::WHITE, CGI->generaltexth->translate("vcmi.statisticWindow.statistic") + ":")); } } diff --git a/client/mainmenu/CHighScoreScreen.h b/client/mainmenu/CHighScoreScreen.h index 68d4dbae1..b00d3c253 100644 --- a/client/mainmenu/CHighScoreScreen.h +++ b/client/mainmenu/CHighScoreScreen.h @@ -71,7 +71,7 @@ public: class CHighScoreInputScreen : public CWindowObject { - std::vector> texts; + std::vector> texts; std::shared_ptr input; std::shared_ptr background; std::shared_ptr videoPlayer; diff --git a/client/mainmenu/CStatisticScreen.cpp b/client/mainmenu/CStatisticScreen.cpp index a103f6c55..e0a716fc1 100644 --- a/client/mainmenu/CStatisticScreen.cpp +++ b/client/mainmenu/CStatisticScreen.cpp @@ -23,7 +23,6 @@ #include "../widgets/Buttons.h" #include "../windows/InfoWindows.h" -#include "../../lib/VCMIDirs.h" #include "../../lib/gameState/GameStatistics.h" #include "../../lib/texts/CGeneralTextHandler.h" @@ -37,20 +36,35 @@ CStatisticScreen::CStatisticScreen(StatisticDataSet stat) filledBackground = std::make_shared(ImagePath::builtin("DiBoxBck"), Rect(0, 0, pos.w, pos.h)); filledBackground->setPlayerColor(PlayerColor(1)); - layout.push_back(std::make_shared(Rect(0, 0, 800, 30), FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.statisticWindow.statistic"))); - layout.push_back(std::make_shared(Rect(10, 30, 780, 530), ColorRGBA(0, 0, 0, 64), ColorRGBA(64, 80, 128, 255), 1)); + auto contentArea = Rect(10, 40, 780, 510); + layout.push_back(std::make_shared(400, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.statisticWindow.statistic"))); + layout.push_back(std::make_shared(contentArea, ColorRGBA(0, 0, 0, 64), ColorRGBA(64, 80, 128, 255), 1)); layout.push_back(std::make_shared(Point(725, 564), AnimationPath::builtin("MUBCHCK"), CButton::tooltip(), [this](){ close(); }, EShortcut::GLOBAL_ACCEPT)); buttonCsvSave = std::make_shared(Point(10, 564), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), [this](bool on){ - const boost::filesystem::path outPath = VCMIDirs::get().userCachePath() / "statistic"; - boost::filesystem::create_directories(outPath); - - const boost::filesystem::path filePath = outPath / (vstd::getDateTimeISO8601Basic(std::time(nullptr)) + ".csv"); - std::ofstream file(filePath.c_str()); - std::string csv = statistic.toCsv(); - file << csv; - - CInfoWindow::showInfoDialog(CGI->generaltexth->translate("vcmi.statisticWindow.csvSaved") + "\n\n" + filePath.string(), {}); + std::string path = statistic.writeCsv(); + CInfoWindow::showInfoDialog(CGI->generaltexth->translate("vcmi.statisticWindow.csvSaved") + "\n\n" + path, {}); }); buttonCsvSave->setTextOverlay(CGI->generaltexth->translate("vcmi.statisticWindow.csvSave"), EFonts::FONT_SMALL, Colors::YELLOW); + + chart = std::make_shared(contentArea.resize(-5), "test title"); +} + +LineChart::LineChart(Rect position, std::string title) : CIntObject() +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + pos = position + pos.topLeft(); + + auto chartArea = pos.resize(-50); + chartArea.moveTo(Point(50, 50)); + + layout.push_back(std::make_shared(pos.w / 2, 20, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, title)); + + canvas = std::make_shared(Rect(0, 0, pos.w, pos.h)); + canvas->addLine(chartArea.topLeft(), chartArea.bottomRight(), Colors::GREEN); + + // Axis + canvas->addLine(chartArea.topLeft() + Point(0, -10), chartArea.topLeft() + Point(0, chartArea.h + 10), Colors::WHITE); + canvas->addLine(chartArea.topLeft() + Point(-10, chartArea.h), chartArea.topLeft() + Point(chartArea.w + 10, chartArea.h), Colors::WHITE); } diff --git a/client/mainmenu/CStatisticScreen.h b/client/mainmenu/CStatisticScreen.h index 325e0e755..bc369c811 100644 --- a/client/mainmenu/CStatisticScreen.h +++ b/client/mainmenu/CStatisticScreen.h @@ -13,6 +13,8 @@ class FilledTexturePlayerColored; class CToggleButton; +class GraphicalPrimitiveCanvas; +class LineChart; class CStatisticScreen : public CWindowObject { @@ -23,6 +25,16 @@ class CStatisticScreen : public CWindowObject std::shared_ptr buttonCsvSave; StatisticDataSet statistic; + + std::shared_ptr chart; public: CStatisticScreen(StatisticDataSet stat); }; + +class LineChart : public CIntObject +{ + std::shared_ptr canvas; + std::vector> layout; +public: + LineChart(Rect position, std::string title); +}; diff --git a/lib/gameState/GameStatistics.cpp b/lib/gameState/GameStatistics.cpp index 5daf0e075..a4b476ed7 100644 --- a/lib/gameState/GameStatistics.cpp +++ b/lib/gameState/GameStatistics.cpp @@ -11,6 +11,7 @@ #include "GameStatistics.h" #include "../CPlayerState.h" #include "../constants/StringConstants.h" +#include "../VCMIDirs.h" #include "CGameState.h" #include "TerrainHandler.h" #include "CHeroHandler.h" @@ -166,6 +167,19 @@ std::string StatisticDataSet::toCsv() return ss.str(); } +std::string StatisticDataSet::writeCsv() +{ + const boost::filesystem::path outPath = VCMIDirs::get().userCachePath() / "statistic"; + boost::filesystem::create_directories(outPath); + + const boost::filesystem::path filePath = outPath / (vstd::getDateTimeISO8601Basic(std::time(nullptr)) + ".csv"); + std::ofstream file(filePath.c_str()); + std::string csv = toCsv(); + file << csv; + + return filePath.string(); +} + std::vector Statistic::getMines(const CGameState * gs, const PlayerState * ps) { std::vector tmp; diff --git a/lib/gameState/GameStatistics.h b/lib/gameState/GameStatistics.h index daec71e4a..5bc34cd6e 100644 --- a/lib/gameState/GameStatistics.h +++ b/lib/gameState/GameStatistics.h @@ -99,6 +99,7 @@ public: void add(StatisticDataSetEntry entry); static StatisticDataSetEntry createEntry(const PlayerState * ps, const CGameState * gs); std::string toCsv(); + std::string writeCsv(); struct PlayerAccumulatedValueStorage // holds some actual values needed for stats { diff --git a/server/processors/PlayerMessageProcessor.cpp b/server/processors/PlayerMessageProcessor.cpp index 6ff2b93f5..e0198744c 100644 --- a/server/processors/PlayerMessageProcessor.cpp +++ b/server/processors/PlayerMessageProcessor.cpp @@ -140,15 +140,9 @@ void PlayerMessageProcessor::commandStatistic(PlayerColor player, const std::vec if(!isHost) return; - const boost::filesystem::path outPath = VCMIDirs::get().userCachePath() / "statistic"; - boost::filesystem::create_directories(outPath); + std::string path = gameHandler->gameState()->statistic.writeCsv(); - const boost::filesystem::path filePath = outPath / (vstd::getDateTimeISO8601Basic(std::time(nullptr)) + ".csv"); - std::ofstream file(filePath.c_str()); - std::string csv = gameHandler->gameState()->statistic.toCsv(); - file << csv; - - broadcastSystemMessage("Statistic files can be found in " + outPath.string() + " directory\n"); + broadcastSystemMessage("Statistic files can be found in " + path + " directory\n"); } void PlayerMessageProcessor::commandHelp(PlayerColor player, const std::vector & words)