Alikberov,
Графики, получились красивые, особенно, с осями координат. Спасибо за ответ. Однако, графики не имеют своих интервалов существования на оси Х, потому что они существуют на всей числовой оси Х и сходятся в одной точке (0, 0) |
Alikberov, Только, что опробовал Ваш код, и оказалось, что Вы построили все возможные варианты построения графиков. Поэтому, очень прошу извинить меня за мою невнимательность и ещё раз большое спасибо. Ваш код не просто правильный, но совершенно полноценный.
|
Alikberov,
Было бы здорово, если бы Вы, общий код разделили на три кода: Соответственно, для одного графика, для графиков на разных интервалах, и графиков проходящих через (0,0). Сам, я боюсь чт что-нибудь не так сделаю или допушу досадную ошибку. Заранее благодарен. |
Увы! Код написан довольно быстро и местами небрежно. Имеет ряд недоработок:
Цитата:
Вот только комментарии не успел раскидать, из-за чего код слишком мутно выглядит. Вот фрагмент с пояснениями. var meine_diagramme = { min_x: 0, // Минимум по оси X на графике max_x: 10, // Максимум по оси X на графике min_y: 0, // Минимум по оси Y на графике max_y: 100, // Максимум по оси Y на графике step_x: 1, // Шаг цифровой разметки по оси X под графиком step_y: 20, // Наш цифровой разметки по оси Y слева от графика width: 390, // Ширина Canvas-области - масштаб графика height: 120, // Высота Canvas-области fn: [ // Здесь можем перечислить массивом все наши функции { x1: 0, // Начальная точка на оси X x2: 100, // Конечная точка на оси X color: "red", // Цвет линии построения графика fn: "x**2" // Ведущая функция на графике } ] }; // Создаём объект графика и передаём ему реквизиты var grafik = new Functions(meine_diagramme); // Добавляем его на страницу document.body.appendChild(grafik.domElement); // Теперь добавим вторую функцию var mein_diagramm = { x1: 2.5, // Начальная точка на оси X x2: 7.5, // Конечная точка на оси X color: "blue", // Цвет линии построения графика fn: "30*sin(10*x)+60" }; // Пауза перед добавлением второго графика setTimeout(`grafik.draw([mein_diagramm])`, 5000); // Пауза перед очищением области графика setTimeout(`grafik.clear()`, 10000); // Пауза перед отображением только второго графика`); setTimeout(`grafik.draw([mein_diagramm])`, 15000); // Пауза перед смещением оси путём коррекции минимума на сетке setTimeout(`grafik.grid.min_x = -12; grafik.clear()`, 20000); // Пауза перед отображением двух графиков setTimeout(`mein_diagramm.x1 = -10; grafik.draw([mein_diagramm, meine_diagramme.fn[0]])`, 25000); |
Alikberov,
Уважаемый Alikberov, так как, я не такой опытный, как Вы, мне так и не удалось Ваш код разделить на три кода ( три типа построения графиков) Убрал строки 152-170 с целью убрать первый тип графиков и, как и ожидалось ничего не получилось (где то ошибка). Вернее, после этого пошли ошибки за ошибкой, которые надо было исправлять. Убедительно прошу разделить общий файл на три по типам построения графиков. Если, есть возможность дайте хоть, какие нибудь главные комментарии. |
Alikberov, Извините, опять поторопился со своим последним сообщением. Мне удалось Ваш код разделить на три кода ( три типа построения графиков). Правда, потратил на это несколько часов.
|
Вот Вам Конструктор Графиков с "горячей отладкой".
(Можно изменять любые параметры как мышкой, так и JSON.) Правда, там не всё работает так, как хотелось бы мне. Но это поправимо в дальнейшем. P.S.: Класс переименовал, добавил сетку и легенду. |
Alikberov,
График не реагирует на изменения шкалы, а должен по идее. Могу подсказать, где подсмотреть можно на эту тему, если интересно. |
Вложений: 1
Alikberov, Я взял за основу Ваш код для построения графиков, но не смог нарисовать обыкновенные геометрические фигуры ромба и окружности, которые привязаны к определенной координате (См.картинку). Попробовал нарисовать обыкновенный отрезок, а он уехал, вобще, куда-то из области координат. Ваш код настолько насышен различными тегами, что я точно не смогу разобраться в чём дело. Видимо здесь более глубинные причины разрыва осей координат от геометрических фигур. Прошу, если возможно, упростить или сделать понятным высланный мной код HTML, который я выделил из общего Вашего кода. И, самое главное - нарисовать ромб и окружность, показанные на картинке. Их размеры должны быть сооизмеримы с координатными осями.
<!DOCTYPE html> <html><head> <canvas id="canvas"></canvas> <script> var canv = document.getElementById(`canvas`), ctx = canv.getContext(`2d`); // рисуем в 2d class Functions { constructor(props) { // описание и атрибуты this.grid = { // это сетка min_x :props && "min_x" in props ? props.min_x : -50, max_x :props && "max_x" in props ? props.max_x : 100, min_y :props && "min_y" in props ? props.min_y : -80, max_y :props && "max_y" in props ? props.max_y : 100, step_x :(props && props.step_x) || 10, step_y :(props && props.step_y) || 20, size :(props && props.size) || 25 }; this.domElement = document.createElement("canvas"); this.domElement.width = props && props.width || 640; this.domElement.height = props && props.height || 480; this.context = this.domElement.getContext("2d"); this.clear(); if(props && props.fn) this.draw(props.fn); return this; } clear() { var from_x = 20, last_x = this.domElement.width - 8; var from_y = 8, last_y = this.domElement.height - 24; var width = last_x - from_x; var height = last_y - from_y; var size_x = this.grid.max_x - this.grid.min_x; var size_y = this.grid.max_y - this.grid.min_y; var left, right, top, bottom; var i, x, y; this.context.fillStyle = "white"; this.context.fillRect(0, 0, this.domElement.width, this.domElement.height); this.context.strokeStyle = "black"; this.context.fillStyle = "black"; this.context.textAlign = "right"; this.context.beginPath(); if(this.grid.min_x * this.grid.max_x >= 0 && this.grid.min_y * this.grid.max_y >= 0) { this.context.rect(from_x, from_y, width, height); left = from_x + 2; right = last_x - 2; top = from_y + 2; bottom = last_y - 2; } else { left = from_x - width / size_x * this.grid.min_x; right = left; top = last_y + height / size_y * this.grid.min_y; bottom = top; this.context.moveTo(left, from_y); this.context.lineTo(left, last_y); this.context.moveTo(from_x, top); this.context.lineTo(last_x, top); } for(i = this.grid.min_x; i <= this.grid.max_x; i += this.grid.step_x) { x = from_x + (i - this.grid.min_x) / size_x * width; this.context.moveTo(x, top - 2); this.context.lineTo(x, top + 2); this.context.moveTo(x, bottom - 2); this.context.lineTo(x, bottom + 2); this.context.fillText(String(i), x + 4, bottom + 14); } for(i = this.grid.min_y; i <= this.grid.max_y; i += this.grid.step_y) { y = from_y + (i - this.grid.min_y) / size_y * height; this.context.moveTo(left - 2, y); this.context.lineTo(left + 2, y); this.context.moveTo(right - 2, y); this.context.lineTo(right + 2, y); this.context.fillText(String((this.grid.max_y - i + this.grid.min_y)), left - 4, y + 8); } this.context.stroke(); this.context.fillText("X", right, bottom); this.context.textAlign = "left"; this.context.fillText("Y", left, top + 12); return this; } draw(functions) { var from_x = 20, last_x = this.domElement.width - 8; var from_y = 8, last_y = this.domElement.height - 24; var width = last_x - from_x; var height = last_y - from_y; var size_x = this.grid.max_x - this.grid.min_x; var size_y = this.grid.max_y - this.grid.min_y; for(var grafic of functions) { var min_x = Math.max(this.grid.min_x, grafic.x1 || 0); var max_x = Math.min(this.grid.max_x, grafic.x2 || 0); var min_y = Math.max(this.grid.min_y, grafic.y1 || 0); var max_y = Math.min(this.grid.max_y, grafic.y2 || 0); var fn = grafic.fn; var left = from_x - this.grid.min_x / size_x * width + width / size_x * min_x; var right = last_x - this.grid.max_x / size_x * width + width / size_x * max_x; var top = last_y + this.grid.min_y / size_y * height + height / size_y * min_y; var bottom = last_y + this.grid.min_y / size_y * height + height / size_y * max_y; var maxi, exprs; this.context.textAlign = "right"; if(fn) { exprs = fn.replace(/\*\*2/g, "\u00B2").replace(/\*\*3/g, "\u00B3").replace(/\*/g, ""); fn = fn.replace(/(cos|sin|tan|exp)/g, "Math.$1"); if(isFinite(grafic.x1) && isFinite(grafic.x2)) { this.context.beginPath(); this.context.strokeStyle = grafic.color || "black"; maxi = this.grid.min_y; for(var x0 = left; x0 < right; ++ x0) { var x = (x0 - from_x) / width * size_x + this.grid.min_x, y = 0; try { y = eval(fn); y = y / size_y * height; maxi = Math.max(maxi, y); } catch(err) { } this.context.lineTo(x0, bottom - y); } this.context.stroke(); this.context.beginPath(); this.context.moveTo(x0, from_y); this.context.lineTo(x0, last_y); this.context.setLineDash([1, 2]); this.context.strokeStyle = "black"; this.context.stroke(); this.context.setLineDash([]); this.context.fillText(exprs, left + (right - left) / 2, bottom - maxi / 2); } else if(isFinite(grafic.y1) && isFinite(grafic.y2)) { this.context.beginPath(); this.context.strokeStyle = grafic.color || "black"; maxi = this.grid.min_x; for(var y0 = top; y0 < bottom; ++ y0) { var x = 0, y = (bottom - y0 - from_y) / height * size_y + this.grid.min_y; try { x = eval(fn); x = x / size_x * width; maxi = Math.max(maxi, x); } catch(err) { } this.context.lineTo(left - x, last_y - y0 - (this.grid.min_y) / size_y * height); } this.context.stroke(); this.context.beginPath(); this.context.moveTo(from_x, last_y - y0 - (this.grid.min_y) / size_y * height); this.context.lineTo(last_x, last_y - y0 - (this.grid.min_y) / size_y * height); this.context.setLineDash([1, 2]); this.context.strokeStyle = "black"; this.context.stroke(); this.context.setLineDash([]); this.context.fillText(exprs, left + maxi / 2, top + (bottom - top) / 2); } } } } } function Draw_Fn() { document.body.appendChild( new Functions({ min_x: 0, max_x: 40, min_y: -8, max_y: 8, step_x: 1, step_y: 20, width: 600, height: 200, fn: [ { x1:0, x2:6, color: "red", fn: "x**2" } ] }).domElement ); } //линия 1 ctx.beginPath(); ctx.moveTo(200, 0); ctx.lineTo(300, 1000); ctx.stroke(); ctx.closePath(); </script> <style> canvas { display: block; } body { background-color: silver; } </style> </head> <body onload='Draw_Fn()'> </body> |
Цитата:
У меня в двух браузерах (Chrome и Firefox ESR) отрабатывается нормально. Цитата:
Очень буду рад помощи в этой бесконечной и бессмыленной битве с кросс-браузерностью.:thanks: Цитата:
Класс просто не расчитывался для внешего вмешательства. Цитата:
Цитата:
|
Часовой пояс GMT +3, время: 20:48. |