From e13969a61080a308c9cf8cec37885a2f0826b164 Mon Sep 17 00:00:00 2001 From: tovjemam Date: Fri, 31 Jan 2025 14:54:52 +0100 Subject: [PATCH] funguje --- canvas_graph.cpp | 166 ++++++++++++++++++++++++++++++++++++----------- shell.html | 46 +++++++++++-- 2 files changed, 169 insertions(+), 43 deletions(-) diff --git a/canvas_graph.cpp b/canvas_graph.cpp index 9116b68..7557ffd 100755 --- a/canvas_graph.cpp +++ b/canvas_graph.cpp @@ -6,24 +6,119 @@ extern "C" { using namespace emscripten; -void canvas_generate_graph(const struct expr_node *node, const struct graph_range *range, const char *function) { - const val document = val::global("document"); - val temp = document.call("getElementById", val("temp")); +struct Line { + double x1; + double y1; + double x2; + double y2; +}; - std::string out; +static void draw_lines(emscripten::val& ctx, const std::vector& lines, const char* style, double width) { + ctx.set("strokeStyle", val(style)); + ctx.set("lineWidth", val(width)); + ctx.call("beginPath"); - for (int i = -10; i <= 10; ++i) { - double x = i * 0.1; - double y; - eval_result res = node_eval(node, x, &y); - - if (res == EVAL_OK) { - out += std::to_string(y); - out += "\n"; - } + for (const Line& line : lines) { + ctx.call("moveTo", val(std::floor(line.x1 + 0.5)), val(std::floor(line.y1 + 0.5))); + ctx.call("lineTo", val(std::floor(line.x2 + 0.5)), val(std::floor(line.y2 + 0.5))); } - temp.set("innerText", out); + ctx.call("stroke"); +} + +void draw_grid(emscripten::val& ctx, const struct graph_range *range, double canvas_width, double canvas_height) { + + // grid + double big_range = std::max(range->xmax - range->xmin, range->ymax - range->ymin); + double log_base = 2.0; + double grid_size = std::pow(log_base, std::floor(std::log(big_range * 0.05) / std::log(log_base))); + // double grid_size = std::pow(10.0, std::floor(std::log10(big_range * 0.1))); + + // if (grid_size < 0.1) + // grid_size = 0.1; + + static std::vector origin_lines; + static std::vector bold_grid_lines; + static std::vector fine_grid_lines; + origin_lines.clear(); + bold_grid_lines.clear(); + fine_grid_lines.clear(); + + double x_labels_y = range->ymax / (range->ymax - range->ymin) * canvas_height + 10; + + if (x_labels_y > canvas_height - 10) + x_labels_y = canvas_height - 10; + else if (x_labels_y < 10) + x_labels_y = 10; + + for (int i = range->xmin / grid_size; i <= range->xmax / grid_size; ++i) { + double x = i * grid_size; + double x_canvas = (x - range->xmin) / (range->xmax - range->xmin) * canvas_width; + + std::vector* lines = &fine_grid_lines; + + if (i % 5 == 0) { + if (i == 0) { + lines = &origin_lines; + } else { + lines = &bold_grid_lines; + } + + ctx.call("fillText", val(x), val(x_canvas + 2), val(x_labels_y)); + } + + lines->push_back({x_canvas, 0, x_canvas, canvas_height}); + } + + double y_labels_x = -range->xmin / (range->xmax - range->xmin) * canvas_width; + + if (y_labels_x > canvas_width - 10) + y_labels_x = canvas_width - 10; + else if (y_labels_x < 10) + y_labels_x = 10; + + for (int i = range->ymin / grid_size; i <= range->ymax / grid_size; ++i) { + double y = i * grid_size; + double y_canvas = (range->ymax - y) / (range->ymax - range->ymin) * canvas_height; + + std::vector* lines = &fine_grid_lines; + + if (i % 5 == 0) { + if (i == 0) { + lines = &origin_lines; + } else { + lines = &bold_grid_lines; + } + + ctx.call("fillText", val(y), val(y_labels_x + 2), val(y_canvas - 2)); + } + + lines->push_back({0, y_canvas, canvas_width, y_canvas}); + } + + draw_lines(ctx, fine_grid_lines, "#dddddd", 1.0); + draw_lines(ctx, bold_grid_lines, "#444444", 1.0); + draw_lines(ctx, origin_lines, "#000000", 1.5); +} + +void canvas_generate_graph(const struct expr_node *node, const struct graph_range *range, const char *function) { + const val document = val::global("document"); + // val temp = document.call("getElementById", val("temp")); + + // std::string out; + + // for (int i = -10; i <= 10; ++i) { + // double x = i * 0.1; + // double y; + // eval_result res = node_eval(node, x, &y); + + // if (res == EVAL_OK) { + // out += std::to_string(y); + // out += "\n"; + // } + // } + + // temp.set("innerText", out); val canvas = document.call("getElementById", val("canvas")); val ctx = canvas.call("getContext", val("2d")); @@ -33,35 +128,30 @@ void canvas_generate_graph(const struct expr_node *node, const struct graph_rang // clear canvas ctx.call("clearRect", val(0), val(0), val(canvas_width), val(canvas_height)); - // grid - double big_range = std::max(range->xmax - range->xmin, range->ymax - range->ymin); - double grid_size = std::pow((int)std::log10(big_range), 10.0); + draw_grid(ctx, range, canvas_width, canvas_height); - if (grid_size < 0.1) - grid_size = 0.1; + // ctx.set("strokeStyle", val("#888888")); + // ctx.set("lineWidth", val(1.0)); + // ctx.call("beginPath"); - ctx.set("strokeStyle", val("#888888")); - ctx.set("lineWidth", val(1.0)); - ctx.call("beginPath"); + // double first_grid_x = (int)(range->xmin / grid_size) * grid_size; + // double grid_x; + // for (int i = 0; (grid_x = first_grid_x + i * grid_size) <= range->xmax; ++i) { + // double x_canvas = (grid_x - range->xmin) / (range->xmax - range->xmin) * canvas_width; + // ctx.call("moveTo", val(x_canvas), val(0)); + // ctx.call("lineTo", val(x_canvas), val(canvas_height)); + // } - double first_grid_x = (int)(range->xmin / grid_size) * grid_size; - double grid_x; - for (int i = 0; (grid_x = first_grid_x + i * grid_size) <= range->xmax; ++i) { - double x_canvas = (grid_x - range->xmin) / (range->xmax - range->xmin) * canvas_width; - ctx.call("moveTo", val(x_canvas), val(0)); - ctx.call("lineTo", val(x_canvas), val(canvas_height)); - } - - double first_grid_y = (int)(range->ymin / grid_size) * grid_size; - double grid_y; - for (int i = 0; (grid_y = first_grid_y + i * grid_size) <= range->ymax; ++i) { - double y_canvas = (range->ymax - grid_y) / (range->ymax - range->ymin) * canvas_height; - ctx.call("moveTo", val(0), val(y_canvas)); - ctx.call("lineTo", val(canvas_width), val(y_canvas)); - } + // double first_grid_y = (int)(range->ymin / grid_size) * grid_size; + // double grid_y; + // for (int i = 0; (grid_y = first_grid_y + i * grid_size) <= range->ymax; ++i) { + // double y_canvas = (range->ymax - grid_y) / (range->ymax - range->ymin) * canvas_height; + // ctx.call("moveTo", val(0), val(y_canvas)); + // ctx.call("lineTo", val(canvas_width), val(y_canvas)); + // } - ctx.call("stroke"); + // ctx.call("stroke"); // graph ctx.set("strokeStyle", val("#000088")); diff --git a/shell.html b/shell.html index 6ca1b08..8a80771 100644 --- a/shell.html +++ b/shell.html @@ -3,9 +3,17 @@ - Document + zbyvaj's Graphing Calculator - - -

-    

+    
+ + +

+    
{{{ SCRIPT }}}