Я создаю веб-сайт, на котором могу вводить данные о полях для гольфа, а затем анализировать их. Я использую экспресс в своем бэкэнде для маршрутизации на мои страницы ejs. Я также использую базу данных MySQL для хранения данных. При создании диаграмм я использовал файлchart.js из w3schools, что позволило мне создать скрипт внутри html-кода для вставки кода javascript. Но потом понял, что мне придется создать соединение с базой данных в файле ejs (что кажется неэффективным и небезопасным (создание нескольких подключений к БД)). Затем я потратил много времени, создавая функции внутри моего js-файла с базой данных и экспресс-соединения, где я выполняю все остальные запросы. Я закончил просто попыткой сохранить сценарий с веб-сайта в файле ejs, а затем попытаться передать данные из моего файла js в этот файл ejs для отображения. Именно по этой причине я прошу о помощи. Я не могу понять, как передать этот список данных из моего js-файла в мой ejs-файл для использования в скрипте? Пока думаю об этом. Должен быть более эффективный способ сделать это?
EJS-файл, в котором я пытаюсь отобразить график:
<body>
<div class = "container">
<div class = "chart">
<canvas id = "myChart" style = "width:100%;max-width:700px"></canvas>
</div>
</div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const scatterGraphData = JSON.parse(document.getElementById('myChart').dataset.scatterData);
new Chart("myChart", {
type: "scatter",
data: {
datasets: [{
pointRadius: 4,
pointBackgroundColor: "rgb(0,0,255)",
data: scatterGraphData
}]
},
options: {
legend: { display: false },
scales: {
xAxes: [{ ticks: { min: 40, max: 160 } }],
yAxes: [{ ticks: { min: 6, max: 16 } }],
}
}
});
});
</script>
</body>
Функция, которая вычисляет данные:
async function getChartData() {
const now = new Date();
const formattedDate = now.toISOString().split('T')[0];
connection.query("SELECT * FROM sample WHERE Date = ?", [formattedDate], (error, results) => {
if (error) {
console.info("Database Error inside getChartData");
return;
}
if (results.length === 0) {
// No data found today
console.info("Entered in the no data found");
// random test data to see if graph even works
const defaultData = [
{ x: 50, y: 7 },
{ x: 60, y: 8 },
{ x: 70, y: 8 },
{ x: 80, y: 9 },
{ x: 90, y: 9 },
{ x: 100, y: 9 },
{ x: 110, y: 10 },
{ x: 120, y: 11 },
{ x: 130, y: 14 },
{ x: 140, y: 14 },
{ x: 150, y: 15 }
];
return defaultData;
}
// real Data exists to map
let AveragesList = [];
let counter = 0;
const sampleHoles = [2, 12, 16];
for (const holeid of sampleHoles) {
const holeRecord = connection.query("SELECT * FROM holes WHERE Id = ?", [results[0][holeid]]);
const upSlopeData = connection.query("SELECT * FROM upslopespeed WHERE UpSlopeID = ?", [holeRecord[0].UpSlopeSpeedID]);
const downSlopeData = connection.query("SELECT * FROM downslopespeed WHERE DownSlopeID = ?", [holeRecord[0].DownSlopeSpeedID]);
const backLeftSpeed = (upSlopeData[0].BackLeft * 2) / (upSlopeData[0].BackLeft + downSlopeData[0].BackLeft);
const backCentreSpeed = (upSlopeData[0].BackCentre * 2) / (upSlopeData[0].BackCentre + downSlopeData[0].BackCentre);
const backRightSpeed = (upSlopeData[0].BackRight * 2) / (upSlopeData[0].BackRight + downSlopeData[0].BackRight);
const AverageSpeed = (backLeftSpeed + backCentreSpeed + backRightSpeed) / 3;
AveragesList[counter] = AverageSpeed;
counter++;
}
const xyValues = [
{x:2, y:AveragesList[0]},
{x:12, y:AveragesList[1]},
{x:16, y:AveragesList[2]}
];
return xyValues;
});
}
Это функция, которая вызывается при загрузке страницы:
function DashboardDetermine(req, res) {
if (req.session.user.isAdmin === 1) {
// ADMIN
// get all employees to list on admin dashboard
connection.query("SELECT * FROM user WHERE admin = 0", async (error, results) => {
if (error) {
console.error('Error executing query:', error);
req.flash('error_msg', 'An error occurred while loading users.');
res.redirect('/dashboard');
return;
}
const scatterGraphData = await JSON.stringify(getChartData());
console.info(scatterGraphData);
// Pass the results to the template
res.render('dashboardAdmin', { user: results, scatterGraphData });
});
} else {
// EMPLOYEE
res.render("dashboard");
}
}
В пустой день функция getChartData() должна просто возвращать фиксированные данные, которые я взял с веб-сайта w3schools в своем примере, просто чтобы устранить источники ошибок. Кажется, данные получаются из вызова getChartData(), но файл JSON из console.info возвращает {}. Из-за этого диаграмма не отображается.
Вот почему мне интересно, переместить ли сценарий точечного графика в этот JS-файл, чтобы функции могли вводить туда данные?
Надеюсь, это не сбивает с толку, большое спасибо за любую помощь!
🤔 А знаете ли вы, что...
JavaScript поддерживает работу с графикой и аудио, что позволяет создавать мультимедийные веб-приложения.
Несколько наблюдений, комментариев, а также рабочий код, основанный на прилагаемом вашем коде.
а. Второй аргумент res.render по сути является объектом. После этого он будет доступен в шаблоне как сам объект. Пожалуйста, посмотрите в приведенном ниже коде, как он был передан как объект, точнее, в данном случае как объект массива объектов.
res.render('index', { graphdata });
б. Продолжая вышеизложенное, нет никаких требований о том, что он должен быть в формате JSON. Форматирование же полностью зависит от контекста, в котором оно будет использоваться в шаблоне. Также обратите внимание, что функция конструктора диаграммы напрямую принимает объект javascript, но обратите внимание, что он должен быть в формате JSON. Это вы можете проверить и подтвердить, назначив массив объектов непосредственно его свойству data.datasets.data.
в. Однако в приведенном ниже коде используется формат JSON. Это стало техническим требованием. Объект, переданный в шаблон, будет доступен как сам объект, который уже упоминался в пункте a, однако доступ к нему в JavaScript в теге «script» потребует немного больше работы. Следующее утверждение выполняет эту работу. В данном конкретном случае он сначала отформатировал JSON и, таким образом, стал доступен в контексте сценариев JavaScript, а затем вернул формат JSON путем анализа. Благодаря этим шагам он стал объектом того же типа, который был передан с сервера. Это один из технических способов сделать объект, передаваемый с сервера, доступным и в контексте сценария. Также обратите внимание на дефис в теге ejs «<%-», он также необходим для получения неэкранированных значений.
const graphdata = JSON.parse('<%- (JSON.stringify(graphdata)) %>');
Рабочий код:
сервер.js
const express = require('express');
const app = express();
app.use(express.static('./'));
app.engine('ejs', require('ejs').__express);
app.set('views', './');
app.set('view engine', 'ejs');
const graphdata = [
{ x: 50, y: 7 },
{ x: 60, y: 8 },
{ x: 70, y: 8 },
{ x: 80, y: 9 },
{ x: 90, y: 9 },
{ x: 100, y: 9 },
{ x: 110, y: 10 },
{ x: 120, y: 11 },
{ x: 130, y: 14 },
{ x: 140, y: 14 },
{ x: 150, y: 15 },
];
console.info(graphdata);
app.get('/', (req, res) => {
res.render('index', { graphdata });
});
app.listen(3000, () => console.info('L@3000'));
index.ejs
<!DOCTYPE html>
<html>
<head>
Chart.js sample - Scatter chart
</head>
<body>
<div class = "container">
<div class = "chart">
<canvas id = "myChart" style = "width: 100%; max-width: 700px"></canvas>
</div>
</div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const graphdata = JSON.parse('<%- (JSON.stringify(graphdata)) %>');
new Chart('myChart', {
type: 'scatter',
data: {
datasets: [
{
pointRadius: 4,
pointBackgroundColor: 'rgb(0,0,255)',
data: graphdata,
},
],
},
options: {
legend: { display: false },
scales: {
xAxes: [{ ticks: { min: 40, max: 160 } }],
yAxes: [{ ticks: { min: 6, max: 16 } }],
},
},
});
});
</script>
</body>
</html>
Выход:
Цитаты:
Доступ к переданной переменной EJS в файле Javascript
Обновление: 11 июля 24 г.