From 1bdfbd1620e69ea76fb3158fd5205e4ea5f0fa41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana?= Date: Tue, 19 Sep 2023 14:07:41 +0200 Subject: [PATCH] Complete adding color to format --- src/Platform/ReportExcel.cc | 207 +++++++++++++++++++++++++++--------- src/Platform/ReportExcel.h | 31 +++--- 2 files changed, 173 insertions(+), 65 deletions(-) diff --git a/src/Platform/ReportExcel.cc b/src/Platform/ReportExcel.cc index 3c011aa..37f9cb5 100644 --- a/src/Platform/ReportExcel.cc +++ b/src/Platform/ReportExcel.cc @@ -12,67 +12,154 @@ namespace platform { string do_grouping() const { return "\03"; } }; + + lxw_format* ReportExcel::efectiveStyle(const string& style) + { + lxw_format* efectiveStyle; + if (style == "") { + efectiveStyle = NULL; + } else { + string suffix = row % 2 ? "_odd" : "_even"; + efectiveStyle = styles.at(style + suffix); + } + return efectiveStyle; + } + void ReportExcel::writeString(int row, int col, const string& text, const string& style) { - lxw_format* efectiveStyle = style == "" ? NULL : styles[style]; - worksheet_write_string(worksheet, row, col, text.c_str(), efectiveStyle); + worksheet_write_string(worksheet, row, col, text.c_str(), efectiveStyle(style)); } void ReportExcel::writeInt(int row, int col, const int number, const string& style) { - lxw_format* efectiveStyle = style == "" ? NULL : styles[style]; - worksheet_write_number(worksheet, row, col, number, efectiveStyle); + worksheet_write_number(worksheet, row, col, number, efectiveStyle(style)); } void ReportExcel::writeDouble(int row, int col, const double number, const string& style) { - lxw_format* efectiveStyle = style == "" ? NULL : styles[style]; - worksheet_write_number(worksheet, row, col, number, efectiveStyle); + worksheet_write_number(worksheet, row, col, number, efectiveStyle(style)); } - void ReportExcel::formatHeader() + void ReportExcel::formatColumns() { - worksheet_freeze_panes(worksheet, 8, 0); + worksheet_freeze_panes(worksheet, 6, 1); + vector columns_sizes = { 22, 10, 9, 7, 12, 12, 12, 12, 12, 3, 14, 12, 50 }; + for (int i = 0; i < columns_sizes.size(); ++i) { + worksheet_set_column(worksheet, i, i, columns_sizes.at(i), NULL); + } } - void ReportExcel::formatBody() + void ReportExcel::addColor(lxw_format* style, bool odd) { - + uint32_t efectiveColor = odd ? colorEven : colorOdd; + format_set_bg_color(style, lxw_color_t(efectiveColor)); } - - void ReportExcel::formatFooter() + void ReportExcel::createStyle(const string& name, lxw_format* style, bool odd) { - + addColor(style, odd); + if (name == "textCentered") { + format_set_align(style, LXW_ALIGN_CENTER); + format_set_font_size(style, normalSize); + format_set_border(style, LXW_BORDER_THIN); + } else if (name == "text") { + format_set_font_size(style, normalSize); + format_set_border(style, LXW_BORDER_THIN); + } else if (name == "bodyHeader") { + format_set_bold(style); + format_set_font_size(style, normalSize); + format_set_align(style, LXW_ALIGN_VERTICAL_CENTER); + format_set_align(style, LXW_ALIGN_CENTER); + format_set_align(style, LXW_ALIGN_VERTICAL_CENTER); + format_set_bg_color(style, lxw_color_t(colorTitle)); + } else if (name == "result") { + format_set_font_size(style, normalSize); + format_set_border(style, LXW_BORDER_THIN); + format_set_num_format(style, "0.0000000"); + } else if (name == "time") { + format_set_font_size(style, normalSize); + format_set_border(style, LXW_BORDER_THIN); + format_set_num_format(style, "#,##0.000000"); + } else if (name == "ints") { + format_set_font_size(style, normalSize); + format_set_num_format(style, "###,###"); + format_set_border(style, LXW_BORDER_THIN); + } else if (name == "floats") { + format_set_border(style, LXW_BORDER_THIN); + format_set_font_size(style, normalSize); + format_set_num_format(style, "#,###.00"); + } } void ReportExcel::createFormats() { - lxw_format* bold = workbook_add_format(workbook); - format_set_bold(bold); + auto styleNames = { "text", "textCentered", "bodyHeader", "result", "time", "ints", "floats" }; + lxw_format* style; + for (string name : styleNames) { + lxw_format* style = workbook_add_format(workbook); + style = workbook_add_format(workbook); + createStyle(name, style, true); + styles[name + "_odd"] = style; + style = workbook_add_format(workbook); + createStyle(name, style, false); + styles[name + "_even"] = style; + } - lxw_format* result = workbook_add_format(workbook); - format_set_num_format(result, "0.0000000"); + // Header 1st line + lxw_format* headerFirst = workbook_add_format(workbook); + format_set_bold(headerFirst); + format_set_font_size(headerFirst, 18); + format_set_align(headerFirst, LXW_ALIGN_CENTER); + format_set_align(headerFirst, LXW_ALIGN_VERTICAL_CENTER); + format_set_border(headerFirst, LXW_BORDER_THIN); + format_set_bg_color(headerFirst, lxw_color_t(colorTitle)); - lxw_format* timeStyle = workbook_add_format(workbook); - format_set_num_format(timeStyle, "#,##0.00"); + // Header rest + lxw_format* headerRest = workbook_add_format(workbook); + format_set_bold(headerRest); + format_set_align(headerRest, LXW_ALIGN_CENTER); + format_set_font_size(headerRest, 16); + format_set_align(headerRest, LXW_ALIGN_VERTICAL_CENTER); + format_set_border(headerRest, LXW_BORDER_THIN); + format_set_bg_color(headerRest, lxw_color_t(colorOdd)); - lxw_format* ints = workbook_add_format(workbook); - format_set_num_format(ints, "###,###"); + // Header small + lxw_format* headerSmall = workbook_add_format(workbook); + format_set_bold(headerSmall); + format_set_align(headerSmall, LXW_ALIGN_LEFT); + format_set_font_size(headerSmall, 12); + format_set_border(headerSmall, LXW_BORDER_THIN); + format_set_align(headerSmall, LXW_ALIGN_VERTICAL_CENTER); + format_set_bg_color(headerSmall, lxw_color_t(colorOdd)); - lxw_format* floats = workbook_add_format(workbook); - format_set_num_format(floats, "#,###.00"); + styles["headerFirst"] = headerFirst; + styles["headerRest"] = headerRest; + styles["headerSmall"] = headerSmall; + } - styles["bold"] = bold; - styles["result"] = result; - styles["time"] = timeStyle; - styles["ints"] = ints; - styles["floats"] = floats + void ReportExcel::setProperties() + { + char line[data["title"].get().size() + 1]; + strcpy(line, data["title"].get().c_str()); + /* Create a properties structure and set some of the fields. */ + lxw_doc_properties properties = { + .title = line, + .subject = "Machine learning results", + .author = "Ricardo Montañana Gómez", + .manager = "Dr. J. A. Gámez, Dr. J. M. Puerta", + .company = "UCLM", + .comments = "Created with libxlsxwriter and c++", + }; + + /* Set the properties in the workbook. */ + workbook_set_properties(workbook, &properties); } void ReportExcel::createFile() { - workbook = workbook_new((Paths::excel() + "some_results.xlsx").c_str()); + workbook = workbook_new((Paths::excel() + fileName).c_str()); const string name = data["model"].get(); worksheet = workbook_add_worksheet(workbook, name.c_str()); + setProperties(); createFormats(); + formatColumns(); } void ReportExcel::closeFile() @@ -86,35 +173,49 @@ namespace platform { locale::global(mylocale); cout.imbue(mylocale); stringstream oss; - writeString(0, 0, "Report " + data["model"].get() + " ver. " + data["version"].get() + " with " + - to_string(data["folds"].get()) + " Folds cross validation and " + to_string(data["seeds"].size()) + - " random seeds. " + data["date"].get() + " " + data["time"].get(), "bold"); - writeString(1, 0, data["title"].get()); - writeString(2, 0, "Random seeds: " + fromVector("seeds") + " Stratified: " + - (data["stratified"].get() ? "True" : "False")); - oss << "Execution took " << setprecision(2) << fixed << data["duration"].get() << " seconds, " - << data["duration"].get() / 3600 << " hours, on " << data["platform"].get(); - writeString(3, 0, oss.str()); - writeString(4, 0, "Score is " + data["score_name"].get()); - formatHeader(); + string message = data["model"].get() + " ver. " + data["version"].get() + + data["language"].get() + " ver. " + data["language_version"].get() + + " with " + to_string(data["folds"].get()) + " Folds cross validation and " + to_string(data["seeds"].size()) + + " random seeds. " + data["date"].get() + " " + data["time"].get(); + worksheet_merge_range(worksheet, 0, 0, 0, 12, message.c_str(), styles["headerFirst"]); + worksheet_merge_range(worksheet, 1, 0, 1, 12, data["title"].get().c_str(), styles["headerRest"]); + worksheet_merge_range(worksheet, 2, 0, 3, 0, ("Score is " + data["score_name"].get()).c_str(), styles["headerRest"]); + worksheet_merge_range(worksheet, 2, 1, 3, 3, "Execution time", styles["headerRest"]); + oss << setprecision(2) << fixed << data["duration"].get() << " s"; + worksheet_merge_range(worksheet, 2, 4, 2, 5, oss.str().c_str(), styles["headerRest"]); + oss.str(""); + oss.clear(); + oss << setprecision(2) << fixed << data["duration"].get() / 3600 << " h"; + worksheet_merge_range(worksheet, 3, 4, 3, 5, oss.str().c_str(), styles["headerRest"]); + worksheet_merge_range(worksheet, 2, 6, 3, 7, "Platform", styles["headerRest"]); + worksheet_merge_range(worksheet, 2, 8, 3, 9, data["platform"].get().c_str(), styles["headerRest"]); + worksheet_merge_range(worksheet, 2, 10, 2, 12, ("Random seeds: " + fromVector("seeds")).c_str(), styles["headerSmall"]); + oss.str(""); + oss.clear(); + oss << "Stratified: " << (data["stratified"].get() ? "True" : "False"); + worksheet_merge_range(worksheet, 3, 10, 3, 11, oss.str().c_str(), styles["headerSmall"]); + oss.str(""); + oss.clear(); + oss << "Discretized: " << (data["discretized"].get() ? "True" : "False"); + worksheet_write_string(worksheet, 3, 12, oss.str().c_str(), styles["headerSmall"]); } void ReportExcel::body() { auto head = vector( - { "Dataset", "Samples", "Features", "Classes", "Nodes", "Edges", "States", "Score", "Score Std.", "Time", + { "Dataset", "Samples", "Features", "Classes", "Nodes", "Edges", "States", "Score", "Score Std.", "St.", "Time", "Time Std.", "Hyperparameters" }); - int col = 1; + int col = 0; for (const auto& item : head) { - writeString(8, col++, item); + writeString(5, col++, item, "bodyHeader"); } - int row = 9; - col = 1; + row = 6; + col = 0; json lastResult; double totalScore = 0.0; string hyperparameters; for (const auto& r : data["results"]) { - writeString(row, col, r["dataset"].get()); + writeString(row, col, r["dataset"].get(), "text"); writeInt(row, col + 1, r["samples"].get(), "ints"); writeInt(row, col + 2, r["features"].get(), "ints"); writeInt(row, col + 3, r["classes"].get(), "ints"); @@ -123,8 +224,10 @@ namespace platform { writeDouble(row, col + 6, r["depth"].get(), "floats"); writeDouble(row, col + 7, r["score"].get(), "result"); writeDouble(row, col + 8, r["score_std"].get(), "result"); - writeDouble(row, col + 9, r["time"].get(), "time"); - writeDouble(row, col + 10, r["time_std"].get(), "time"); + const string status = "X"; + writeString(row, col + 9, status, "textCentered"); + writeDouble(row, col + 10, r["time"].get(), "time"); + writeDouble(row, col + 11, r["time_std"].get(), "time"); try { hyperparameters = r["hyperparameters"].get(); } @@ -133,7 +236,7 @@ namespace platform { oss << r["hyperparameters"]; hyperparameters = oss.str(); } - writeString(row, col + 11, hyperparameters); + writeString(row, col + 12, hyperparameters, "text"); lastResult = r; totalScore += r["score"].get(); row++; @@ -150,16 +253,14 @@ namespace platform { } else { footer(totalScore, row); } - formatBody(); } void ReportExcel::footer(double totalScore, int row) { auto score = data["score_name"].get(); if (score == BestResult::scoreName()) { - writeString(row + 2, 1, score + " compared to " + BestResult::title() + " .: "); - writeDouble(row + 2, 7, totalScore / BestResult::score(), "result"); + worksheet_merge_range(worksheet, row + 2, 1, row + 2, 5, (score + " compared to " + BestResult::title() + " .:").c_str(), styles["text_even"]); + writeDouble(row + 2, 6, totalScore / BestResult::score(), "result"); } - formatFooter(); } } \ No newline at end of file diff --git a/src/Platform/ReportExcel.h b/src/Platform/ReportExcel.h index 69d9f69..9dc3aa3 100644 --- a/src/Platform/ReportExcel.h +++ b/src/Platform/ReportExcel.h @@ -12,23 +12,30 @@ namespace platform { public: explicit ReportExcel(json data_) : ReportBase(data_) { createFile(); }; virtual ~ReportExcel() { closeFile(); }; - protected: + private: void writeString(int row, int col, const string& text, const string& style = ""); void writeInt(int row, int col, const int number, const string& style = ""); void writeDouble(int row, int col, const double number, const string& style = ""); - void formatHeader(); - void formatBody(); - void formatFooter(); + void formatColumns(); void createFormats(); - private: galeote + void setProperties(); void createFile(); - void closeFile(); - lxw_workbook* workbook; - lxw_worksheet* worksheet; - map styles; - void header() override; - void body() override; - void footer(double totalScore, int row); + void closeFile(); + lxw_workbook* workbook; + lxw_worksheet* worksheet; + map styles; + int row = 0; + int normalSize = 14; //font size for report body + uint32_t colorTitle = 0xB1A0C7; + uint32_t colorOdd = 0xDCE6F1; + uint32_t colorEven = 0xFDE9D9; + const string fileName = "some_results.xlsx"; + void header() override; + void body() override; + void footer(double totalScore, int row); + void createStyle(const string& name, lxw_format* style, bool odd); + void addColor(lxw_format* style, bool odd); + lxw_format* efectiveStyle(const string& name); }; }; #endif // !REPORTEXCEL_H \ No newline at end of file