Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
7 / 7 / 0
Регистрация: 28.06.2019
Сообщений: 92

Перед выводом чисел на оси можно округлить их до разумного количества знаков

25.07.2025, 08:41. Показов 807. Ответов 10

Студворк — интернет-сервис помощи студентам
В JS численная нумерация меток на осях X и Y получается в виде чисел 5.99999999999999999999 вместо 6. И, так для всей числовой нумерации меток осей. Как с эти бороться ?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.07.2025, 08:41
Ответы с готовыми решениями:

Как округлить число до нужного количества знаков без добавления нулей?
Добрый день! Мне нужно округлять десятичные числа, в которых после запятой больше пяти знаков. ...

Как в JS округлить число до целого? -до 2-х знаков впосле точки?
Как в JS округлить число до целого? -до 2-х знаков впосле точки? Спасибо.

Как округлить число до 2-х знаков после запятой?
Всем привет! Поможите, люди добрые... Знаю что вопрос мой не нов, но мне от этого не легче... Я...

10
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3827 / 1664 / 429
Регистрация: 14.03.2022
Сообщений: 4,182
25.07.2025, 08:56
Лучший ответ Сообщение было отмечено Rommancen как решение

Решение

Цитата Сообщение от Rommancen Посмотреть сообщение
Как с эти бороться ?
Использовать округление до "определенной точности"... Например до сотых.

JavaScript
1
2
let v = 5.99999999999999999999
v = +v.toFixed(2) // => 6
0
1191 / 760 / 128
Регистрация: 10.03.2012
Сообщений: 4,893
25.07.2025, 10:57
JavaScript
1
2
let format = d3.format(".0f");
console.log(format(5.999999999999999)); // "6"
0
7 / 7 / 0
Регистрация: 28.06.2019
Сообщений: 92
25.07.2025, 13:56  [ТС]
Это понятно... но мне надо внести изменения в плоттере:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/**
 * Класс Plotter предназначен для рисования графиков на HTML5 Canvas.
 * Он предоставляет методы для отображения координатной сетки, осей, насечек и самих графиков.
 */
export class Plotter {
    /**
     * Конструктор класса Plotter.
     * Инициализирует параметры для масштабирования и отображения графика.
     * @param {CanvasRenderingContext2D} ctx - Контекст рисования canvas
     * @param {number} width - Ширина рабочей области в пикселях
     * @param {number} height - Высота рабочей области в пикселях
     * @param {number} x0 - X-координата начала системы координат (в пикселях)
     * @param {number} y0 - Y-координата начала системы координат (в пикселях)
     * @param {number} xMin - Минимальное значение по оси X (в единицах данных)
     * @param {number} xMax - Максимальное значение по оси X (в единицах данных)
     * @param {number} yMin - Минимальное значение по оси Y (в единицах данных)
     * @param {number} yMax - Максимальное значение по оси Y (в единицах данных)
     */
    constructor(ctx, width, height, x0, y0, xMin, xMax, yMin, yMax) {
        // Сохраняем контекст canvas для рисования
        this.ctx = ctx;
        
        // Сохраняем координаты начала системы координат (в пикселях)
        this.x0 = x0;
        this.y0 = y0;
        
        // Вычисляем масштабные коэффициенты для преобразования данных в пиксели
        // xScale - количество единиц данных на один пиксель по оси X
        this.xScale = (xMax - xMin) / width;
        // yScale - количество единиц данных на один пиксель по оси Y
        this.yScale = (yMax - yMin) / height;
        
        // Преобразуем границы области в пиксельные координаты относительно начала системы координат
        this.xMin = xMin / this.xScale;
        this.xMax = xMax / this.xScale;
        this.yMin = yMin / this.yScale;
        this.yMax = yMax / this.yScale;
    }
 
