24.08.2022, 22:36
|
Аспирант
|
|
Регистрация: 21.08.2022
Сообщений: 57
|
|
Alikberov,
Графики, получились красивые, особенно, с осями координат. Спасибо за ответ. Однако, графики не имеют своих интервалов существования на оси Х, потому что они существуют на всей числовой оси Х и сходятся в одной точке (0, 0)
|
|
24.08.2022, 22:54
|
Аспирант
|
|
Регистрация: 21.08.2022
Сообщений: 57
|
|
Alikberov, Только, что опробовал Ваш код, и оказалось, что Вы построили все возможные варианты построения графиков. Поэтому, очень прошу извинить меня за мою невнимательность и ещё раз большое спасибо. Ваш код не просто правильный, но совершенно полноценный.
|
|
24.08.2022, 23:03
|
Аспирант
|
|
Регистрация: 21.08.2022
Сообщений: 57
|
|
Alikberov,
Было бы здорово, если бы Вы, общий код разделили на три кода: Соответственно, для одного графика, для графиков на разных интервалах, и графиков проходящих через (0,0). Сам, я боюсь чт что-нибудь не так сделаю или допушу досадную ошибку. Заранее благодарен.
|
|
25.08.2022, 01:39
|
|
Кандидат Javascript-наук
|
|
Регистрация: 16.08.2018
Сообщений: 109
|
|
Увы! Код написан довольно быстро и местами небрежно. Имеет ряд недоработок: - Отсутствует сетка, хотя параметр (строка 12) для указания размера ячеек имеется
- Отсутствует клиппинг рабочей области и график может выйти за её пределы
- Строка математического выражения к графику выводится чуть ли ни хаотически: Нужно добавить параметр для ручного позиционирования текста
- Стиль текста никак не настраивается
- Нужно добавить опцию подавления пунктирного разделителя
- Самое неприятное: Построение графиков по оси Y (строки 127-134) имеет много грубых досадных ошибок (привет двойкам по математике) и я не успел отладить (методом проб и ошибок) эту часть кода
Цитата:
|
Было бы здорово, если бы Вы, общий код разделили на три кода
|
А там специально я код вызова функции разделил на три части (строки 152-170, 172-200 и 202-230), чтобы можно было скопировать и изменять по своему усмотрению.
Вот только комментарии не успел раскидать, из-за чего код слишком мутно выглядит.
Вот фрагмент с пояснениями.
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, 25.08.2022 в 02:14.
|
|
25.08.2022, 11:33
|
Аспирант
|
|
Регистрация: 21.08.2022
Сообщений: 57
|
|
Alikberov,
Уважаемый Alikberov, так как, я не такой опытный, как Вы, мне так и не удалось Ваш код разделить на три кода ( три типа построения графиков)
Убрал строки 152-170 с целью убрать первый тип графиков и, как и ожидалось ничего не получилось (где то ошибка). Вернее, после этого пошли ошибки за ошибкой, которые надо было исправлять. Убедительно прошу разделить общий файл на три по типам построения графиков. Если, есть возможность дайте хоть, какие нибудь главные комментарии.
|
|
25.08.2022, 18:14
|
Аспирант
|
|
Регистрация: 21.08.2022
Сообщений: 57
|
|
Alikberov, Извините, опять поторопился со своим последним сообщением. Мне удалось Ваш код разделить на три кода ( три типа построения графиков). Правда, потратил на это несколько часов.
|
|
26.08.2022, 04:29
|
|
Кандидат Javascript-наук
|
|
Регистрация: 16.08.2018
Сообщений: 109
|
|
Вот Вам Конструктор Графиков с "горячей отладкой".
(Можно изменять любые параметры как мышкой, так и JSON.)
Правда, там не всё работает так, как хотелось бы мне. Но это поправимо в дальнейшем.
P.S.: Класс переименовал, добавил сетку и легенду.
|
|
26.08.2022, 16:26
|
Профессор
|
|
Регистрация: 07.11.2013
Сообщений: 456
|
|
Alikberov,
График не реагирует на изменения шкалы, а должен по идее.
Могу подсказать, где подсмотреть можно на эту тему, если интересно.
Последний раз редактировалось Rise, 26.08.2022 в 16:34.
|
|
26.08.2022, 16:30
|
Аспирант
|
|
Регистрация: 21.08.2022
Сообщений: 57
|
|
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>
Последний раз редактировалось IZUM, 26.08.2022 в 16:34.
|
|
26.08.2022, 17:25
|
|
Кандидат Javascript-наук
|
|
Регистрация: 16.08.2018
Сообщений: 109
|
|
Сообщение от Rise
|
График не реагирует на изменения шкалы, а должен по идее.
|
Этo очень плохо!
У меня в двух браузерах (Chrome и Firefox ESR) отрабатывается нормально.
Сообщение от Rise
|
Могу подсказать, где подсмотреть можно на эту тему, если интересно.
|
Конечно!
Очень буду рад помощи в этой бесконечной и бессмыленной битве с кросс-браузерностью.
Сообщение от IZUM
|
Я взял за основу Ваш код для построения графиков, но не смог нарисовать обыкновенные геометрические фигуры ромба и окружности, которые привязаны к определенной координате (См.картинку).
|
И не мудрено, так как в основе этого класса ставилась задача простого вывода графика.
Класс просто не расчитывался для внешего вмешательства.
Сообщение от IZUM
|
Попробовал нарисовать обыкновенный отрезок, а он уехал, вобще, куда-то из области координат.
|
Чем подкидываете мне идею преобразования координат. Только это займёт время.
Сообщение от IZUM
|
Прошу, если возможно, упростить или сделать понятным высланный мной код HTML, который я выделил из общего Вашего кода. И, самое главное - нарисовать ромб и окружность, показанные на картинке. Их размеры должны быть сооизмеримы с координатными осями.
|
Я просто добавлю Вам метод для преобразования массива Ваших координат в координаты шкалы.
|
|
|
|