#include #include #include #include "histogram.h" #include "text.h" #include #include #include #include using namespace std; struct progress { char* privat; size_t size; }; void svg_begin(double width, double height) { cout << "\n"; cout << "\n"; } void svg_text(double left, double baseline, string text) { cout << "" << text <<"\n"; } void svg_rect(double x, double y, double width, double height, string stroke = "yellow", string fill = "red") { cout << "\n"; } void svg_end() { cout << "\n"; } void show_histogram_svg(const vector& marks, const vector& chart) { const auto IMAGE_WIDTH = 400; const auto IMAGE_HEIGHT = 300; const auto TEXT_LEFT = 20; const auto TEXT_BASELINE = 20; const auto TEXT_WIDTH = 50; const auto BIN_HEIGHT = 30; const auto BLOCK_WIDTH = 10; double min = 0, max = 0, scale = 1, average = 0, sum = 0; int maxlen = IMAGE_WIDTH - TEXT_WIDTH; svg_begin(4000, 300); double top = 0; for (double x : chart) { sum += x; } average = sum / chart.size(); FindMinMax(chart, min, max); scale = max * BLOCK_WIDTH / maxlen; for (double bin : chart) { double bin_width = BLOCK_WIDTH * bin; svg_text(TEXT_LEFT, top + TEXT_BASELINE, to_string((int)bin)); if (bin > average) { svg_rect(TEXT_WIDTH, top, bin_width / scale, BIN_HEIGHT, "yellow", "red"); } else { svg_rect(TEXT_WIDTH, top, bin_width / scale, BIN_HEIGHT, "yellow", "green"); } top += BIN_HEIGHT; } svg_end(); } struct Input { vector marks; int NCharts = 0; }; Input input_data(istream& instr, bool promt) { Input in; int VecSize = 0; if (promt) { cout << "input num of marks\n"; } instr >> VecSize; in.marks.resize(VecSize); if (promt) { cout << "input num marks\n"; } for (int i = 0; i < VecSize; i++) { instr >> in.marks[i]; } if (promt) { cout << "input num of charts\n"; } instr >> in.NCharts; return in; }; size_t write_data(void* items, size_t item_size, size_t item_count, void* ctx) { size_t data_size = item_size * item_count; stringstream* buffer = reinterpret_cast(ctx); (*buffer).write(reinterpret_cast(items), data_size); return data_size; } size_t write_header(char* buffer, size_t size, size_t nitems, void* userdata) { cerr << "Headers: " << buffer << endl; return size * nitems; } static size_t progress_callback(void* clientp, double dltotal, double dlnow, double ultotal, double ulnow) { struct progress* memory = (progress*)clientp; cerr << "Progress: " << (dlnow / dltotal) * 100 << "%\n"; //cerr << "Progress: " << memory->privat << "\n"; return 0; /* all is good */ } Input download(const string& address) { stringstream buffer; struct progress data; CURL* curl = curl_easy_init(); if (curl) { CURLcode res; curl_easy_setopt(curl, CURLOPT_URL, address.c_str()); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &data); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_header); curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL); res = curl_easy_perform(curl); curl_easy_cleanup(curl); if (res != CURLE_OK) { cout << curl_easy_strerror(res); exit(1); } } return input_data(buffer, false); } int main(int argc, char* argv[]){ Input input; if (argc > 1) { input = download(argv[1]); } else { input = input_data(cin, true); } vector chart = MakeHistogram(input.marks, input.NCharts); //show_histogram_text(in.marks, chart); show_histogram_svg(input.marks, chart); }