    /**
     * Рисует координатную сетку.
     * @param {number} xCell - Ширина клетки сетки по оси X (в единицах данных)
     * @param {number} yCell - Высота клетки сетки по оси Y (в единицах данных)
     * @param {string} color - Цвет линий сетки (по умолчанию "lightgray")
     */
    drawGrid(xCell, yCell, color = "lightgray") {
        // Сохраняем текущее состояние контекста (стили, трансформации)
        this.ctx.save();
        
        // Переносим начало координат в указанную точку (x0, y0)
        this.ctx.translate(this.x0, this.y0);
        
        // Инвертируем ось Y, чтобы направление вверх было положительным
        this.ctx.scale(1, -1);
        
        // Устанавливаем стили для линий сетки
        this.ctx.lineWidth = 1;
        this.ctx.strokeStyle = color;
        
        // Начинаем новый путь
        this.ctx.beginPath();
        
        // Преобразуем размеры клеток из единиц данных в пиксели
        xCell /= this.xScale;
        yCell /= this.yScale;
        
        // Рисуем вертикальные линии сетки
        let x = this.xMin; // Начинаем от левой границы
        do {
            // Перемещаем перо в начало линии (нижняя точка)
            this.ctx.moveTo(x, this.yMin);
            // Рисуем линию до верхней точки
            this.ctx.lineTo(x, this.yMax);
            // Переходим к следующей вертикальной линии
            x += xCell;
        } while (x <= this.xMax); // Продолжаем пока не достигнем правой границы
        
        // Рисуем горизонтальные линии сетки
        let y = this.yMin; // Начинаем от нижней границы
        do {
            // Перемещаем перо в начало линии (левая точка)
            this.ctx.moveTo(this.xMin, y);
            // Рисуем линию до правой точки
            this.ctx.lineTo(this.xMax, y);
            // Переходим к следующей горизонтальной линии
            y += yCell;
        } while (y <= this.yMax); // Продолжаем пока не достигнем верхней границы
        
        // Отрисовываем все линии
        this.ctx.stroke();
        
        // Восстанавливаем сохраненное состояние контекста
        this.ctx.restore();
    }
 
    /**
     * Рисует координатные оси с метками.
     * @param {string} xLabel - Метка для оси X (по умолчанию "x")
     * @param {string} yLabel - Метка для оси Y (по умолчанию "y")
     * @param {string} color - Цвет осей и меток (по умолчанию "black")
     * @param {string} font - Шрифт для меток (по умолчанию "12px Arial")
     */
    drawAxes(xLabel = "x", yLabel = "y", color = "black", font = "12px Roboto") {
        // Сохраняем текущее состояние контекста
        this.ctx.save();
        
        // Переносим и инвертируем систему координат как в drawGrid
        this.ctx.translate(this.x0, this.y0);
        this.ctx.scale(1, -1);
        
        // Устанавливаем стили для осей
        this.ctx.lineWidth = 0.5;
        this.ctx.strokeStyle = color;
        
        // Начинаем новый путь для осей
        this.ctx.beginPath();
        
        // Рисуем ось X (горизонтальная линия)
        this.ctx.moveTo(this.xMin, 0); // Начинаем от левой границы
        this.ctx.lineTo(this.xMax, 0); // До правой границы
        
        // Рисуем ось Y (вертикальная линия)
        this.ctx.moveTo(0, this.yMin); // Начинаем от нижней границы
        this.ctx.lineTo(0, this.yMax); // До верхней границы
        
        // Отрисовываем оси
        this.ctx.stroke();
        
        // Инвертируем только ось Y обратно для правильного отображения текста
        this.ctx.scale(1, -1);
        
        // Устанавливаем стили для текста меток
        this.ctx.fillStyle = color;
        this.ctx.font = font;
        this.ctx.textAlign = "center"; // Выравнивание по центру
        this.ctx.textBaseline = "middle"; // Базовая линия по середине
        
        // Рисуем метку оси X справа от оси
        this.ctx.fillText(xLabel, this.xMax + 10, -10);
        
        // Рисуем метку оси Y сверху от оси
        this.ctx.fillText(yLabel, 0, -this.yMax - 10);
        
        // Восстанавливаем состояние контекста
        this.ctx.restore();
    }
 
    /**
     * Рисует насечки (тики) на осях координат.
     * @param {number} xCell - Расстояние между насечками по оси X (в единицах данных)
     * @param {number} yCell - Расстояние между насечками по оси Y (в единицах данных)
     * @param {string} color - Цвет насечек (по умолчанию "black")
     */
    drawTicks(xCell, yCell, color = "black") {
        // Сохраняем состояние контекста
        this.ctx.save();
        
        // Переносим и инвертируем систему координат
        this.ctx.translate(this.x0, this.y0);
        this.ctx.scale(1, -1);
        
        // Устанавливаем стили для насечек
        this.ctx.lineWidth = 1;
        this.ctx.strokeStyle = color;
        
        // Начинаем новый путь
        this.ctx.beginPath();
        
        // Преобразуем расстояния между насечками в пиксели
        xCell /= this.xScale;
        yCell /= this.yScale;
        
        // Рисуем вертикальные насечки (для оси X)
        let x = this.xMin; // Начинаем от левой границы
        do {
            // Рисуем короткую горизонтальную линию (длиной 8 пикселей)
            this.ctx.moveTo(x, -4); // Начало линии
            this.ctx.lineTo(x, 4);  // Конец линии
            x += xCell; // Переходим к следующей насечке
        } while (x <= this.xMax); // Продолжаем до правой границы
        
        // Рисуем горизонтальные насечки (для оси Y)
        let y = this.yMin; // Начинаем от нижней границы
        do {
            // Рисуем короткую вертикальную линию (длиной 8 пикселей)
            this.ctx.moveTo(-4, y); // Начало линии
            this.ctx.lineTo(4, y);  // Конец линии
            y += yCell; // Переходим к следующей насечке
        } while (y <= this.yMax); // Продолжаем до верхней границы
        
        // Отрисовываем все насечки
        this.ctx.stroke();
        
        // Восстанавливаем состояние контекста
        this.ctx.restore();
    }
 
    /**
     * Рисует числовые подписи (единицы измерения) на осях.
     * @param {number} xCell - Расстояние между подписями по оси X (в единицах данных)
     * @param {number} yCell - Расстояние между подписями по оси Y (в единицах данных)
     * @param {string} color - Цвет текста (по умолчанию "black")
     * @param {string} font - Шрифт текста (по умолчанию "10px Arial")
     */
    drawUnits(xCell, yCell, color = "black", font = "10px Roboto") {
        // Сохраняем состояние контекста
        this.ctx.save();
        
        // Переносим начало координат, но не инвертируем ось Y (текст должен быть читаемым)
        this.ctx.translate(this.x0, this.y0);
        
        // Устанавливаем стили для текста
        this.ctx.fillStyle = color;
        this.ctx.font = font;
        
        // Преобразуем расстояния между подписями в пиксели
        xCell /= this.xScale;
        yCell /= this.yScale;
        
        // Устанавливаем выравнивание текста (влево и вверх от точки)
        this.ctx.textAlign = "left";
        this.ctx.textBaseline = "top";
        
        // Рисуем подписи для оси X
        let x = this.xMin; // Начинаем от левой границы
        do {
            // Вычисляем значение в единицах данных и отображаем его
            // Подпись размещается немного выше оси X (y=4) и справа от тика (x+4)
            this.ctx.fillText(x * this.xScale, x + 4, 4);
            x += xCell; // Переходим к следующей подписи
        } while (x <= this.xMax); // Продолжаем до правой границы
        
        // Рисуем подписи для оси Y
        let y = this.yMin; // Начинаем от нижней границы
        do {
            // Вычисляем значение в единицах данных и отображаем его
            // Подпись размещается немного правее оси Y (x=4) и выше тика (-y+4)
            this.ctx.fillText(y * this.yScale, 4, -y + 4);
            y += yCell; // Переходим к следующей подписи
        } while (y <= this.yMax); // Продолжаем до верхней границы
        
        // Восстанавливаем состояние контекста
        this.ctx.restore();
    }
 
    /**
     * Рисует график по массивам координат.
     * @param {number[]} xArray - Массив X-координат точек (в единицах данных)
     * @param {number[]} yArray - Массив Y-координат точек (в единицах данных)
     * @param {string} color - Цвет графика (по умолчанию "blue")
     * @param {boolean} dots - Флаг отображения точек (по умолчанию false)
     * @param {boolean} line - Флаг отображения линии (по умолчанию true)
     */
    drawGraph(xArray, yArray, color = "blue", dots = false, line = true) {
        // Сохраняем состояние контекста
        this.ctx.save();
        
        // Переносим и инвертируем систему координат
        this.ctx.translate(this.x0, this.y0);
        this.ctx.scale(1, -1);
        
        // Устанавливаем стили для графика
        this.ctx.lineWidth = 1;
        this.ctx.strokeStyle = color;
        
        // Начинаем новый путь
        this.ctx.beginPath();
        
        // Константа для рисования полного круга (2π радиан)
        let angle2PI = 2 * Math.PI;
        
        // Проходим по всем точкам графика
        for (let i = 0; i < xArray.length; i++) {
            // Преобразуем координаты из единиц данных в пиксели
            let x = xArray[i] / this.xScale;
            let y = yArray[i] / this.yScale;
            
            if (line) {
                // Если это не первая точка и нужно рисовать линию, рисуем линию к текущей точке
                if (i != 0) {
                    this.ctx.lineTo(x, y);
                } else {
                    // Для первой точки просто перемещаем перо
                    this.ctx.moveTo(x, y);
                }
            }
            
            if (dots) {
                // Если нужно рисовать точки, рисуем маленький круг в текущей точке
                this.ctx.arc(x, y, 1, 0, angle2PI);
                // Возвращаем перо в центр точки после рисования круга
                this.ctx.moveTo(x, y);
            }
        }
        
        // Отрисовываем график
        this.ctx.stroke();
        
        // Восстанавливаем состояние контекста
        this.ctx.restore();
    }
 
    /**
     * Рисует пунктирную линию между двумя точками.
     * @param {number} x1 - X-координата начальной точки (в единицах данных)
     * @param {number} y1 - Y-координата начальной точки (в единицах данных)
     * @param {number} x2 - X-координата конечной точки (в единицах данных)
     * @param {number} y2 - Y-координата конечной точки (в единицах данных)
     * @param {string} color - Цвет линии (по умолчанию "red")
     * @param {number[]} pattern - Шаблон пунктира (по умолчанию [5, 3] - 5px черта, 3px пропуск)
     */
    drawDashedLine(x1, y1, x2, y2, color = "red", pattern = [5, 3]) {
        // Сохраняем состояние контекста
        this.ctx.save();
        
        // Переносим и инвертируем систему координат
        this.ctx.translate(this.x0, this.y0);
        this.ctx.scale(1, -1);
        
        // Устанавливаем стили для пунктирной линии
        this.ctx.strokeStyle = color;
        this.ctx.lineWidth = 1;
        this.ctx.setLineDash(pattern); // Устанавливаем шаблон пунктира
        
        // Начинаем новый путь
        this.ctx.beginPath();
        
        // Преобразуем координаты в пиксели и рисуем линию
        this.ctx.moveTo(x1 / this.xScale, y1 / this.yScale);
        this.ctx.lineTo(x2 / this.xScale, y2 / this.yScale);
        
        // Отрисовываем пунктирную линию
        this.ctx.stroke();
        
        // Восстанавливаем состояние контекста (сбрасываем пунктир)
        this.ctx.restore();
    }
}
Добавлено через 52 минуты
Вот посмотрите, как получается по оси X. Также, и по оси Y
0
7 / 7 / 0
Регистрация: 28.06.2019
Сообщений: 92
25.07.2025, 13:58  [ТС]
Посмотрите, пожалуйста
Миниатюры
Перед выводом чисел на оси можно округлить их до разумного количества знаков  
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3827 / 1664 / 429
Регистрация: 14.03.2022
Сообщений: 4,182
25.07.2025, 14:14
Если я правильно понял...
Цитата Сообщение от Rommancen Посмотреть сообщение
JavaScript
1
this.ctx.fillText(x * this.xScale, x + 4, 4);
Цитата Сообщение от Rommancen Посмотреть сообщение
JavaScript
1
this.ctx.fillText(y * this.yScale, 4, -y + 4);
Вот тут и округляй.
1
100 / 96 / 17
Регистрация: 05.08.2021
Сообщений: 474
25.07.2025, 14:54
В этом не JS виноват... Это процессор компьютера так считает, а не JS. Что-то в этом случае там завязано у него на представлении десятичных чисел в двоичном виде
0
7 / 7 / 0
Регистрация: 28.06.2019
Сообщений: 92
25.07.2025, 14:54  [ТС]
спасибо. Помогите, кто-нибудь найти эту строку в высланном мной коде, что бы не ошибиться. И, самое главное - помогите там сделать правильную запись в строке кода.
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3827 / 1664 / 429
Регистрация: 14.03.2022
Сообщений: 4,182
25.07.2025, 15:05
Rommancen, т.е. ты в программировании совсем не смыслишь?

Предполагаемые строки я тебе уже показал выше...
Если просто нужны целые числа - можно заменить на

JavaScript
1
this.ctx.fillText((x * this.xScale).toFixed(0), x + 4, 4);
и

JavaScript
1
this.ctx.fillText((y * this.yScale).toFixed(0), 4, -y + 4);
соответственно.
1
7 / 7 / 0
Регистрация: 28.06.2019
Сообщений: 92
25.07.2025, 15:23  [ТС]
Вот написал this.ctx.fillText(Number(x * this.xScale).toFixed(0), x + 4, 4); и всё получилось
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3827 / 1664 / 429
Регистрация: 14.03.2022
Сообщений: 4,182
25.07.2025, 16:24
Rommancen, зачем использовал Number?
Результатом умножения и так будет число.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.07.2025, 16:24
Помогаю со студенческими работами здесь

Округлить дробную часть в меньшую сторону до указанного к-во знаков
Делаю это примерно таким образом, но окутывают сомнению по поводу правильности, может есть какая-то...

Разумно заменить innerHTML, чтобы работало во всех браузерах
уважаемые, как разумно заменить innerHTML, специально чтобы работало во всех броузерах, нужно чтобы...

Разумно ли писать на js большие проекты
Здравствуйте. Рассмотрим простую задачу - на странице боксера нужно изменить его вес без...

Округлить число до нужного количества символов
Неужели придётся писать подобную функцию, кто знает, подскажите!

Как округлить число до целого при выводе на сайт?
Помогите разобраться, пожалуйста. На странице...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru